This is the mail archive of the gcc-help@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: Do not spill variables/registers on the stack


On 04/02/2011 13:19, Drasko DRASKOVIC wrote:
On Fri, Feb 4, 2011 at 12:29 PM, David Brown<david@westcontrol.com>
wrote:
On 03/02/2011 23:36, Drasko DRASKOVIC wrote:

Back to the topic, few things crossed my mind :


1) Register keyword is a "hint" to the compiler, and thus not
obligatory. We saw that for -O1 and above it is "useless hint",
as it is always ignored. Is it however always respected by GCC
when -O0 ? If yes - why is it a hint ? If no, in which cases it
is not respected ? Only when you assign more vars than you have
reg, or GCC might ignore it some other times even with -O0 ?

2) Is this behavior documented anywhere ? Can we find docs that
note : a) that "regiser" keyword is not ignored only with -O0 b)
when -O0 in which cases it is taken into account and in which
cases not.


<http://gcc.gnu.org/onlinedocs/gcc/Hints-implementation.html>



To quote:


4.8 Hints

* The extent to which suggestions made by using the register
storage-class specifier are effective (C90 6.5.1, C99 6.7.1).

The register specifier affects code generation only in these ways:
o When used as part of the register variable extension, see
Explicit Reg Vars. o When -O0 is in use, the compiler allocates
distinct stack memory for all variables that do not have the
register storage-class specifier; if register is specified, the
variable may have a shorter lifespan than the code would indicate
and may never be placed in memory. o On some rare x86 targets,
setjmp doesn't save the registers in all circumstances. In those
cases, GCC doesn't allocate any variables in registers unless they
are marked register.

Hi David, thanks for the llink.


From what I see, for -O0 "register" does not look like a "hint" but
an obligation to the compiler (i.e. by this document it is promised
that variable will finish into the register).


No, it's a hint - but one that gcc will take seriously and do its best to honour (at -O0). The compiler cannot guarantee that it will be able to put the data into a register - there are many things that could keep it out of the register, including register pressure and the way the data is used. The text says that with -O0 gcc will put all non-register variables on the stack - that does /not/ imply that it will put all register variables in registers.


Also, no mention what happens for -O1 and above - there is no
promise that variable will finish into the reg, but also no mention
that it will be ignored. Maybe in this case it is really a hint ?


No, it is ignored for -O1 and above, except in odd combinations of particular x86 targets when using setjmp - as detailed on that page. The page says "The register specifier affects code generation /only/ in these ways..." - if these don't apply, the hint is ignored.



What about global register variables ? Is it the same, ignored for -O1 and above ?


Variables allocated to a specific named register are a different matter entirely - that is a gcc extension that is related to its inline assembler, and is not related to the "register" storage specifier. It's an example of C's bad habit of overloading keywords - albeit a fairly natural one.


I am asking this because I know that for example U-Boot uses
register variable to hold some global information (pointer to global
structure), as you can see at the bottom of this file :
http://git.denx.de/?p=u-boot.git;a=blob;f=arch/arm/include/asm/global_data.h;h=2a84d27a4e15e10a86cc5842eae25e80d21981e1;hb=42d44f631c4e8e5359775bdc098f2fffde4e5c05

 Then the code takes care not to clobber this reg in the .S files,
and in .c files it counts on GCC to to always allocate this reg to
this global variable, and keep it protected from clobbering during C
compilation. And U-Boot is surely compiled with highest possible
optimizations. But not only that it works, it is specified in the
official U-Boot documentation that it should always be done like
this.


That's correct - you can put data into specified dedicated named registers like this, if you are /very/ careful. But it is unrelated to the register storage specifier, and unaffected by any optimisation levels.



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