On 8/12/23 10:44, Jivan Hakobyan wrote:
Yes, as mentioned Jeff I have some work in that scope.
The first is related to address computation when it has a large constant
part.
Suppose we have this code:
int consume (void *);
int foo (void) {
int x[1000];
return consume (x);
}
before IRA we have the following sequence
19: r140:DI=0xfffffffffffff000
20: r136:DI=r140:DI+0x60
REG_EQUAL 0xfffffffffffff060
8: a0:DI=frame:DI+r136:DI
REG_DEAD r136:DI
but during IRA (eliminate_regs_in_insn) insn 8 transforms to
8: a0:DI=r136:DI+0xfa0+frame:DI
REG_DEAD r136:DI
and in the end, we get the wrong sequence.
21: r136:DI=0xfffffffffffff060
REG_EQUIV 0xfffffffffffff060
25: r143:DI=0x1000
26: r142:DI=r143:DI-0x60
REG_DEAD r143:DI
REG_EQUAL 0xfa0
27: r142:DI=r142:DI+r136:DI
REG_DEAD r136:DI
8: a0:DI=r142:DI+frame:DI
REG_DEAD r142:DI
My changes prevent that transformation.
I have tested on spec and did not get regressions.
Besides. executed 40B fewer instructions.
Right. And this looks like a generic failing of the register
elimination code to simplify after eliminating fp/ap to sp. It's a bit
of a surprise as I thought that code had some simplification
capabilities. But clearly if it has that ability it isn't working
well. Part of me wondered if it's falling down due to constants not
fitting in a 12 bit signed immediate. I've got a TODO to look at your
patch in this space. Maybe tonight if I can keep moving things off my
TODO list ;-)
The second work related to hoisting out loop invariant code.
I have a test case where SP + const can be hoisted out.
......
.L3:
call foo
addi a5,sp,16
sh3add a0,a0,a5
.......
Before IRA that code is already out of the loop, but IRA moves back.
My approach was done in update_equiv_regs().
It prevents any move if its uses and defs are held in a single place,
and used in the loop.
Currently, that improvement is under evaluation.
Yea, we're going to need to sit down with this. IRA is working per
design and we may be able to avoid these problems with -fsched-pressure,
but it feels a bit hackish.
Jeff