2

私はLLVMの基礎を学んでいます。私はビルダーフレームワークに入ろうとしており、モジュール、関数ヘッダーなどをセットアップしましたが、ビルダーで次のような単純なシーケンスを作成する方法をまだ見つけられていません:

%0 = 41
%1 = add i32 42, %0 

ビルダーフレームワークを介して疑似レジスタ表記を使用するにはどうすればよいですか?

2 つの定数に基づいて plus 命令を作成しようとしました。(整数)加算を生成するために使用しているコアラインは次のとおりです。

    Value *L = (Value *)m_left->Create_LLVM(  );
    Value *R = (Value *)m_right->Create_LLVM();
    if ( L == 0 || R == 0 ) return 0;

    llvm::Value *p_instruction =  Get_Builder().CreateAdd( L, R, "addtmp" );

これには私自身の機能がたくさん含まれていますが、基本は明らかだと思います。どちらも定数である左オペランドと右オペランドの値ポインターを取得し、ビルダー フレームワークで加算操作を作成します。ここでも、モジュールとビルダーは正しくセットアップされています。dump() を呼び出すと、他のすべての処理が表示されますが、上記の行では IR コードが作成されません。

私はそれが次のようなものを共同で作成することを期待しています

%4 = add i32 %3, %2 

または似たようなもの。ビルダーを使用して操作を構築する方法について、何か基本的なことを誤解していますか?それとも、細部の小さな見落としですか?

ありがとう

4

1 に答える 1

5

ファンシー関数なしで何が間違っているのかを言うのは難しいですCreate_LLVM()が、一般的には2つの定数を追加するためです:

2 を作成する必要がありますConstantInt:

const auto& ctx = getGlobalContext(); // just your LLVMContext
auto* L = ConstantInt::get(Type::getInt32Ty(ctx), 41);
auto* R = ConstantInt::get(Type::getInt32Ty(ctx), 42);
const auto& builder = Get_Builder();
builder.Insert(L);  // just a no-op in standard builder impl
builder.Insert(R);  // just a no-op in standard builder impl
builder.CreateAdd(L, R, "addtmp");

あなたは得るべきです:

%addtmp = add i32 41, i32 42;

ビルダーは正しくセットアップされているとのことでしたので、現在動作しているaddの最後にを追加します。そして、少なくとも 1 つの をBasicBlock含む をすでに作成していると思います。FunctionBasicBlock

編集: ビルダーを使用せずに C++ API を呼び出すだけで追加命令を作成できます。

BinaryOperator* add = BinaryOperator::Create(BinaryOps::Add, L, R, "addtmp", BB); 

ここで、BB は電流BasicBlockです。

より洗練されたもの(変数に追加する)を取得するには、標準的な方法は次のとおりです。

最初はメモリが必要です。はAllocaInst、スタックにメモリを割り当てます。

これにはビルダーを使用できます。

auto* A = builder.CreateAlloca (Type::getInt32Ty(ctx), nullptr, "a");
auto* B = builder.CreateAlloca (Type::getInt32Ty(ctx), nullptr, "b");

簡単にするために、上記の定数を取得して、A と B に格納します。必要な値を格納するには、次のようにしますStoreInst

builder.CreateStore (L, A, /*isVolatile=*/false);
builder.CreateStore (R, B, /*isVolatile=*/false);

加算のために、以下を使用してメモリからレジスタに値をロードしますLoadInst

auto* addLHS = builder.CreateLoad(A);
auto* addRHS = builder.CreateLoad(B);

最後に上記の追加: auto* add = builder.CreateAdd(addLHS, addRHS , "add");

そして、追加するポインターを使用して、たとえば、それを返すか、別の変数に格納することができます。

IR は次のようになります。

define i32 foo() {
entry:
  %a = alloca i32, align 4
  %b = alloca i32, align 4
  store i32 41, i32* %a, align 4
  store i32 42, i32* %b, align 4
  %0 = load i32* %a, align 4
  %1 = load i32* %b, align 4
  %add = add i32 %0, %1
  ret i32 %add
}
于 2015-03-24T08:11:32.077 に答える