On Mon, Feb 13, 2012 at 10:54 AM, Jiangning Liu <jiangning....@arm.com> wrote:
>
>
>> -----Original Message-----
>> From: gcc-patches-ow...@gcc.gnu.org [mailto:gcc-patches-
>> ow...@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....@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....@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
>
>
>

Reply via email to