This is the mail archive of the 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]



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

	* tree-scalar-evolution.c (interpret_rhs_expr): Handle
 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,
+      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;

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