16

LLVMでトランポリン組み込み関数を使用する方法を理解しようとしています。ドキュメントには、プラットフォームに依存する、トランポリンを格納するために必要なある程度のストレージについて言及されています。私の質問は、必要な量をどのように把握するのですか?

明らかに理由もなく 32 バイトを選択するこの例を見つけました。適切な値をどのように選択しますか?

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
}
4

1 に答える 1

1

はい、トランポリンは「その場で」コードを生成するために使用されます。これらの組み込み関数は GCC のネストされた関数拡張を実装するために使用されるため (特に、ネストされた関数のアドレスがキャプチャされ、関数が囲んでいる関数内のものにアクセスする場合)、なぜこれらの組み込み関数が必要なのかは不明です。

トランポリン バッファの必要なサイズと配置を把握する最善の方法は、"TRAMPOLINE_SIZE" と "TRAMPOLINE_ALIGNMENT" の gcc ソースを grep することです。

私が見る限り、この記事の執筆時点では、72 バイトのバッファーと 16 バイトのアライメントで、gcc / LLVM がサポートするすべてのプラットフォームで十分です。

于 2013-05-17T21:23:54.367 に答える