This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix some weird IVOPTs choices (part of PR26726)


Currently, for PR26726 we generate an "interesting" MEM-ref, namely

<bb 2>:
  ivtmp.39_12 = &x[1];

  # ivtmp.39_10 = PHI <ivtmp.39_11(4), ivtmp.39_12(2)>;
<L0>:;
  D.2068_13 = (int *) &x[0];
  D.2069_29 = (int *) ivtmp.39_10;
  D.2070_28 = D.2068_13 + D.2069_29;
  D.2071_27 = -&x;
  D.2072_26 = (int *) D.2071_27;
  MEM[base: D.2070_28, index: D.2072_26, offset: -4B]{D.2003->s} = 1;
  ivtmp.39_11 = ivtmp.39_10 + 4B;
  if (ivtmp.39_11 != &x[5]) goto <L5>; else goto <L2>;

which has a base &x[0] + ivtmp and an index of -&x, ivtmp being counted
from &x[1] to &x[5].  This is due to the fact that we do not fold
the IV uses base address, but have

use 0
  address
  in statement D.2003_30->s = 1
  at position D.2003_30->s
  type int *
  base &(&x[0])->s
  step 4
  base object (void *) &x
  related candidates

which confuses us a lot.  The patch addresses this and results in the
more appropriate 

<bb 2>:
  ivtmp.39_12 = &x[1];

  # ivtmp.39_10 = PHI <ivtmp.39_11(4), ivtmp.39_12(2)>;
<L0>:;
  D.2068_13 = (int *) ivtmp.39_10;
  MEM[base: D.2068_13, offset: -4B]{D.2003->s} = 1;
  ivtmp.39_11 = ivtmp.39_10 + 4B;
  if (ivtmp.39_11 != &x[5]) goto <L5>; else goto <L2>;

being created.  The -4B offset is due to the i386 backend cost metrics
appearantly, as noted by Zdenek.

Bootstrapped and tested on x86_64-unknown-linux-gnu.  The testcase
also checks for (xfailed) the weird offset and the &x[5] reference,
which is sort-of-wrong-code (and the actual reason for the PR).

Ok for mainline?

Thanks,
Richard.

:ADDPATCH ivopts:


2006-04-27  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/26726
	* tree-ssa-loop-ivopts.c (find_bivs): Strip useless
	type conversions from base addresses.
	(idx_find_step): Mark source of the problem ...
	(find_interesting_uses_address): ... we work around here
	by folding INDIRECT_REFs in the substituted base.

	* g++.dg/tree-ssa/ivopts-1.C: New testcase.


Index: tree-ssa-loop-ivopts.c
===================================================================
*** tree-ssa-loop-ivopts.c	(revision 113341)
--- tree-ssa-loop-ivopts.c	(working copy)
*************** find_bivs (struct ivopts_data *data)
*** 975,982 ****
  
        type = TREE_TYPE (PHI_RESULT (phi));
        base = fold_convert (type, base);
        if (step)
! 	step = fold_convert (type, step);
  
        set_iv (data, PHI_RESULT (phi), base, step);
        found = true;
--- 975,983 ----
  
        type = TREE_TYPE (PHI_RESULT (phi));
        base = fold_convert (type, base);
+       STRIP_USELESS_TYPE_CONVERSION (base);
        if (step)
! 	step = fold_convert (TREE_TYPE (base), step);
  
        set_iv (data, PHI_RESULT (phi), base, step);
        found = true;
*************** idx_find_step (tree base, tree *idx, voi
*** 1376,1381 ****
--- 1377,1385 ----
    if (!iv)
      return false;
  
+   /* XXX  We produce for a base of *D42 with iv->base being &x[0]
+ 	  *&x[0], which is not folded and does not trigger the
+ 	  ARRAY_REF path below.  */
    *idx = iv->base;
  
    if (!iv->step)
*************** find_interesting_uses_address (struct iv
*** 1536,1541 ****
--- 1540,1546 ----
      }
    else
      {
+       tree *ref;
        ifs_ivopts_data.ivopts_data = data;
        ifs_ivopts_data.stmt = stmt;
        ifs_ivopts_data.step_p = &step;
*************** find_interesting_uses_address (struct iv
*** 1547,1552 ****
--- 1552,1568 ----
        gcc_assert (TREE_CODE (base) != MISALIGNED_INDIRECT_REF);
  
        base = build_fold_addr_expr (base);
+ 
+       /* Substituting bases of IVs into the base expression might
+ 	 have caused folding opportunities.  */
+       if (TREE_CODE (base) == ADDR_EXPR)
+ 	{
+ 	  ref = &TREE_OPERAND (base, 0);
+ 	  while (handled_component_p (*ref))
+ 	    ref = &TREE_OPERAND (*ref, 0);
+ 	  if (TREE_CODE (*ref) == INDIRECT_REF)
+ 	    *ref = fold_indirect_ref (*ref);
+ 	}
      }
  
    civ = alloc_iv (base, step);
Index: testsuite/g++.dg/tree-ssa/ivopts-1.C
===================================================================
*** testsuite/g++.dg/tree-ssa/ivopts-1.C	(revision 0)
--- testsuite/g++.dg/tree-ssa/ivopts-1.C	(revision 0)
***************
*** 0 ****
--- 1,18 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O2 -fdump-tree-ivopts" } */
+ 
+ struct Foo {
+   Foo() : s(1) {}
+   int s;
+ };
+ void foo(Foo&);
+ void bar(void)
+ {
+   Foo x[4];
+   foo(x[0]);
+ }
+ 
+ /* { dg-final { scan-tree-dump-not "-&x" "ivopts" } } */
+ /* { dg-final { scan-tree-dump-not "offset: -4B" "ivopts" { xfail *-*-* } } } */
+ /* { dg-final { scan-tree-dump-not "&x\\\[5\\\]" "ivopts" { xfail *-*-* } } } */
+ /* { dg-final { cleanup-tree-dump "ivopts" } } */




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]