diff mbox

[Fortran] CAF dep (1/3): PR62278 - improve dependency.c's gfc_check_dependency's check (missed-optimization)

Message ID 53FE46CB.6030505@net-b.de
State New
Headers show

Commit Message

Tobias Burnus Aug. 27, 2014, 8:59 p.m. UTC
The current gfc_check_dependency check always looked at the pointer 
attribute - and assumed the worst, if either the LHS or the RHS was true.

Thus, it claimed that "a" and "b" alias for the following definition:  
integer, pointer :: p;  integer :: a. However, as "a" has no target (or 
pointer) attribute, that's not possible. Additionally, "class(t) :: a" 
has internally the "pointer" attribute (but 
CLASS_DATA(sym)->attr.class_pointer == 0), however, in the Fortran 
sense, "a" is not a pointer and cannot alias.

I do not have a good example for the test case, except for a similar one 
as above using "a[i] = p" and looking at the dump; but that requires 
patch 3/3 of this series.

Build and regtested on x86-64-gnu-linux. (I do get a failure for 
gfortran.dg/graphite/pr42393.f90, but only with -O1 -fgraphite-identity 
and also without the patch.)

OK for the trunk?

Tobias

Comments

Tobias Burnus Aug. 27, 2014, 9:20 p.m. UTC | #1
Tobias Burnus wrote:
>   	{
> +	  symbol_attribute attr1, attr2;
>   	  gfc_typespec *ts1 = &expr1->symtree->n.sym->ts;
> -	  gfc_typespec *ts2 = &expr2->symtree->n.sym->ts;
> + 	  gfc_typespec *ts2 = &expr2->symtree->n.sym->ts;

[Ignore the "ts2"-line change: I have accidentally added a spurious " " 
in column 1, and missed it when sending the patch out.]

Tobias
Paul Richard Thomas Aug. 30, 2014, 11:54 a.m. UTC | #2
Dear Tobias,

Given Dominques news that this fixes a golden oldie that drove me to
madness and PR60593 - OK for trunk, 4.8 and 4.9

Many thanks for the patch

Paul

On 27 August 2014 22:59, Tobias Burnus <burnus@net-b.de> wrote:
> The current gfc_check_dependency check always looked at the pointer
> attribute - and assumed the worst, if either the LHS or the RHS was true.
>
> Thus, it claimed that "a" and "b" alias for the following definition:
> integer, pointer :: p;  integer :: a. However, as "a" has no target (or
> pointer) attribute, that's not possible. Additionally, "class(t) :: a" has
> internally the "pointer" attribute (but CLASS_DATA(sym)->attr.class_pointer
> == 0), however, in the Fortran sense, "a" is not a pointer and cannot alias.
>
> I do not have a good example for the test case, except for a similar one as
> above using "a[i] = p" and looking at the dump; but that requires patch 3/3
> of this series.
>
> Build and regtested on x86-64-gnu-linux. (I do get a failure for
> gfortran.dg/graphite/pr42393.f90, but only with -O1 -fgraphite-identity and
> also without the patch.)
>
> OK for the trunk?
>
> Tobias
diff mbox

Patch

2014-08-27  Tobias Burnus  <burnus@net-b.de>

	PR fortran/62278
	* dependency.c (gfc_check_dependency): Allow for optimizations
	in the pointer-alias check.

diff --git a/gcc/fortran/dependency.c b/gcc/fortran/dependency.c
index c18482a..1cdd141 100644
--- a/gcc/fortran/dependency.c
+++ b/gcc/fortran/dependency.c
@@ -1269,8 +1269,9 @@  gfc_check_dependency (gfc_expr *expr1, gfc_expr *expr2, bool identical)
       /* The interesting cases are when the symbols don't match.  */
       if (expr1->symtree->n.sym != expr2->symtree->n.sym)
 	{
+	  symbol_attribute attr1, attr2;
 	  gfc_typespec *ts1 = &expr1->symtree->n.sym->ts;
-	  gfc_typespec *ts2 = &expr2->symtree->n.sym->ts;
+ 	  gfc_typespec *ts2 = &expr2->symtree->n.sym->ts;
 
 	  /* Return 1 if expr1 and expr2 are equivalenced arrays.  */
 	  if (gfc_are_equivalenced_arrays (expr1, expr2))
@@ -1284,9 +1285,13 @@  gfc_check_dependency (gfc_expr *expr1, gfc_expr *expr2, bool identical)
 		return 0;
 	    }
 
-	  /* If either variable is a pointer, assume the worst.  */
-	  /* TODO: -fassume-no-pointer-aliasing */
-	  if (gfc_is_data_pointer (expr1) || gfc_is_data_pointer (expr2))
+	  /* We have to also include target-target as ptr%comp is not a
+	     pointer but it still alias with "dt%comp" for "ptr => dt".  As
+	     subcomponents and array access to pointers retains the target
+	     attribute, that's sufficient.  */
+	  attr1 = gfc_expr_attr (expr1);
+	  attr2 = gfc_expr_attr (expr2);
+	  if ((attr1.pointer || attr1.target) && (attr2.pointer || attr2.target))
 	    {
 	      if (check_data_pointer_types (expr1, expr2)
 		    && check_data_pointer_types (expr2, expr1))