On Fri, Jun 25, 2010 at 8:34 AM, Eric Botcazou <ebotca...@adacore.com> wrote:
>> Minus whitespace changes it seems to be
>>
>> !           if (lhs_free && (is_gimple_reg (rhs) ||
>> is_gimple_min_invariant (rhs)))
>>               rhs_free = true;
>>
>> vs.
>>
>> !           if (lhs_free
>> !               && (is_gimple_reg (rhs)
>> !                   || !is_gimple_reg_type (TREE_TYPE (rhs))
>> !                   || is_gimple_min_invariant (rhs)))
>>               rhs_free = true;
>>
>> so the stmt is likely being eliminated if either the LHS or the RHS is
>> based on a parameter and the other side is a register or an invariant.  You
>> change that to also discount aggregate stores/loads to/from parameters to
>> be free.
>
> There is also the counterpart for the RHS:
>
> !           if (rhs_free && is_gimple_reg (lhs))
>              lhs_free = true;
> vs
>
> !           if (rhs_free
> !               && (is_gimple_reg (lhs)
> !                   || !is_gimple_reg_type (TREE_TYPE (lhs))))
>              lhs_free = true;

Sure, but it's requivalent.

>> Which you could have simplified to just say
>>
>>   if (lhs_free || rhs_free)
>>     return true;
>>
>> and drop the code you are changing.
>
> I don't think so, compare your version and mine for scalar stores/loads
> from/to parameters or return values.

I do think so.  Quoting the complete patched code:

            if (TREE_CODE (inner_rhs) == PARM_DECL
                || (TREE_CODE (inner_rhs) == SSA_NAME
                    && SSA_NAME_IS_DEFAULT_DEF (inner_rhs)
                    && TREE_CODE (SSA_NAME_VAR (inner_rhs)) == PARM_DECL))
              rhs_free = true;
!           if (rhs_free
!               && (is_gimple_reg (lhs)
!                   || !is_gimple_reg_type (TREE_TYPE (lhs))))
              lhs_free = true;
            if (((TREE_CODE (inner_lhs) == PARM_DECL
                  || (TREE_CODE (inner_lhs) == SSA_NAME
                      && SSA_NAME_IS_DEFAULT_DEF (inner_lhs)
                      && TREE_CODE (SSA_NAME_VAR (inner_lhs)) == PARM_DECL))
                 && inner_lhs != lhs)
                || TREE_CODE (inner_lhs) == RESULT_DECL
                || (TREE_CODE (inner_lhs) == SSA_NAME
                    && TREE_CODE (SSA_NAME_VAR (inner_lhs)) == RESULT_DECL))
              lhs_free = true;
!           if (lhs_free
!               && (is_gimple_reg (rhs)
!                   || !is_gimple_reg_type (TREE_TYPE (rhs))
!                   || is_gimple_min_invariant (rhs)))
              rhs_free = true;
            if (lhs_free && rhs_free)
              return true;

now, with is_gimple_reg () || !is_gimple_reg_type () ||
is_gimple_min_invariant () you allow registers, constants or
any aggregates but _not_ register typed variables that have
their address taken.

Which in the following example makes i = *p not likely eliminated
but makes j = *q likely eliminated.

void foo (int *p, struct X *q)
{
  int i;
  struct X j;
  i = *p;
  j = *q;
  bar (&i, &q);
}

That doesn't make sense.

What makes sense is that all scalar (thus gimple_reg_typed)
loads/stores to/from parameters or the result are free.  Which
isn't what the current code does but is also not what you
are changing it to.

Thus in the above example i = *p should be likely eliminated
but not j = *q (maybe we can make aggregate loads/stores
from/to non-address-taken vars as free, too).

Richard.

> --
> Eric Botcazou
>

Reply via email to