ファンシー関数なしで何が間違っているのかを言うのは難しいです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
含む をすでに作成していると思います。Function
BasicBlock
編集:
ビルダーを使用せずに 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
}