* Re: [PATCH] Improve SCEV for array element
[not found] <4f1677c5.0630440a.1021.ffffb00eSMTPIN_ADDED@mx.google.com>
@ 2012-01-18 10:33 ` Richard Guenther
2012-01-20 9:07 ` Jiangning Liu
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Richard Guenther @ 2012-01-18 10:33 UTC (permalink / raw)
To: Jiangning Liu; +Cc: gcc-patches
On Wed, Jan 18, 2012 at 8:41 AM, Jiangning Liu <jiangning.liu@arm.com> wrote:
> 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?
It's definitely not ok at this stage but at most for next stage1. But ...
> 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)
This is a very narrow pattern-match. It doesn't allow for &a[i].x for example,
even if a[i] is a one-element structure. I think the canonical way of handling
ADDR_EXPR is to use sth like
base = get_inner_reference (TREE_OPERAND (rhs1, 0), ..., &offset, ...);
base = build1 (ADDR_EXPR, TREE_TYPE (rhs1), base);
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);
where you probably need to handle scev_not_known when analyzing offset
(which might be NULL). You also need to add bitpos to the base address
(in bytes, of course). Note that the &MEM_REF case would naturally work
with this as well.
Richard.
> + {
> + 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
^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: [PATCH] Improve SCEV for array element
2012-01-18 10:33 ` [PATCH] Improve SCEV for array element Richard Guenther
@ 2012-01-20 9:07 ` Jiangning Liu
2012-02-13 10:15 ` Jiangning Liu
[not found] ` <4f38de06.0630440a.4838.5731SMTPIN_ADDED@mx.google.com>
[not found] ` <4f192ee1.c84b440a.3d24.ffffae31SMTPIN_ADDED@mx.google.com>
2 siblings, 1 reply; 10+ messages in thread
From: Jiangning Liu @ 2012-01-20 9:07 UTC (permalink / raw)
To: 'Richard Guenther'; +Cc: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 5177 bytes --]
> It's definitely not ok at this stage but at most for next stage1.
OK. I may wait until next stage1.
> This is a very narrow pattern-match. It doesn't allow for &a[i].x for
> example,
> even if a[i] is a one-element structure. I think the canonical way of
> handling
> ADDR_EXPR is to use sth like
>
> base = get_inner_reference (TREE_OPERAND (rhs1, 0), ..., &offset, ...);
> base = build1 (ADDR_EXPR, TREE_TYPE (rhs1), base);
> 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);
>
> where you probably need to handle scev_not_known when analyzing offset
> (which might be NULL). You also need to add bitpos to the base address
> (in bytes, of course). Note that the &MEM_REF case would naturally
> work
> with this as well.
OK. New patch is like below, and bootstrapped on x86-32.
ChangeLog:
2012-01-20 Jiangning Liu <jiangning.liu@arm.com>
* tree-scalar-evolution (interpret_rhs_expr): generate chrec for
array reference and component reference.
ChangeLog for testsuite:
2012-01-20 Jiangning Liu <jiangning.liu@arm.com>
* gcc.dg/tree-ssa/scev-3.c: New.
* gcc.dg/tree-ssa/scev-4.c: New.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/scev-3.c
b/gcc/testsuite/gcc.dg/tree-ssa/scev-3.c
new file mode 100644
index 0000000..28d5c93
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-3.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/testsuite/gcc.dg/tree-ssa/scev-4.c
b/gcc/testsuite/gcc.dg/tree-ssa/scev-4.c
new file mode 100644
index 0000000..6c1e530
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-4.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+typedef struct {
+ int x;
+ int y;
+} S;
+
+int *a_p;
+S a[1000];
+
+f(int k)
+{
+ int i;
+
+ for (i=k; i<1000; i+=k) {
+ a_p = &a[i].y;
+ *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..4e06b75
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -1712,16 +1712,61 @@ interpret_rhs_expr (struct loop *loop, gimple
at_stmt,
switch (code)
{
case ADDR_EXPR:
- /* Handle &MEM[ptr + CST] which is equivalent to POINTER_PLUS_EXPR.
*/
- if (TREE_CODE (TREE_OPERAND (rhs1, 0)) != MEM_REF)
- {
- res = chrec_dont_know;
- break;
- }
+ if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == ARRAY_REF
+ || TREE_CODE (TREE_OPERAND (rhs1, 0)) == MEM_REF
+ || TREE_CODE (TREE_OPERAND (rhs1, 0)) == COMPONENT_REF)
+ {
+ enum machine_mode mode;
+ HOST_WIDE_INT bitsize, bitpos;
+ int unsignedp;
+ int volatilep = 0;
+ tree base, offset;
+ tree chrec3;
+
+ base = get_inner_reference (TREE_OPERAND (rhs1, 0),
+ &bitsize, &bitpos, &offset,
+ &mode, &unsignedp, &volatilep, false);
+
+ if (TREE_CODE (base) == MEM_REF)
+ {
+ rhs2 = TREE_OPERAND (base, 1);
+ rhs1 = TREE_OPERAND (base, 0);
+
+ chrec1 = analyze_scalar_evolution (loop, rhs1);
+ chrec2 = analyze_scalar_evolution (loop, rhs2);
+ chrec1 = chrec_convert (type, chrec1, at_stmt);
+ chrec2 = chrec_convert (TREE_TYPE (rhs2), chrec2, at_stmt);
+ res = chrec_fold_plus (type, chrec1, chrec2);
+ }
+ else
+ {
+ base = build1 (ADDR_EXPR, TREE_TYPE (rhs1), base);
+ chrec1 = analyze_scalar_evolution (loop, base);
+ chrec1 = chrec_convert (type, chrec1, at_stmt);
+ res = chrec1;
+ }
- rhs2 = TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1);
- rhs1 = TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0);
- /* Fall through. */
+ if (offset != NULL_TREE)
+ {
+ chrec2 = analyze_scalar_evolution (loop, offset);
+ chrec2 = chrec_convert (TREE_TYPE (offset), chrec2, at_stmt);
+ res = chrec_fold_plus (type, res, chrec2);
+ }
+
+ if (bitpos)
+ {
+ gcc_assert ((bitpos % BITS_PER_UNIT) == 0);
+
+ chrec3 = build_int_cst (integer_type_node,
+ bitpos / BITS_PER_UNIT);
+ chrec3 = analyze_scalar_evolution (loop, chrec3);
+ chrec3 = chrec_convert (integer_type_node, chrec3, at_stmt);
+ res = chrec_fold_plus (type, res, chrec3);
+ }
+ }
+ else
+ res = chrec_dont_know;
+ break;
case POINTER_PLUS_EXPR:
chrec1 = analyze_scalar_evolution (loop, rhs1);
Thanks,
-Jiangning
[-- Attachment #2: scev-2.patch --]
[-- Type: application/octet-stream, Size: 3586 bytes --]
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/scev-3.c b/gcc/testsuite/gcc.dg/tree-ssa/scev-3.c
new file mode 100644
index 0000000..28d5c93
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-3.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/testsuite/gcc.dg/tree-ssa/scev-4.c b/gcc/testsuite/gcc.dg/tree-ssa/scev-4.c
new file mode 100644
index 0000000..6c1e530
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-4.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+typedef struct {
+ int x;
+ int y;
+} S;
+
+int *a_p;
+S a[1000];
+
+f(int k)
+{
+ int i;
+
+ for (i=k; i<1000; i+=k) {
+ a_p = &a[i].y;
+ *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..4e06b75
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -1712,16 +1712,61 @@ interpret_rhs_expr (struct loop *loop, gimple at_stmt,
switch (code)
{
case ADDR_EXPR:
- /* Handle &MEM[ptr + CST] which is equivalent to POINTER_PLUS_EXPR. */
- if (TREE_CODE (TREE_OPERAND (rhs1, 0)) != MEM_REF)
- {
- res = chrec_dont_know;
- break;
- }
+ if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == ARRAY_REF
+ || TREE_CODE (TREE_OPERAND (rhs1, 0)) == MEM_REF
+ || TREE_CODE (TREE_OPERAND (rhs1, 0)) == COMPONENT_REF)
+ {
+ enum machine_mode mode;
+ HOST_WIDE_INT bitsize, bitpos;
+ int unsignedp;
+ int volatilep = 0;
+ tree base, offset;
+ tree chrec3;
+
+ base = get_inner_reference (TREE_OPERAND (rhs1, 0),
+ &bitsize, &bitpos, &offset,
+ &mode, &unsignedp, &volatilep, false);
+
+ if (TREE_CODE (base) == MEM_REF)
+ {
+ rhs2 = TREE_OPERAND (base, 1);
+ rhs1 = TREE_OPERAND (base, 0);
+
+ chrec1 = analyze_scalar_evolution (loop, rhs1);
+ chrec2 = analyze_scalar_evolution (loop, rhs2);
+ chrec1 = chrec_convert (type, chrec1, at_stmt);
+ chrec2 = chrec_convert (TREE_TYPE (rhs2), chrec2, at_stmt);
+ res = chrec_fold_plus (type, chrec1, chrec2);
+ }
+ else
+ {
+ base = build1 (ADDR_EXPR, TREE_TYPE (rhs1), base);
+ chrec1 = analyze_scalar_evolution (loop, base);
+ chrec1 = chrec_convert (type, chrec1, at_stmt);
+ res = chrec1;
+ }
- rhs2 = TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1);
- rhs1 = TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0);
- /* Fall through. */
+ if (offset != NULL_TREE)
+ {
+ chrec2 = analyze_scalar_evolution (loop, offset);
+ chrec2 = chrec_convert (TREE_TYPE (offset), chrec2, at_stmt);
+ res = chrec_fold_plus (type, res, chrec2);
+ }
+
+ if (bitpos)
+ {
+ gcc_assert ((bitpos % BITS_PER_UNIT) == 0);
+
+ chrec3 = build_int_cst (integer_type_node,
+ bitpos / BITS_PER_UNIT);
+ chrec3 = analyze_scalar_evolution (loop, chrec3);
+ chrec3 = chrec_convert (integer_type_node, chrec3, at_stmt);
+ res = chrec_fold_plus (type, res, chrec3);
+ }
+ }
+ else
+ res = chrec_dont_know;
+ break;
case POINTER_PLUS_EXPR:
chrec1 = analyze_scalar_evolution (loop, rhs1);
^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: [PATCH] Improve SCEV for array element
2012-01-20 9:07 ` Jiangning Liu
@ 2012-02-13 10:15 ` Jiangning Liu
0 siblings, 0 replies; 10+ messages in thread
From: Jiangning Liu @ 2012-02-13 10:15 UTC (permalink / raw)
To: Jiangning Liu, 'Richard Guenther'; +Cc: gcc-patches
> -----Original Message-----
> From: gcc-patches-owner@gcc.gnu.org [mailto:gcc-patches-
> owner@gcc.gnu.org] On Behalf Of Jiangning Liu
> Sent: Friday, January 20, 2012 5:07 PM
> To: 'Richard Guenther'
> Cc: gcc-patches@gcc.gnu.org
> Subject: RE: [PATCH] Improve SCEV for array element
>
> > It's definitely not ok at this stage but at most for next stage1.
>
> OK. I may wait until next stage1.
>
> > This is a very narrow pattern-match. It doesn't allow for &a[i].x
> for
> > example, even if a[i] is a one-element structure. I think the
> > canonical way of handling ADDR_EXPR is to use sth like
> >
> > base = get_inner_reference (TREE_OPERAND (rhs1, 0), ..., &offset,
> > ...); base = build1 (ADDR_EXPR, TREE_TYPE (rhs1), base);
> > 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);
> >
> > where you probably need to handle scev_not_known when analyzing
> offset
> > (which might be NULL). You also need to add bitpos to the base
> > address (in bytes, of course). Note that the &MEM_REF case would
> > naturally work with this as well.
>
> OK. New patch is like below, and bootstrapped on x86-32.
>
> ChangeLog:
>
> 2012-01-20 Jiangning Liu <jiangning.liu@arm.com>
>
> * tree-scalar-evolution (interpret_rhs_expr): generate chrec
> for
> array reference and component reference.
>
>
> ChangeLog for testsuite:
>
> 2012-01-20 Jiangning Liu <jiangning.liu@arm.com>
>
> * gcc.dg/tree-ssa/scev-3.c: New.
> * gcc.dg/tree-ssa/scev-4.c: New.
>
Richard,
PING... Is this patch OK after branch 4.7 is created and trunk is open
again?
Thanks,
-Jiangning
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/scev-3.c
> b/gcc/testsuite/gcc.dg/tree-ssa/scev-3.c
> new file mode 100644
> index 0000000..28d5c93
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-3.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/testsuite/gcc.dg/tree-ssa/scev-4.c
> b/gcc/testsuite/gcc.dg/tree-ssa/scev-4.c
> new file mode 100644
> index 0000000..6c1e530
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-4.c
> @@ -0,0 +1,23 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +typedef struct {
> + int x;
> + int y;
> +} S;
> +
> +int *a_p;
> +S a[1000];
> +
> +f(int k)
> +{
> + int i;
> +
> + for (i=k; i<1000; i+=k) {
> + a_p = &a[i].y;
> + *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..4e06b75
> --- a/gcc/tree-scalar-evolution.c
> +++ b/gcc/tree-scalar-evolution.c
> @@ -1712,16 +1712,61 @@ interpret_rhs_expr (struct loop *loop, gimple
> at_stmt,
> switch (code)
> {
> case ADDR_EXPR:
> - /* Handle &MEM[ptr + CST] which is equivalent to
> POINTER_PLUS_EXPR.
> */
> - if (TREE_CODE (TREE_OPERAND (rhs1, 0)) != MEM_REF)
> - {
> - res = chrec_dont_know;
> - break;
> - }
> + if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == ARRAY_REF
> + || TREE_CODE (TREE_OPERAND (rhs1, 0)) == MEM_REF
> + || TREE_CODE (TREE_OPERAND (rhs1, 0)) == COMPONENT_REF)
> + {
> + enum machine_mode mode;
> + HOST_WIDE_INT bitsize, bitpos;
> + int unsignedp;
> + int volatilep = 0;
> + tree base, offset;
> + tree chrec3;
> +
> + base = get_inner_reference (TREE_OPERAND (rhs1, 0),
> + &bitsize, &bitpos, &offset,
> + &mode, &unsignedp, &volatilep, false);
> +
> + if (TREE_CODE (base) == MEM_REF)
> + {
> + rhs2 = TREE_OPERAND (base, 1);
> + rhs1 = TREE_OPERAND (base, 0);
> +
> + chrec1 = analyze_scalar_evolution (loop, rhs1);
> + chrec2 = analyze_scalar_evolution (loop, rhs2);
> + chrec1 = chrec_convert (type, chrec1, at_stmt);
> + chrec2 = chrec_convert (TREE_TYPE (rhs2), chrec2, at_stmt);
> + res = chrec_fold_plus (type, chrec1, chrec2);
> + }
> + else
> + {
> + base = build1 (ADDR_EXPR, TREE_TYPE (rhs1), base);
> + chrec1 = analyze_scalar_evolution (loop, base);
> + chrec1 = chrec_convert (type, chrec1, at_stmt);
> + res = chrec1;
> + }
>
> - rhs2 = TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1);
> - rhs1 = TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0);
> - /* Fall through. */
> + if (offset != NULL_TREE)
> + {
> + chrec2 = analyze_scalar_evolution (loop, offset);
> + chrec2 = chrec_convert (TREE_TYPE (offset), chrec2, at_stmt);
> + res = chrec_fold_plus (type, res, chrec2);
> + }
> +
> + if (bitpos)
> + {
> + gcc_assert ((bitpos % BITS_PER_UNIT) == 0);
> +
> + chrec3 = build_int_cst (integer_type_node,
> + bitpos / BITS_PER_UNIT);
> + chrec3 = analyze_scalar_evolution (loop, chrec3);
> + chrec3 = chrec_convert (integer_type_node, chrec3, at_stmt);
> + res = chrec_fold_plus (type, res, chrec3);
> + }
> + }
> + else
> + res = chrec_dont_know;
> + break;
>
> case POINTER_PLUS_EXPR:
> chrec1 = analyze_scalar_evolution (loop, rhs1);
>
> Thanks,
> -Jiangning
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] Improve SCEV for array element
[not found] ` <4f38de06.0630440a.4838.5731SMTPIN_ADDED@mx.google.com>
@ 2012-02-13 11:30 ` Richard Guenther
0 siblings, 0 replies; 10+ messages in thread
From: Richard Guenther @ 2012-02-13 11:30 UTC (permalink / raw)
To: Jiangning Liu; +Cc: gcc-patches
On Mon, Feb 13, 2012 at 10:54 AM, Jiangning Liu <jiangning.liu@arm.com> wrote:
>
>
>> -----Original Message-----
>> From: gcc-patches-owner@gcc.gnu.org [mailto:gcc-patches-
>> owner@gcc.gnu.org] On Behalf Of Jiangning Liu
>> Sent: Friday, January 20, 2012 5:07 PM
>> To: 'Richard Guenther'
>> Cc: gcc-patches@gcc.gnu.org
>> Subject: RE: [PATCH] Improve SCEV for array element
>>
>> > It's definitely not ok at this stage but at most for next stage1.
>>
>> OK. I may wait until next stage1.
>>
>> > This is a very narrow pattern-match. It doesn't allow for &a[i].x
>> for
>> > example, even if a[i] is a one-element structure. I think the
>> > canonical way of handling ADDR_EXPR is to use sth like
>> >
>> > base = get_inner_reference (TREE_OPERAND (rhs1, 0), ..., &offset,
>> > ...); base = build1 (ADDR_EXPR, TREE_TYPE (rhs1), base);
>> > 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);
>> >
>> > where you probably need to handle scev_not_known when analyzing
>> offset
>> > (which might be NULL). You also need to add bitpos to the base
>> > address (in bytes, of course). Note that the &MEM_REF case would
>> > naturally work with this as well.
>>
>> OK. New patch is like below, and bootstrapped on x86-32.
>>
>> ChangeLog:
>>
>> 2012-01-20 Jiangning Liu <jiangning.liu@arm.com>
>>
>> * tree-scalar-evolution (interpret_rhs_expr): generate chrec
>> for
>> array reference and component reference.
>>
>>
>> ChangeLog for testsuite:
>>
>> 2012-01-20 Jiangning Liu <jiangning.liu@arm.com>
>>
>> * gcc.dg/tree-ssa/scev-3.c: New.
>> * gcc.dg/tree-ssa/scev-4.c: New.
>>
>
> Richard,
>
> PING... Is this patch OK after branch 4.7 is created and trunk is open
> again?
It's on my (rather large) list of things to review for 4.8. Be patient ...
Richard.
> Thanks,
> -Jiangning
>
>> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/scev-3.c
>> b/gcc/testsuite/gcc.dg/tree-ssa/scev-3.c
>> new file mode 100644
>> index 0000000..28d5c93
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-3.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/testsuite/gcc.dg/tree-ssa/scev-4.c
>> b/gcc/testsuite/gcc.dg/tree-ssa/scev-4.c
>> new file mode 100644
>> index 0000000..6c1e530
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-4.c
>> @@ -0,0 +1,23 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-O2 -fdump-tree-optimized" } */
>> +
>> +typedef struct {
>> + int x;
>> + int y;
>> +} S;
>> +
>> +int *a_p;
>> +S a[1000];
>> +
>> +f(int k)
>> +{
>> + int i;
>> +
>> + for (i=k; i<1000; i+=k) {
>> + a_p = &a[i].y;
>> + *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..4e06b75
>> --- a/gcc/tree-scalar-evolution.c
>> +++ b/gcc/tree-scalar-evolution.c
>> @@ -1712,16 +1712,61 @@ interpret_rhs_expr (struct loop *loop, gimple
>> at_stmt,
>> switch (code)
>> {
>> case ADDR_EXPR:
>> - /* Handle &MEM[ptr + CST] which is equivalent to
>> POINTER_PLUS_EXPR.
>> */
>> - if (TREE_CODE (TREE_OPERAND (rhs1, 0)) != MEM_REF)
>> - {
>> - res = chrec_dont_know;
>> - break;
>> - }
>> + if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == ARRAY_REF
>> + || TREE_CODE (TREE_OPERAND (rhs1, 0)) == MEM_REF
>> + || TREE_CODE (TREE_OPERAND (rhs1, 0)) == COMPONENT_REF)
>> + {
>> + enum machine_mode mode;
>> + HOST_WIDE_INT bitsize, bitpos;
>> + int unsignedp;
>> + int volatilep = 0;
>> + tree base, offset;
>> + tree chrec3;
>> +
>> + base = get_inner_reference (TREE_OPERAND (rhs1, 0),
>> + &bitsize, &bitpos, &offset,
>> + &mode, &unsignedp, &volatilep, false);
>> +
>> + if (TREE_CODE (base) == MEM_REF)
>> + {
>> + rhs2 = TREE_OPERAND (base, 1);
>> + rhs1 = TREE_OPERAND (base, 0);
>> +
>> + chrec1 = analyze_scalar_evolution (loop, rhs1);
>> + chrec2 = analyze_scalar_evolution (loop, rhs2);
>> + chrec1 = chrec_convert (type, chrec1, at_stmt);
>> + chrec2 = chrec_convert (TREE_TYPE (rhs2), chrec2, at_stmt);
>> + res = chrec_fold_plus (type, chrec1, chrec2);
>> + }
>> + else
>> + {
>> + base = build1 (ADDR_EXPR, TREE_TYPE (rhs1), base);
>> + chrec1 = analyze_scalar_evolution (loop, base);
>> + chrec1 = chrec_convert (type, chrec1, at_stmt);
>> + res = chrec1;
>> + }
>>
>> - rhs2 = TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1);
>> - rhs1 = TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0);
>> - /* Fall through. */
>> + if (offset != NULL_TREE)
>> + {
>> + chrec2 = analyze_scalar_evolution (loop, offset);
>> + chrec2 = chrec_convert (TREE_TYPE (offset), chrec2, at_stmt);
>> + res = chrec_fold_plus (type, res, chrec2);
>> + }
>> +
>> + if (bitpos)
>> + {
>> + gcc_assert ((bitpos % BITS_PER_UNIT) == 0);
>> +
>> + chrec3 = build_int_cst (integer_type_node,
>> + bitpos / BITS_PER_UNIT);
>> + chrec3 = analyze_scalar_evolution (loop, chrec3);
>> + chrec3 = chrec_convert (integer_type_node, chrec3, at_stmt);
>> + res = chrec_fold_plus (type, res, chrec3);
>> + }
>> + }
>> + else
>> + res = chrec_dont_know;
>> + break;
>>
>> case POINTER_PLUS_EXPR:
>> chrec1 = analyze_scalar_evolution (loop, rhs1);
>>
>> Thanks,
>> -Jiangning
>
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] Improve SCEV for array element
[not found] ` <4f192ee1.c84b440a.3d24.ffffae31SMTPIN_ADDED@mx.google.com>
@ 2012-03-06 13:11 ` Richard Guenther
2012-03-08 7:13 ` Jiangning Liu
` (3 more replies)
0 siblings, 4 replies; 10+ messages in thread
From: Richard Guenther @ 2012-03-06 13:11 UTC (permalink / raw)
To: Jiangning Liu; +Cc: gcc-patches
On Fri, Jan 20, 2012 at 10:06 AM, Jiangning Liu <jiangning.liu@arm.com> wrote:
>> It's definitely not ok at this stage but at most for next stage1.
>
> OK. I may wait until next stage1.
>
>> This is a very narrow pattern-match. It doesn't allow for &a[i].x for
>> example,
>> even if a[i] is a one-element structure. I think the canonical way of
>> handling
>> ADDR_EXPR is to use sth like
>>
>> base = get_inner_reference (TREE_OPERAND (rhs1, 0), ..., &offset, ...);
>> base = build1 (ADDR_EXPR, TREE_TYPE (rhs1), base);
>> 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);
>>
>> where you probably need to handle scev_not_known when analyzing offset
>> (which might be NULL). You also need to add bitpos to the base address
>> (in bytes, of course). Note that the &MEM_REF case would naturally
>> work
>> with this as well.
>
> OK. New patch is like below, and bootstrapped on x86-32.
You want instead of
+ if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == ARRAY_REF
+ || TREE_CODE (TREE_OPERAND (rhs1, 0)) == MEM_REF
+ || TREE_CODE (TREE_OPERAND (rhs1, 0)) == COMPONENT_REF)
+ {
if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == MEM_REF
|| handled_component_p (TREE_OPERAND (rhs1, 0)))
{
+ base = build1 (ADDR_EXPR, TREE_TYPE (rhs1), base);
+ chrec1 = analyze_scalar_evolution (loop, base);
can you please add a wrapper
tree
analyze_scalar_evolution_for_address_of (struct loop *loop, tree var)
{
return analyze_scalar_evolution (loop, build_fold_addr_expr (var));
}
and call that instead of building the ADDR_EXPR there? We want
to avoid building that tree node, but even such a simple wrapper would
be prefered.
+ if (bitpos)
if (bitpos != 0)
+ chrec3 = build_int_cst (integer_type_node,
+ bitpos / BITS_PER_UNIT);
please use size_int (bitpos / BITS_PER_UNIT) instead. Using
integer_type_node is definitely wrong.
Ok with that changes.
Thanks,
Richard.
> ChangeLog:
>
> 2012-01-20 Jiangning Liu <jiangning.liu@arm.com>
>
> * tree-scalar-evolution (interpret_rhs_expr): generate chrec for
> array reference and component reference.
>
>
> ChangeLog for testsuite:
>
> 2012-01-20 Jiangning Liu <jiangning.liu@arm.com>
>
> * gcc.dg/tree-ssa/scev-3.c: New.
> * gcc.dg/tree-ssa/scev-4.c: New.
>
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/scev-3.c
> b/gcc/testsuite/gcc.dg/tree-ssa/scev-3.c
> new file mode 100644
> index 0000000..28d5c93
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-3.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/testsuite/gcc.dg/tree-ssa/scev-4.c
> b/gcc/testsuite/gcc.dg/tree-ssa/scev-4.c
> new file mode 100644
> index 0000000..6c1e530
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-4.c
> @@ -0,0 +1,23 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +typedef struct {
> + int x;
> + int y;
> +} S;
> +
> +int *a_p;
> +S a[1000];
> +
> +f(int k)
> +{
> + int i;
> +
> + for (i=k; i<1000; i+=k) {
> + a_p = &a[i].y;
> + *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..4e06b75
> --- a/gcc/tree-scalar-evolution.c
> +++ b/gcc/tree-scalar-evolution.c
> @@ -1712,16 +1712,61 @@ interpret_rhs_expr (struct loop *loop, gimple
> at_stmt,
> switch (code)
> {
> case ADDR_EXPR:
> - /* Handle &MEM[ptr + CST] which is equivalent to POINTER_PLUS_EXPR.
> */
> - if (TREE_CODE (TREE_OPERAND (rhs1, 0)) != MEM_REF)
> - {
> - res = chrec_dont_know;
> - break;
> - }
> + if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == ARRAY_REF
> + || TREE_CODE (TREE_OPERAND (rhs1, 0)) == MEM_REF
> + || TREE_CODE (TREE_OPERAND (rhs1, 0)) == COMPONENT_REF)
> + {
> + enum machine_mode mode;
> + HOST_WIDE_INT bitsize, bitpos;
> + int unsignedp;
> + int volatilep = 0;
> + tree base, offset;
> + tree chrec3;
> +
> + base = get_inner_reference (TREE_OPERAND (rhs1, 0),
> + &bitsize, &bitpos, &offset,
> + &mode, &unsignedp, &volatilep, false);
> +
> + if (TREE_CODE (base) == MEM_REF)
> + {
> + rhs2 = TREE_OPERAND (base, 1);
> + rhs1 = TREE_OPERAND (base, 0);
> +
> + chrec1 = analyze_scalar_evolution (loop, rhs1);
> + chrec2 = analyze_scalar_evolution (loop, rhs2);
> + chrec1 = chrec_convert (type, chrec1, at_stmt);
> + chrec2 = chrec_convert (TREE_TYPE (rhs2), chrec2, at_stmt);
> + res = chrec_fold_plus (type, chrec1, chrec2);
> + }
> + else
> + {
> + base = build1 (ADDR_EXPR, TREE_TYPE (rhs1), base);
> + chrec1 = analyze_scalar_evolution (loop, base);
> + chrec1 = chrec_convert (type, chrec1, at_stmt);
> + res = chrec1;
> + }
>
> - rhs2 = TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1);
> - rhs1 = TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0);
> - /* Fall through. */
> + if (offset != NULL_TREE)
> + {
> + chrec2 = analyze_scalar_evolution (loop, offset);
> + chrec2 = chrec_convert (TREE_TYPE (offset), chrec2, at_stmt);
> + res = chrec_fold_plus (type, res, chrec2);
> + }
> +
> + if (bitpos)
> + {
> + gcc_assert ((bitpos % BITS_PER_UNIT) == 0);
> +
> + chrec3 = build_int_cst (integer_type_node,
> + bitpos / BITS_PER_UNIT);
> + chrec3 = analyze_scalar_evolution (loop, chrec3);
> + chrec3 = chrec_convert (integer_type_node, chrec3, at_stmt);
> + res = chrec_fold_plus (type, res, chrec3);
> + }
> + }
> + else
> + res = chrec_dont_know;
> + break;
>
> case POINTER_PLUS_EXPR:
> chrec1 = analyze_scalar_evolution (loop, rhs1);
>
> Thanks,
> -Jiangning
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: [PATCH] Improve SCEV for array element
2012-03-06 13:11 ` Richard Guenther
@ 2012-03-08 7:13 ` Jiangning Liu
[not found] ` <4f585bf3.1eecd80a.3185.ffffe392SMTPIN_ADDED@mx.google.com>
` (2 subsequent siblings)
3 siblings, 0 replies; 10+ messages in thread
From: Jiangning Liu @ 2012-03-08 7:13 UTC (permalink / raw)
To: 'Richard Guenther'; +Cc: gcc-patches
> -----Original Message-----
> From: Richard Guenther [mailto:richard.guenther@gmail.com]
> Sent: Tuesday, March 06, 2012 9:12 PM
> To: Jiangning Liu
> Cc: gcc-patches@gcc.gnu.org
> Subject: Re: [PATCH] Improve SCEV for array element
>
> On Fri, Jan 20, 2012 at 10:06 AM, Jiangning Liu <jiangning.liu@arm.com>
> wrote:
> >> It's definitely not ok at this stage but at most for next stage1.
> >
> > OK. I may wait until next stage1.
> >
> >> This is a very narrow pattern-match. It doesn't allow for &a[i].x
> for
> >> example,
> >> even if a[i] is a one-element structure. I think the canonical way
> of
> >> handling
> >> ADDR_EXPR is to use sth like
> >>
> >> base = get_inner_reference (TREE_OPERAND (rhs1, 0), ...,
> &offset, ...);
> >> base = build1 (ADDR_EXPR, TREE_TYPE (rhs1), base);
> >> 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);
> >>
> >> where you probably need to handle scev_not_known when analyzing
> offset
> >> (which might be NULL). You also need to add bitpos to the base
> address
> >> (in bytes, of course). Note that the &MEM_REF case would naturally
> >> work
> >> with this as well.
> >
> > OK. New patch is like below, and bootstrapped on x86-32.
>
> You want instead of
>
> + if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == ARRAY_REF
> + || TREE_CODE (TREE_OPERAND (rhs1, 0)) == MEM_REF
> + || TREE_CODE (TREE_OPERAND (rhs1, 0)) == COMPONENT_REF)
> + {
>
> if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == MEM_REF
> || handled_component_p (TREE_OPERAND (rhs1, 0)))
> {
>
> + base = build1 (ADDR_EXPR, TREE_TYPE (rhs1), base);
> + chrec1 = analyze_scalar_evolution (loop, base);
>
> can you please add a wrapper
>
> tree
> analyze_scalar_evolution_for_address_of (struct loop *loop, tree var)
> {
> return analyze_scalar_evolution (loop, build_fold_addr_expr (var));
> }
>
> and call that instead of building the ADDR_EXPR there? We want
> to avoid building that tree node, but even such a simple wrapper would
> be prefered.
>
> + if (bitpos)
>
> if (bitpos != 0)
>
> + chrec3 = build_int_cst (integer_type_node,
> + bitpos / BITS_PER_UNIT);
>
> please use size_int (bitpos / BITS_PER_UNIT) instead. Using
> integer_type_node is definitely wrong.
>
> Ok with that changes.
>
Richard,
Modified as all you suggested, and new code is like below. Bootstrapped on
x86-32. OK for trunk now?
Thanks,
-Jiangning
ChangeLog:
2012-03-08 Jiangning Liu <jiangning.liu@arm.com>
* tree-scalar-evolution (interpret_rhs_expr): generate chrec for
array reference and component reference.
(analyze_scalar_evolution_for_address_of): New.
ChangeLog for testsuite:
2012-03-08 Jiangning Liu <jiangning.liu@arm.com>
* gcc.dg/tree-ssa/scev-3.c: New.
* gcc.dg/tree-ssa/scev-4.c: New.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/scev-3.c
b/gcc/testsuite/gcc.dg/tree-ssa/scev-3.c
new file mode 100644
index 0000000..28d5c93
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-3.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/testsuite/gcc.dg/tree-ssa/scev-4.c
b/gcc/testsuite/gcc.dg/tree-ssa/scev-4.c
new file mode 100644
index 0000000..6c1e530
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-4.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+typedef struct {
+ int x;
+ int y;
+} S;
+
+int *a_p;
+S a[1000];
+
+f(int k)
+{
+ int i;
+
+ for (i=k; i<1000; i+=k) {
+ a_p = &a[i].y;
+ *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..c719984
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -266,6 +266,8 @@ along with GCC; see the file COPYING3. If not see
#include "params.h"
static tree analyze_scalar_evolution_1 (struct loop *, tree, tree);
+static tree analyze_scalar_evolution_for_address_of (struct loop *loop,
+ tree var);
/* The cached information about an SSA name VAR, claiming that below
basic block INSTANTIATED_BELOW, the value of VAR can be expressed
@@ -1712,16 +1714,59 @@ interpret_rhs_expr (struct loop *loop, gimple
at_stmt,
switch (code)
{
case ADDR_EXPR:
- /* Handle &MEM[ptr + CST] which is equivalent to POINTER_PLUS_EXPR.
*/
- if (TREE_CODE (TREE_OPERAND (rhs1, 0)) != MEM_REF)
- {
- res = chrec_dont_know;
- break;
- }
+ if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == MEM_REF
+ || handled_component_p (TREE_OPERAND (rhs1, 0)))
+ {
+ enum machine_mode mode;
+ HOST_WIDE_INT bitsize, bitpos;
+ int unsignedp;
+ int volatilep = 0;
+ tree base, offset;
+ tree chrec3;
+ tree unitpos;
+
+ base = get_inner_reference (TREE_OPERAND (rhs1, 0),
+ &bitsize, &bitpos, &offset,
+ &mode, &unsignedp, &volatilep, false);
+
+ if (TREE_CODE (base) == MEM_REF)
+ {
+ rhs2 = TREE_OPERAND (base, 1);
+ rhs1 = TREE_OPERAND (base, 0);
+
+ chrec1 = analyze_scalar_evolution (loop, rhs1);
+ chrec2 = analyze_scalar_evolution (loop, rhs2);
+ chrec1 = chrec_convert (type, chrec1, at_stmt);
+ chrec2 = chrec_convert (TREE_TYPE (rhs2), chrec2, at_stmt);
+ res = chrec_fold_plus (type, chrec1, chrec2);
+ }
+ else
+ {
+ chrec1 = analyze_scalar_evolution_for_address_of (loop, base);
+ chrec1 = chrec_convert (type, chrec1, at_stmt);
+ res = chrec1;
+ }
+
+ if (offset != NULL_TREE)
+ {
+ chrec2 = analyze_scalar_evolution (loop, offset);
+ chrec2 = chrec_convert (TREE_TYPE (offset), chrec2, at_stmt);
+ res = chrec_fold_plus (type, res, chrec2);
+ }
+
+ if (bitpos != 0)
+ {
+ gcc_assert ((bitpos % BITS_PER_UNIT) == 0);
- rhs2 = TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1);
- rhs1 = TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0);
- /* Fall through. */
+ unitpos = size_int_kind (bitpos / BITS_PER_UNIT, SIZETYPE);
+ chrec3 = analyze_scalar_evolution (loop, unitpos);
+ chrec3 = chrec_convert (TREE_TYPE (unitpos), chrec3, at_stmt);
+ res = chrec_fold_plus (type, res, chrec3);
+ }
+ }
+ else
+ res = chrec_dont_know;
+ break;
case POINTER_PLUS_EXPR:
chrec1 = analyze_scalar_evolution (loop, rhs1);
@@ -1961,6 +2006,14 @@ analyze_scalar_evolution (struct loop *loop, tree
var)
return res;
}
+/* Analyzes and returns the scalar evolution of VAR address in LOOP. */
+
+static tree
+analyze_scalar_evolution_for_address_of (struct loop *loop, tree var)
+{
+ return analyze_scalar_evolution (loop, build_fold_addr_expr (var));
+}
+
/* Analyze scalar evolution of use of VERSION in USE_LOOP with respect to
WRTO_LOOP (which should be a superloop of USE_LOOP)
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] Improve SCEV for array element
[not found] ` <4f585bf3.1eecd80a.3185.ffffe392SMTPIN_ADDED@mx.google.com>
@ 2012-03-12 10:42 ` Richard Guenther
0 siblings, 0 replies; 10+ messages in thread
From: Richard Guenther @ 2012-03-12 10:42 UTC (permalink / raw)
To: Jiangning Liu; +Cc: gcc-patches
On Thu, Mar 8, 2012 at 8:13 AM, Jiangning Liu <jiangning.liu@arm.com> wrote:
>
>
>> -----Original Message-----
>> From: Richard Guenther [mailto:richard.guenther@gmail.com]
>> Sent: Tuesday, March 06, 2012 9:12 PM
>> To: Jiangning Liu
>> Cc: gcc-patches@gcc.gnu.org
>> Subject: Re: [PATCH] Improve SCEV for array element
>>
>> On Fri, Jan 20, 2012 at 10:06 AM, Jiangning Liu <jiangning.liu@arm.com>
>> wrote:
>> >> It's definitely not ok at this stage but at most for next stage1.
>> >
>> > OK. I may wait until next stage1.
>> >
>> >> This is a very narrow pattern-match. It doesn't allow for &a[i].x
>> for
>> >> example,
>> >> even if a[i] is a one-element structure. I think the canonical way
>> of
>> >> handling
>> >> ADDR_EXPR is to use sth like
>> >>
>> >> base = get_inner_reference (TREE_OPERAND (rhs1, 0), ...,
>> &offset, ...);
>> >> base = build1 (ADDR_EXPR, TREE_TYPE (rhs1), base);
>> >> 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);
>> >>
>> >> where you probably need to handle scev_not_known when analyzing
>> offset
>> >> (which might be NULL). You also need to add bitpos to the base
>> address
>> >> (in bytes, of course). Note that the &MEM_REF case would naturally
>> >> work
>> >> with this as well.
>> >
>> > OK. New patch is like below, and bootstrapped on x86-32.
>>
>> You want instead of
>>
>> + if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == ARRAY_REF
>> + || TREE_CODE (TREE_OPERAND (rhs1, 0)) == MEM_REF
>> + || TREE_CODE (TREE_OPERAND (rhs1, 0)) == COMPONENT_REF)
>> + {
>>
>> if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == MEM_REF
>> || handled_component_p (TREE_OPERAND (rhs1, 0)))
>> {
>>
>> + base = build1 (ADDR_EXPR, TREE_TYPE (rhs1), base);
>> + chrec1 = analyze_scalar_evolution (loop, base);
>>
>> can you please add a wrapper
>>
>> tree
>> analyze_scalar_evolution_for_address_of (struct loop *loop, tree var)
>> {
>> return analyze_scalar_evolution (loop, build_fold_addr_expr (var));
>> }
>>
>> and call that instead of building the ADDR_EXPR there? We want
>> to avoid building that tree node, but even such a simple wrapper would
>> be prefered.
>>
>> + if (bitpos)
>>
>> if (bitpos != 0)
>>
>> + chrec3 = build_int_cst (integer_type_node,
>> + bitpos / BITS_PER_UNIT);
>>
>> please use size_int (bitpos / BITS_PER_UNIT) instead. Using
>> integer_type_node is definitely wrong.
>>
>> Ok with that changes.
>>
>
> Richard,
>
> Modified as all you suggested, and new code is like below. Bootstrapped on
> x86-32. OK for trunk now?
Ok.
Thanks,
Richard.
> Thanks,
> -Jiangning
>
> ChangeLog:
>
> 2012-03-08 Jiangning Liu <jiangning.liu@arm.com>
>
> * tree-scalar-evolution (interpret_rhs_expr): generate chrec for
> array reference and component reference.
> (analyze_scalar_evolution_for_address_of): New.
>
> ChangeLog for testsuite:
>
> 2012-03-08 Jiangning Liu <jiangning.liu@arm.com>
>
> * gcc.dg/tree-ssa/scev-3.c: New.
> * gcc.dg/tree-ssa/scev-4.c: New.
>
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/scev-3.c
> b/gcc/testsuite/gcc.dg/tree-ssa/scev-3.c
> new file mode 100644
> index 0000000..28d5c93
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-3.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/testsuite/gcc.dg/tree-ssa/scev-4.c
> b/gcc/testsuite/gcc.dg/tree-ssa/scev-4.c
> new file mode 100644
> index 0000000..6c1e530
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-4.c
> @@ -0,0 +1,23 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +typedef struct {
> + int x;
> + int y;
> +} S;
> +
> +int *a_p;
> +S a[1000];
> +
> +f(int k)
> +{
> + int i;
> +
> + for (i=k; i<1000; i+=k) {
> + a_p = &a[i].y;
> + *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..c719984
> --- a/gcc/tree-scalar-evolution.c
> +++ b/gcc/tree-scalar-evolution.c
> @@ -266,6 +266,8 @@ along with GCC; see the file COPYING3. If not see
> #include "params.h"
>
> static tree analyze_scalar_evolution_1 (struct loop *, tree, tree);
> +static tree analyze_scalar_evolution_for_address_of (struct loop *loop,
> + tree var);
>
> /* The cached information about an SSA name VAR, claiming that below
> basic block INSTANTIATED_BELOW, the value of VAR can be expressed
> @@ -1712,16 +1714,59 @@ interpret_rhs_expr (struct loop *loop, gimple
> at_stmt,
> switch (code)
> {
> case ADDR_EXPR:
> - /* Handle &MEM[ptr + CST] which is equivalent to POINTER_PLUS_EXPR.
> */
> - if (TREE_CODE (TREE_OPERAND (rhs1, 0)) != MEM_REF)
> - {
> - res = chrec_dont_know;
> - break;
> - }
> + if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == MEM_REF
> + || handled_component_p (TREE_OPERAND (rhs1, 0)))
> + {
> + enum machine_mode mode;
> + HOST_WIDE_INT bitsize, bitpos;
> + int unsignedp;
> + int volatilep = 0;
> + tree base, offset;
> + tree chrec3;
> + tree unitpos;
> +
> + base = get_inner_reference (TREE_OPERAND (rhs1, 0),
> + &bitsize, &bitpos, &offset,
> + &mode, &unsignedp, &volatilep, false);
> +
> + if (TREE_CODE (base) == MEM_REF)
> + {
> + rhs2 = TREE_OPERAND (base, 1);
> + rhs1 = TREE_OPERAND (base, 0);
> +
> + chrec1 = analyze_scalar_evolution (loop, rhs1);
> + chrec2 = analyze_scalar_evolution (loop, rhs2);
> + chrec1 = chrec_convert (type, chrec1, at_stmt);
> + chrec2 = chrec_convert (TREE_TYPE (rhs2), chrec2, at_stmt);
> + res = chrec_fold_plus (type, chrec1, chrec2);
> + }
> + else
> + {
> + chrec1 = analyze_scalar_evolution_for_address_of (loop, base);
> + chrec1 = chrec_convert (type, chrec1, at_stmt);
> + res = chrec1;
> + }
> +
> + if (offset != NULL_TREE)
> + {
> + chrec2 = analyze_scalar_evolution (loop, offset);
> + chrec2 = chrec_convert (TREE_TYPE (offset), chrec2, at_stmt);
> + res = chrec_fold_plus (type, res, chrec2);
> + }
> +
> + if (bitpos != 0)
> + {
> + gcc_assert ((bitpos % BITS_PER_UNIT) == 0);
>
> - rhs2 = TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1);
> - rhs1 = TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0);
> - /* Fall through. */
> + unitpos = size_int_kind (bitpos / BITS_PER_UNIT, SIZETYPE);
> + chrec3 = analyze_scalar_evolution (loop, unitpos);
> + chrec3 = chrec_convert (TREE_TYPE (unitpos), chrec3, at_stmt);
> + res = chrec_fold_plus (type, res, chrec3);
> + }
> + }
> + else
> + res = chrec_dont_know;
> + break;
>
> case POINTER_PLUS_EXPR:
> chrec1 = analyze_scalar_evolution (loop, rhs1);
> @@ -1961,6 +2006,14 @@ analyze_scalar_evolution (struct loop *loop, tree
> var)
> return res;
> }
>
> +/* Analyzes and returns the scalar evolution of VAR address in LOOP. */
> +
> +static tree
> +analyze_scalar_evolution_for_address_of (struct loop *loop, tree var)
> +{
> + return analyze_scalar_evolution (loop, build_fold_addr_expr (var));
> +}
> +
> /* Analyze scalar evolution of use of VERSION in USE_LOOP with respect to
> WRTO_LOOP (which should be a superloop of USE_LOOP)
>
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH][Testsuite] XFAIL scev-3/4.c and add scev-5.c
2012-03-06 13:11 ` Richard Guenther
2012-03-08 7:13 ` Jiangning Liu
[not found] ` <4f585bf3.1eecd80a.3185.ffffe392SMTPIN_ADDED@mx.google.com>
@ 2012-03-22 2:19 ` Jiangning Liu
[not found] ` <4f6a8c26.45abb60a.1dd0.01b7SMTPIN_ADDED@mx.google.com>
3 siblings, 0 replies; 10+ messages in thread
From: Jiangning Liu @ 2012-03-22 2:19 UTC (permalink / raw)
To: gcc-patches
Hi,
This patch is to XFAIL scev-3.c and scev-5.c.
The bug is going to be fixed after Richard Guenther fix a serials of
problems related to POINTER_PLUS_EXPR and sizetype precision.
Thanks,
-Jiangning
ChangeLog for testsuite:
2012-03-21 Jiangning Liu <jiangning.liu@arm.com>
PR tree-optimization/52563
* gcc.dg/tree-ssa/scev-3.c: XFAIL on lp64.
* gcc.dg/tree-ssa/scev-4.c: XFAIL on lp64.
* gcc.dg/tree-ssa/scev-5.c: New.
Thanks,
-Jiangning
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/scev-3.c
b/gcc/testsuite/gcc.dg/tree-ssa/scev-3.c
index 28d5c93..ed63a18 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/scev-3.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-3.c
@@ -14,5 +14,5 @@ f(int k)
}
}
-/* { dg-final { scan-tree-dump-times "&a" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "&a" 1 "optimized" { xfail lp64 }
+} } */
/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git
a/gcc/testsuite/gcc.dg/tree-ssa/scev-4.c
b/gcc/testsuite/gcc.dg/tree-ssa/scev-4.c
index 6c1e530..a538c32 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/scev-4.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-4.c
@@ -19,5 +19,5 @@ f(int k)
}
}
-/* { dg-final { scan-tree-dump-times "&a" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "&a" 1 "optimized" { xfail lp64 }
+} } */
/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git
a/gcc/testsuite/gcc.dg/tree-ssa/scev-5.c
b/gcc/testsuite/gcc.dg/tree-ssa/scev-5.c
new file mode 100644
index 0000000..b9de36a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-5.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int *a_p;
+int a[1000];
+
+f(int k)
+{
+ long long 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" } } */
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH][Testsuite] XFAIL scev-3/4.c and add scev-5.c
[not found] ` <4f6a8c26.45abb60a.1dd0.01b7SMTPIN_ADDED@mx.google.com>
@ 2012-03-22 7:16 ` Richard Guenther
0 siblings, 0 replies; 10+ messages in thread
From: Richard Guenther @ 2012-03-22 7:16 UTC (permalink / raw)
To: Jiangning Liu; +Cc: gcc-patches
On Thu, Mar 22, 2012 at 3:19 AM, Jiangning Liu <jiangning.liu@arm.com> wrote:
> Hi,
>
> This patch is to XFAIL scev-3.c and scev-5.c.
>
> The bug is going to be fixed after Richard Guenther fix a serials of
> problems related to POINTER_PLUS_EXPR and sizetype precision.
Ok.
Thanks,
Richard.
> Thanks,
> -Jiangning
>
> ChangeLog for testsuite:
>
> 2012-03-21 Jiangning Liu <jiangning.liu@arm.com>
>
> PR tree-optimization/52563
> * gcc.dg/tree-ssa/scev-3.c: XFAIL on lp64.
> * gcc.dg/tree-ssa/scev-4.c: XFAIL on lp64.
> * gcc.dg/tree-ssa/scev-5.c: New.
>
> Thanks,
> -Jiangning
>
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/scev-3.c
> b/gcc/testsuite/gcc.dg/tree-ssa/scev-3.c
> index 28d5c93..ed63a18 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/scev-3.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-3.c
> @@ -14,5 +14,5 @@ f(int k)
> }
> }
>
> -/* { dg-final { scan-tree-dump-times "&a" 1 "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "&a" 1 "optimized" { xfail lp64 }
> +} } */
> /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git
> a/gcc/testsuite/gcc.dg/tree-ssa/scev-4.c
> b/gcc/testsuite/gcc.dg/tree-ssa/scev-4.c
> index 6c1e530..a538c32 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/scev-4.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-4.c
> @@ -19,5 +19,5 @@ f(int k)
> }
> }
>
> -/* { dg-final { scan-tree-dump-times "&a" 1 "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "&a" 1 "optimized" { xfail lp64 }
> +} } */
> /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git
> a/gcc/testsuite/gcc.dg/tree-ssa/scev-5.c
> b/gcc/testsuite/gcc.dg/tree-ssa/scev-5.c
> new file mode 100644
> index 0000000..b9de36a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-5.c
> @@ -0,0 +1,18 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +int *a_p;
> +int a[1000];
> +
> +f(int k)
> +{
> + long long 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" } } */
>
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH] Improve SCEV for array element
@ 2012-01-18 7:41 Jiangning Liu
0 siblings, 0 replies; 10+ messages in thread
From: Jiangning Liu @ 2012-01-18 7:41 UTC (permalink / raw)
To: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 2967 bytes --]
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
[-- Attachment #2: scev.patch --]
[-- Type: application/octet-stream, Size: 2175 bytes --]
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)
{
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2012-03-22 7:16 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <4f1677c5.0630440a.1021.ffffb00eSMTPIN_ADDED@mx.google.com>
2012-01-18 10:33 ` [PATCH] Improve SCEV for array element Richard Guenther
2012-01-20 9:07 ` Jiangning Liu
2012-02-13 10:15 ` Jiangning Liu
[not found] ` <4f38de06.0630440a.4838.5731SMTPIN_ADDED@mx.google.com>
2012-02-13 11:30 ` Richard Guenther
[not found] ` <4f192ee1.c84b440a.3d24.ffffae31SMTPIN_ADDED@mx.google.com>
2012-03-06 13:11 ` Richard Guenther
2012-03-08 7:13 ` Jiangning Liu
[not found] ` <4f585bf3.1eecd80a.3185.ffffe392SMTPIN_ADDED@mx.google.com>
2012-03-12 10:42 ` Richard Guenther
2012-03-22 2:19 ` [PATCH][Testsuite] XFAIL scev-3/4.c and add scev-5.c Jiangning Liu
[not found] ` <4f6a8c26.45abb60a.1dd0.01b7SMTPIN_ADDED@mx.google.com>
2012-03-22 7:16 ` Richard Guenther
2012-01-18 7:41 [PATCH] Improve SCEV for array element Jiangning Liu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).