This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Handle ADDR_EXPR in SCEV
- From: Alexander Monakov <amonakov at ispras dot ru>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Richard Guenther <richard dot guenther at gmail dot com>
- Date: Wed, 17 Feb 2010 13:39:43 +0300 (MSK)
- Subject: [PATCH] Handle ADDR_EXPR in SCEV
Hi,
Currently, SCEV analysis is not able to decompose scalar evolutions of
expressions like &a[i] into scev(&a[0]) + scev(i). Proposed patch improves
SCEV by teaching it to decompose ADDR_EXPRs in interpret_rhs_expr in a manner
similar to how ADDR_EXPRs are handled in tree-data-ref.c.
This is useful to reduce number of induction variables in simple loops with
-fprefetch-loop-arrays (prefetch pass inserts
__builtin_prefetch(&a[i+offset])). It also improves ivopts in cases like
below (with arrays in structures).
struct {
int a;
int b[4200];
} bars[123123];
int asd(int n)
{
int i, s = 0;
int *c;
for (i = 0; i < n; i++)
for (c = bars[i].b; c < &bars[i].b[bars[i].a]; c++)
s += *c;
return s;
}
The patch reduces size of reload1.o by about 2KB, other cc1 .o files
grow/shrink by small amounts. However, on the same reload1.o I see that the
patch sometimes increases function frame size.
Speed improvement on spec2k for a core2 with profile feedback and the following options:
-O3 -ffast-math -march=native -fsched-pressure -fschedule-insns -fprefetch-loop-arrays
is +1% for FP, no average change for INT.
Bootstrapped and regtested on x86_64-linux. I've browsed through the list of
regressions and I doubt this patch fixes any, so: OK for stage 1?
2010-02-17 Alexander Monakov <amonakov@ispras.ru>
* tree-scalar-evolution.c (interpret_rhs_expr): Handle
ADDR_EXPR.
---
gcc/tree-scalar-evolution.c | 28 ++++++++++++++++++++++++++++
1 files changed, 28 insertions(+), 0 deletions(-)
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
index 4d8f85e..b9f7125 100644
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -1720,6 +1720,34 @@ interpret_rhs_expr (struct loop *loop, gimple at_stmt,
at_stmt);
}
+ if (code == ADDR_EXPR
+ && handled_component_p (TREE_OPERAND (rhs1, 0)))
+ {
+ HOST_WIDE_INT bitsize, bitpos;
+ tree toff, base, ref;
+ enum machine_mode mode;
+ int uns, vol;
+
+ ref = TREE_OPERAND (rhs1, 0);
+ base = get_inner_reference (ref, &bitsize, &bitpos, &toff, &mode,
+ &uns, &vol, false);
+ if (bitpos % BITS_PER_UNIT == 0)
+ {
+ base = build_fold_addr_expr (base);
+ chrec1 = analyze_scalar_evolution (loop, base);
+ chrec1 = chrec_convert (type, chrec1, at_stmt);
+ chrec1 = chrec_fold_plus (type, chrec1,
+ size_int (bitpos / BITS_PER_UNIT));
+ if (toff)
+ {
+ chrec2 = analyze_scalar_evolution (loop, toff);
+ chrec2 = chrec_convert (sizetype, chrec2, at_stmt);
+ chrec1 = chrec_fold_plus (type, chrec1, chrec2);
+ }
+ return chrec1;
+ }
+ }
+
return chrec_dont_know;
}