limiting call clobbered registers for library functions

Yury Gribov y.gribov@samsung.com
Mon Feb 2 08:55:00 GMT 2015


On 01/30/2015 11:16 AM, Matthew Fortune wrote:
> Yury Gribov <y.gribov@samsung.com> writes:
>> On 01/29/2015 08:32 PM, Richard Henderson wrote:
>>> On 01/29/2015 02:08 AM, Paul Shortis wrote:
>>>> I've ported GCC to a small 16 bit CPU that has single bit shifts. So
>>>> I've handled variable / multi-bit shifts using a mix of inline shifts
>>>> and calls to assembler support functions.
>>>>
>>>> The calls to the asm library functions clobber only one (by const) or
>>>> two
>>>> (variable) registers but of course calling these functions causes all
>>>> of the standard call clobbered registers to be considered clobbered,
>>>> thus wasting lots of candidate registers for use in expressions
>>>> surrounding these shifts and causing unnecessary register saves in
>> the surrounding function prologue/epilogue.
>>>>
>>>> I've scrutinized and cloned the actions of other ports that do the
>>>> same, however I'm unable to convince the various passes that only r1
>>>> and r2 can be clobbered by these library calls.
>>>>
>>>> Is anyone able to point me in the proper direction for a solution to
>>>> this problem ?
>>>
>>> You wind up writing a pattern that contains a call, but isn't
>>> represented in rtl as a call.
>>
>> Could it be useful to provide a pragma for specifying function register
>> usage? This would allow e.g. library writer to write a hand-optimized
>> assembly version and then inform compiler of it's binary interface.
>>
>> Currently a surrogate of this can be achieved by putting inline asm code
>> in static inline functions in public library headers but this has it's
>> own disadvantages (e.g. code bloat).
>
> This sounds like a good idea in principle. I seem to recall seeing something
> similar to this in other compiler frameworks that allow a number of special
> calling conventions to be defined and enable functions to be attributed to use
> one of them. I.e. not quite so general as specifying an arbitrary clobber list
> but some sensible pre-defined alternative conventions.

FYI a colleague from kernel mentioned that they already achieve this by 
wrapping the actual call with inline asm e.g.

static inline int foo(int x) {
   asm(
     ".global foo_core\n"
     // foo_core accepts single parameter in %rax,
     // returns result in %rax and
     // clobbers %rbx
     "call foo_core\n"
     : "+a"(x)
     :
     : "rbx"
   );
   return x;
}

We still can't mark inline asm with things like __attribute__((pure)), 
etc. though so it's not an ideal solution.

-Y



More information about the Gcc mailing list