avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] Strange Code generated when using Global Register Var


From: Georg-Johann Lay
Subject: Re: [avr-gcc-list] Strange Code generated when using Global Register Variables
Date: Sat, 30 Apr 2011 16:25:09 +0200
User-agent: Mozilla Thunderbird 1.0.7 (Windows/20050923)

Christian Steer schrieb:
Hi,

this is only a small example to demonstrate the compiled result. I do
not expect good or small code from -O0, but for me it explains what
the compiler is thinking: r24 is a storage location like ram, not
able to perform calculations.

If you like to understand what the compiler is doing, you may want to specify the -fdump-tree-all -da -dP -save-temps -fverbose-asm
options and inspect gcc intermediate language and assembler dumps.

By making a register fixed you take it /away/ from the register allocator. If you had a pointer p in a global reg r25:r25 you would expect code like *p to work.

It's the same here: The compiler generates /abstract/ representation of code and allocates the pseudos in the subtraction so some freely available registers that match the insn's constraints. Hardly any optimization is possible after register allocation; you might be lucky to see whatever you expect -- whatever that is -- but more probably you will see some other code.

But also the most optimised case (-O3) is far from what I expected. Why the calculation cannot be performed directly on the register?

This is a question more appropriate for the address@hidden mailing list. There is nothing special about global registers in the avr part of GCC except that global register variables will never be saved/restored in function prologue/epilogue.

It is not important which register is used, the output does not match
my expectation. When using register variables my expectation is
that calculations are done directly on the register, or the register
is used directly as operand source or target.

Some notes:
- I will not use the Lib so I dont care about ABI.

The ABI not just covers library calls. The ABI covers /any/ function call (and other things besides that). So note that your r24 might be clobbered. You may want to study PR45099 where an implicit function call silently clobbers a global register. If you want a warning/error, you will have to extend gcc/config/avr/avr.c:avr_function_arg_advance().

- First I used register r2, the compiler copied it to r24. Ok, some operations can not be done on the lower register, so to help the compiler I switched to the
  prefered register r24, but now he is using r25. So it does not matter
  which register is used, no chance for better results.
  But you are right for the example r16 would be a better choice.
- If the keyword volatile is not used, the result is even more strange:
  (or consistent with the assumption: r24 is equal to a ram location)

       ldir25,lo8(100);  tmp43,
        sts tmp,r25       ;  tmp, tmp43
.L2:
        .stabn   68,0,14,.LM2-.LFBB1
.LM2:
        sts tmp,r25       ;  tmp, ivtmp.16
        subir25,lo8(-(-1));  ivtmp.16,
        .stabn   68,0,15,.LM3-.LFBB1
.LM3:
        brne.L2          ; ,
        ldir24,lo8(0);  state,

Instead of using the suggested register r24, the compiler uses r25, and
will do an additonal load with zero to leave r24 with the correct value.
Why not use r24 directly ????

To answer this question you will have to dig into GCC. There are three ways that might give you some insight:

- Read the dumps generated as outlined above. Increasing numbers stand
  for increasing pass number (~150 passes).
- Read the sources
- Debug the compiler and look what it is doing.

A compiler is not a high-level assembler. It's a program to translate standardised source code into some object format. GCC development does not focus on optimizing global register variables (which is not covered by, say, C99) and it's not very likely anyone will do the digging for you.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]