[PATCH] Improve SCEV for array element

Jiangning Liu jiangning.liu@arm.com
Wed Jan 18 07:41:00 GMT 2012


This code change intends to improve scev for array element and reduce the
common sub-expressions in loop, which may be introduced by multiple
reference of expression like &a[i]. With this optimization the register
pressure can be reduced in loops. 

The problem is originally from a real benchmark, and the test case only
tries to detect the GIMPLE level changes.

Bootstraped on x86-32. OK for trunk?

ChangeLog:

2012-01-05  Jiangning Liu  <jiangning.liu@arm.com>

        * tree-scalar-evolution (interpret_rhs_expr): generate chrec for
        array reference.

ChangeLog for testsuite:

2012-01-05  Jiangning Liu  <jiangning.liu@arm.com>

        * gcc.dg/scev-1.c: New.

diff --git a/gcc/testsuite/gcc.dg/scev-1.c b/gcc/testsuite/gcc.dg/scev-1.c
new file mode 100644 index 0000000..28d5c93
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/scev-1.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int *a_p;
+int a[1000];
+
+f(int k)
+{
+	int i;
+
+	for (i=k; i<1000; i+=k) {
+		a_p = &a[i];
+		*a_p = 100;
+        }
+}
+
+/* { dg-final { scan-tree-dump-times "&a" 1 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c index
2077c8d..de89fc4
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -1712,6 +1712,42 @@ interpret_rhs_expr (struct loop *loop, gimple
at_stmt,
   switch (code)
     {
     case ADDR_EXPR:
+      if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == ARRAY_REF)
+        {
+	  tree array_ref;
+	  tree var_decl, base, offset;
+	  tree low_bound;
+	  tree unit_size;
+	  tree index;
+
+	  array_ref = TREE_OPERAND (rhs1, 0);
+	  var_decl = TREE_OPERAND (array_ref, 0);
+	  index = TREE_OPERAND (array_ref, 1);
+
+	  low_bound = array_ref_low_bound (array_ref);
+	  unit_size = array_ref_element_size (array_ref);
+
+	  /* We assume all arrays have sizes that are a multiple of a byte.
+	     First subtract the lower bound, if any, in the type of the
+	     index, then convert to sizetype and multiply by the size of
+	     the array element.  */
+	  if (! integer_zerop (low_bound))
+	    index = fold_build2 (MINUS_EXPR, TREE_TYPE (index),
+				 index, low_bound);
+
+	  offset = size_binop (MULT_EXPR,
+			       fold_convert (sizetype, index),
+			       unit_size);
+
+	  base = build1 (ADDR_EXPR, TREE_TYPE (rhs1), var_decl);
+	  chrec1 = analyze_scalar_evolution (loop, base);
+	  chrec2 = analyze_scalar_evolution (loop, offset);
+          chrec1 = chrec_convert (type, chrec1, at_stmt);
+          chrec2 = chrec_convert (TREE_TYPE (offset), chrec2, at_stmt);
+	  res = chrec_fold_plus (type, chrec1, chrec2);
+	  break;
+        }
+
       /* Handle &MEM[ptr + CST] which is equivalent to POINTER_PLUS_EXPR.
*/
       if (TREE_CODE (TREE_OPERAND (rhs1, 0)) != MEM_REF)
 	{

Thanks,
-Jiangning
-------------- next part --------------
A non-text attachment was scrubbed...
Name: scev.patch
Type: application/octet-stream
Size: 2175 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20120118/f77e8605/attachment.obj>


More information about the Gcc-patches mailing list