Thanks for the feedback.

Paolo Bonzini <bonz...@gnu.org> writes:
> On 08/17/2011 07:52 AM, Richard Sandiford wrote:
>>    cost = rtx_cost (SET_SRC (set), SET, speed);
>>    return cost>  0 ? cost : COSTS_N_INSNS (1);
>>
>> This ignores SET_DEST (the problem I'm trying to fix).  It also means
>> that constants that are slightly more expensive than a register --
>> somewhere in the range [0, COSTS_N_INSNS (1)] -- end up seeming
>> cheaper than registers.
>
> This can be fixed by doing
>
>    return cost >= COSTS_N_INSNS (1) ? cost : COSTS_N_INSNS (1);

Is that really a fix though?  Those sorts of constant are supposed to be
more expensive than a normal register move, not the same cost.

To put it another way: for real operations like PLUS, you have full
control.  If something is slightly more expensive than a single move,
but not as expensive as two moves, you can return a cost in the
range [COSTS_N_INSNS (1), COSTS_N_INSNS (2)].  But constants are
generally given relative to the cost of a register, so the corresponding
range would be [0, COSTS_N_INSNS (1)] instead.

>> One approach I'm trying is to make sure that every target that doesn't
>> explicitly handle SET does nothing with it.  (Targets that do handle
>> SET remain unchanged.)  Then, if we see a SET whose SET_SRC is a
>> register, constant, memory or subreg, we give it cost:
>>
>>      COSTS_N_INSNS (1)
>>      + rtx_cost (SET_DEST (x), SET, speed)
>>      + rtx_cost (SET_SRC (x), SET, speed)
>>
>> as now.  In other cases we give it a cost of:
>>
>>      rtx_cost (SET_DEST (x), SET, speed)
>>      + rtx_cost (SET_SRC (x), SET, speed)
>>
>> But that hardly seems clean either.  Perhaps we should instead make
>> the SET_SRC always include the cost of the SET, even for registers,
>> constants and the like.  Thoughts?
>
> Similarly, this becomes
>
>    dest_cost = rtx_cost (SET_DEST (x), SET, speed);
>    src_cost = MAX (rtx_cost (SET_SRC (x), SET, speed),
>                    COSTS_N_INSNS (1));
>    return dest_cost + src_cost;
>
> How does this look?

This has the same problem as above.  There's a second problem though:
what about register stores?  Say a load is as expensive as a store
(often true, when optimising for size).  The formula above would give
the cost of a load as being:

   cost(REG) + MAX(cost(MEM), CNI1) == cost(MEM)

whereas the cost of a store would be:

   cost(MEM) + MAX(cost(REG), CNI1) == cost(MEM) + CNI1

On RISCy machines you could try to compensate by making the cost of a
MEM smaller for lvalues, but that doesn't seem very clean.  It would
also skew the costs of MEM-to-MEM moves on CISCy machines, where the
MAX would have no effect.

Richard

Reply via email to