On 02/08/11 13:22, Richard Guenther wrote: > On Tue, Aug 2, 2011 at 2:06 PM, Mikael Pettersson <mi...@it.uu.se> wrote: >> Michael Walle writes: >> > >> > Hi, >> > >> > > To confirm that try -fno-tree-ter. >> > >> > "lm32-gcc -O1 -fno-tree-ter -S -c test.c" generates the following working >> > assembly code: >> > >> > f2: >> > addi sp, sp, -4 >> > sw (sp+4), ra >> > addi r2, r0, 10 >> > calli __ashrsi3 >> > addi r8, r0, 10 >> > scall >> > lw ra, (sp+4) >> > addi sp, sp, 4 >> > b ra >> >> -fno-tree-ter also unbreaks the ARM test case in PR48863 comment #4. > > It's of course only a workaround, not a real fix as nothing prevents > other optimizers from performing the re-scheduling TER does. > > I suggest to amend the documentation for local call-clobbered register > variables to say that the only valid sequence using them is from a > non-inlinable function that contains only direct initializations of the > register variables from constants or parameters. > > Or go one step further and deprecate local register variables alltogether > (they IMHO don't make much sense, and rather the targets should provide > a way to properly constrain asm inputs and outputs). > > Richard. > >
Better still would be to change the specification and implementation of local register variables to only guarantee them at the beginning of ASM statements. At other times they are simply the same as other local variables. Now we have a problem that the register allocator knows how to solve. In other words, if the user writes bar (int y) { register int x asm ("r0") = y; foo() asm volatile ("mov r1, r0"); } The compiler will generate (set (reg:SI 999 <x>) (reg:SI <y>)) (call "foo") (set (reg:SI 0 "r0") (reg:SI 999 <x>)) (asm "mov r1, r0") (set (reg:SI 999 <x>) (reg:SI 0 "r0")) That is, it inserts appropriate set insns around asm blocks. Of course, the register allocator can try to allocate reg 999 to r0 and if it succeeds, then the sets become dead. But if it fails then at least the code will continue to execute as intended. R.