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
This commit is contained in:
Roger Sayle 2006-03-25 01:28:11 +00:00 committed by Roger Sayle
parent 9e51ddaa6e
commit 31708dc644
6 changed files with 127 additions and 2 deletions

View 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

View 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;
}

View 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 */

View 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;

View 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.

View File

@ -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" } }