[cfe-dev] A new builtin: __builtin_stack_pointer()

Richard Smith richard at metafoo.co.uk
Fri Nov 8 17:37:21 PST 2013


On Fri, Nov 8, 2013 at 1:48 PM, Behan Webster <behanw at converseincode.com>wrote:

>  On 11/08/13 11:34, Richard Smith wrote:
>
> On Thu, Nov 7, 2013 at 6:29 PM, Behan Webster <behanw at converseincode.com>wrote:
>
>> On 11/07/13 01:47, Joerg Sonnenberger wrote:
>> > On Wed, Nov 06, 2013 at 05:46:43PM -0800, Behan Webster wrote:
>> >> Another way would be to introduce a new builtin in parallel to others
>> >> like __builtin_return_address(). Essentially adding a
>> >> __builtin_stack_pointer() which does what the above code does. The idea
>> >> would be to get something like this added to both clang and gcc in
>> order
>> >> to make this work across compilers, and across arches.
>> > You still haven't said what the intended behavior of this builtin is
>> > when the function containing it is inlined.
>>  The intent in all situations is for it to use the current value in the
>> stack pointer register. It doesn't matter whether it is inlined or not.
>> It should be the immediate value of R13 on ARM or esp on X86_64 (etc for
>> other arches).
>>
>> The idea is to preclude the need to use ASM to move the value in the
>> stack pointer to another register in order to use it in C code (which is
>> inefficient).
>>
>> Essentially I'm looking for a better solution than adding a C symbol
>> name to the stack register.
>>
>> Does that make sense?
>
>
>  Not yet. Why do you want this? What will you do with it? What semantics
> do you want the returned pointer to have? How can correct code ever do
> anything with this pointer? (Remember that the backend is in principle
> allowed to modify the stack pointer at any time, including between the
> point where you call this intrinsic and the point where you use its result.)
>
> Its used by the Linux kernel in several situations, but mostly for
> threading, and various debug and stack tracing code.
>
> Essentially the kernel code primarily uses the stack pointer by assigning
> it a C symbol name like this.
>
>     register unsigned long current_sp asm ("sp");
>
> The value of that named register is read and stored elsewhere, or is used
> to calculate the beginning or end of the stack in order to find the current
> threadinfo or the current pt_regs (previous dump of the CPU registers).
> Essentially in the case of ARM, r13 is used directly in the resulting code.
>
> gcc allows you to do the above in order to access the value of the stack
> pointer register (in the way I describe), however clang does not unless you
> then add the following.
>
>     register unsigned long current_sp asm ("sp");
>     asm("" : "=r(current_sp));
>
> ... which works, but is ugly. Since my goal is to be able to compile the
> Linux kernel with both clang and gcc, in a way which is the most efficient
> with each compiler, and which doesn't make the code worse, the above it's
> going to cut it.
>
> Instead I'd like to see __builtin_stack_pointer() added to both clang and
> gcc. It's easier to read, would provide read only access to the register
> value (which is safer), and mirrors the other __builtin functions (which in
> the Linux kernel are often called together: __builtin_frame_address() and
> __builtin_return_address()
>
> For instance:
>
>         frame.fp = (unsigned long)__builtin_frame_address(0);
>         frame.sp = current_sp;
>
        frame.lr = (unsigned long)__builtin_return_address(0);
>         frame.pc = (unsigned long)return_address;
>
> No doubt there is a more optimal way than the patch I sent.
>

I don't think you've answered my main question: what semantics do you want
the returned pointer to have (and how can any correct code ever do anything
with the pointer)? If you just want some approximation of the stack pointer
to use as a key, __builtin_frame_address seems like it would work. Do you
*also* need a guarantee that the stack pointer will not change between the
call to __builtin_stack_address and the end of the function (except in
callees)? Can we reorder a call to alloca() past __builtin_stack_address?
Can we reorder the initialization of a VLA past a call to
__builtin_stack_address? Can the backend choose to perform a stack
adjustment afterwards?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20131108/97630cef/attachment.html>


More information about the cfe-dev mailing list