This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix some weird IVOPTs choices (part of PR26726)
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 28 Apr 2006 16:32:07 +0200 (CEST)
- Subject: [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" } } */