Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How much space for a LLVM trampoline

Tags:

llvm

I'm trying to figure out how to use the trampoline intrinsics in LLVM. The documentation makes mention of some amount of storage that's needed to store the trampoline in, which is platform dependent. My question is, how do I figure out how much is needed?

I found this example, that picks 32 bytes for apparently no reason. How does one choose a good value?

declare void @llvm.init.trampoline(i8*, i8*, i8*);
declare i8* @llvm.adjust.trampoline(i8*);

define i32 @foo(i32* nest %ptr, i32 %val)
{
    %x = load i32* %ptr
    %sum = add i32 %x, %val
    ret i32 %sum
}

define i32 @main(i32, i8**)
{
    %closure = alloca i32
    store i32 13, i32* %closure
    %closure_ptr = bitcast i32* %closure to i8*

    %tramp_buf = alloca [32 x i8], align 4
    %tramp_ptr = getelementptr [32 x i8]* %tramp_buf, i32 0, i32 0
    call void @llvm.init.trampoline(
            i8* %tramp_ptr,
            i8* bitcast (i32 (i32*, i32)* @foo to i8*),
            i8* %closure_ptr)
    %ptr = call i8* @llvm.adjust.trampoline(i8* %tramp_ptr)
    %fp = bitcast i8* %ptr to i32(i32)*

    %val2 = call i32 %fp (i32 13)

    ; %val = call i32 @foo(i32* %closure, i32 42);

    ret i32 %val2
}
like image 548
brooks94 Avatar asked Mar 19 '13 20:03

brooks94


1 Answers

Yes, trampolines are used to generate some code "on fly". It's unclear why do you need these intrinsics at all, because they are used to implement GCC's nested functions extension (in particular, when the address of the nested function is captured and the function access the stuff inside the enclosing function).

The best way to figure out the necessary size and alignment of trampoline buffer is to grep gcc sources for "TRAMPOLINE_SIZE" and "TRAMPOLINE_ALIGNMENT".

As far as I can see, at the time of this writing, the buffer of 72 bytes and alignment of 16 bytes will be enough for all the platforms gcc / LLVM supports.

like image 96
Anton Korobeynikov Avatar answered Nov 14 '22 21:11

Anton Korobeynikov