On 31.05.2017 10:15, Jakub Jelinek wrote:
On Wed, May 31, 2017 at 10:06:34AM +0200, Georg-Johann Lay wrote:
Hi, this causes a performance degradation for avr.
When optimizing for speed, and with a known denominatior, then v6 uses
s/umulMM3_highpart insn to avoid division because no div instruction is
available.
unsigned scale256 (unsigned val)
{
return value / 255;
}
With this patch, v7 now uses __divmodhi4 which is very expensive but
the costs are not computed because rtlanal.c:seq_cost assumes a cost of
ONE:
for (; seq; seq = NEXT_INSN (seq))
{
set = single_set (seq);
if (set)
cost += set_rtx_cost (set, speed);
else
cost++;
}
because divmod in not a single_set:
(gdb) p seq
$10 = (const rtx_insn *) 0x7ffff730d500
(gdb) pr
warning: Expression is not an assignment (and might have no effect)
(insn 14 13 0 (parallel [
(set (reg:HI 52)
(div:HI (reg:HI 47)
(reg:HI 54)))
(set (reg:HI 53)
(mod:HI (reg:HI 47)
(reg:HI 54)))
(clobber (reg:QI 21 r21))
(clobber (reg:HI 22 r22))
(clobber (reg:HI 24 r24))
(clobber (reg:HI 26 r26))
]) "scale.c":7 -1
(nil))
(gdb)
Hence the divmod appears to be much less expensive than the unsigned
variant that computed the costs for mult_highpart.
Then you should fix the cost computation - be able to use a target hook
on insns that are not a single set or something similar.
Jakub
Are you saying that cost computation in GCC is fundamentally flawed
for anything that it not a single_set?
Johann