aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/dependency.c
diff options
context:
space:
mode:
authorRoger Sayle <roger@eyesopen.com>2006-03-25 01:28:11 +0000
committerRoger Sayle <sayle@gcc.gnu.org>2006-03-25 01:28:11 +0000
commit31708dc6447f26d71c005f440c83de0a0bc590ef (patch)
tree8535c89df5c94aed2fd99466c926796da843b79c /gcc/fortran/dependency.c
parent9e51ddaa6e4902e734b803b9ede861eb499b3bd0 (diff)
downloadgcc-31708dc6447f26d71c005f440c83de0a0bc590ef.zip
gcc-31708dc6447f26d71c005f440c83de0a0bc590ef.tar.gz
gcc-31708dc6447f26d71c005f440c83de0a0bc590ef.tar.bz2
gfortran.h (gfc_symbol): Add a new "forall_index" bit field.
* 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
Diffstat (limited to 'gcc/fortran/dependency.c')
-rw-r--r--gcc/fortran/dependency.c96
1 files changed, 94 insertions, 2 deletions
diff --git a/gcc/fortran/dependency.c b/gcc/fortran/dependency.c
index 03cabf0..2c52882 100644
--- a/gcc/fortran/dependency.c
+++ b/gcc/fortran/dependency.c
@@ -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;
}