This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: libgcc: strange optimization


On 02/08/11 13:22, Richard Guenther wrote:
> On Tue, Aug 2, 2011 at 2:06 PM, Mikael Pettersson <mikpe@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.




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]