gfortran.h (gfc_symbol): Add a new "forall_index" bit field.
authorRoger Sayle <roger@eyesopen.com>
Sat, 25 Mar 2006 01:28:11 +0000 (01:28 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Sat, 25 Mar 2006 01:28:11 +0000 (01:28 +0000)
* gfortran.h (gfc_symbol): Add a new "forall_index" bit field.
* match.c (match_forall_iterator): Set forall_index field on
the iteration variable's symbol.
* dependency.c (contains_forall_index_p): New function to
traverse a gfc_expr to check whether it contains a variable
with forall_index set in it's symbol.
(gfc_check_element_vs_element): Return GFC_DEP_EQUAL for scalar
constant expressions that don't variables used as FORALL indices.

* gfortran.dg/dependency_9.f90: New (resurected) test case.

From-SVN: r112373

gcc/fortran/ChangeLog
gcc/fortran/dependency.c
gcc/fortran/gfortran.h
gcc/fortran/match.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/dependency_9.f90 [new file with mode: 0644]

index e6ce54a3f42678e70665bf2c319dbb25aee519cf..9bb4edccf5487566be6848fabf6ae78e89c25449 100644 (file)
@@ -1,3 +1,14 @@
+2006-03-24  Roger Sayle  <roger@eyesopen.com>
+
+       * gfortran.h (gfc_symbol): Add a new "forall_index" bit field.
+       * match.c (match_forall_iterator): Set forall_index field on
+       the iteration variable's symbol.
+       * dependency.c (contains_forall_index_p): New function to
+       traverse a gfc_expr to check whether it contains a variable
+       with forall_index set in it's symbol.
+       (gfc_check_element_vs_element): Return GFC_DEP_EQUAL for scalar
+       constant expressions that don't variables used as FORALL indices.
+
 2006-03-22  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
 
        PR driver/22600
index 03cabf05be925c8e530f7c94f16a64f9768589ca..2c52882405561f969ee3292c53829ad18cb7384b 100644 (file)
@@ -794,6 +794,84 @@ gfc_check_element_vs_section( gfc_ref * lref, gfc_ref * rref, int n)
 }
 
 
+/* Traverse expr, checking all EXPR_VARIABLE symbols for their
+   forall_index attribute.  Return true if any variable may be
+   being used as a FORALL index.  Its safe to pessimistically
+   return true, and assume a dependency.  */
+
+static bool
+contains_forall_index_p (gfc_expr * expr)
+{
+  gfc_actual_arglist *arg;
+  gfc_constructor *c;
+  gfc_ref *ref;
+  int i;
+
+  if (!expr)
+    return false;
+
+  switch (expr->expr_type)
+    {
+    case EXPR_VARIABLE:
+      if (expr->symtree->n.sym->forall_index)
+       return true;
+      break;
+
+    case EXPR_OP:
+      if (contains_forall_index_p (expr->value.op.op1)
+         || contains_forall_index_p (expr->value.op.op2))
+       return true;
+      break;
+
+    case EXPR_FUNCTION:
+      for (arg = expr->value.function.actual; arg; arg = arg->next)
+       if (contains_forall_index_p (arg->expr))
+         return true;
+      break;
+
+    case EXPR_CONSTANT:
+    case EXPR_NULL:
+    case EXPR_SUBSTRING:
+      break;
+
+    case EXPR_STRUCTURE:
+    case EXPR_ARRAY:
+      for (c = expr->value.constructor; c; c = c->next)
+       if (contains_forall_index_p (c->expr))
+         return true;
+      break;
+
+    default:
+      gcc_unreachable ();
+    }
+
+  for (ref = expr->ref; ref; ref = ref->next)
+    switch (ref->type)
+      {
+      case REF_ARRAY:
+       for (i = 0; i < ref->u.ar.dimen; i++)
+         if (contains_forall_index_p (ref->u.ar.start[i])
+             || contains_forall_index_p (ref->u.ar.end[i])
+             || contains_forall_index_p (ref->u.ar.stride[i]))
+           return true;
+       break;
+
+      case REF_COMPONENT:
+       break;
+
+      case REF_SUBSTRING:
+       if (contains_forall_index_p (ref->u.ss.start)
+           || contains_forall_index_p (ref->u.ss.end))
+         return true;
+       break;
+
+      default:
+       gcc_unreachable ();
+      }
+
+  return false;
+}
+
 /* Determines overlapping for two single element array references.  */
 
 static gfc_dependency
@@ -812,9 +890,23 @@ gfc_check_element_vs_element (gfc_ref * lref, gfc_ref * rref, int n)
   i = gfc_dep_compare_expr (r_start, l_start);
   if (i == 0)
     return GFC_DEP_EQUAL;
-  if (i == -2)
+  if (i != -2)
+    return GFC_DEP_NODEP;
+
+  /* Treat two scalar variables as potentially equal.  This allows
+     us to prove that a(i,:) and a(j,:) have no dependency.  See
+     Gerald Roth, "Evaluation of Array Syntax Dependence Analysis",
+     Proceedings of the International Conference on Parallel and
+     Distributed Processing Techniques and Applications (PDPTA2001),
+     Las Vegas, Nevada, June 2001.  */
+  /* However, we need to be careful when either scalar expression
+     contains a FORALL index, as these can potentially change value
+     during the scalarization/traversal of this array reference.  */
+  if (contains_forall_index_p (r_start)
+      || contains_forall_index_p (l_start))
     return GFC_DEP_OVERLAP;
-  return GFC_DEP_NODEP;
+
+  return GFC_DEP_EQUAL;
 }
 
 
index 3e673a8ccf51651e93df5a254b07e00e30fc122a..a7b84b1a2e3827b4de5239a0c1d4647043462628 100644 (file)
@@ -852,6 +852,8 @@ typedef struct gfc_symbol
   /* Nonzero if all equivalences associated with this symbol have been
      processed.  */
   unsigned equiv_built:1;
+  /* Set if this variable is used as an index name in a FORALL.  */
+  unsigned forall_index:1;
   int refs;
   struct gfc_namespace *ns;    /* namespace containing this symbol */
 
index 4c2fe1b71ce430b7915ea956eeefdcf2ab6f6935..865781f9f865f5ad75dfb6ccdb3bf4462740a89e 100644 (file)
@@ -3370,6 +3370,9 @@ match_forall_iterator (gfc_forall_iterator ** result)
        goto cleanup;
     }
 
+  /* Mark the iteration variable's symbol as used as a FORALL index.  */
+  iter->var->symtree->n.sym->forall_index = true;
+
   *result = iter;
   return MATCH_YES;
 
index f85f232bf8ae6cfcb47de368151e0db66f293c0c..aa61c522aa4c4fd57ec6e11ee5f5a7eee6c358c7 100644 (file)
@@ -1,3 +1,7 @@
+2006-03-24  Roger Sayle  <roger@eyesopen.com>
+
+       * gfortran.dg/dependency_9.f90: New (resurected) test case.
+
 2006-03-24  Jeff Law  <law@redhat.com>
 
        * gcc.c-torture/pr26840.c: New test.
diff --git a/gcc/testsuite/gfortran.dg/dependency_9.f90 b/gcc/testsuite/gfortran.dg/dependency_9.f90
new file mode 100644 (file)
index 0000000..d1f6f5e
--- /dev/null
@@ -0,0 +1,13 @@
+! { dg-do compile }
+! { dg-options "-O2 -fdump-tree-original" }
+subroutine foo(a,i,j)
+  integer, dimension (4,4) :: a
+  integer :: i
+  integer :: j
+
+  where (a(i,:) .ne. 0)
+    a(j,:) = 1
+  endwhere
+end subroutine
+! { dg-final { scan-tree-dump-times "malloc" 0 "original" } }
+! { dg-final { cleanup-tree-dump "original" } }