BasickBlockに後から命令を追加する
最初にIRBuilderで作成したBasicBlockに後からInstructionを
追加する必要が出てきたので、コードを書いた。
BasickBlockは必ずBranchInstかReturnInstで終わっているはず
なので、その直前に新たに命令をinsertしていく。
#include <llvm/LLVMContext.h> #include <llvm/Module.h> #include <llvm/Support/IRBuilder.h> using namespace llvm; Function *createFunc(Module *m) { /* void test() { return; } */ Type *voidTy = Type::getVoidTy(m->getContext()); std::vector<Type*> args; FunctionType *Ty = FunctionType::get(voidTy, args, false); Function *F = Function::Create(Ty, GlobalValue::ExternalLinkage, "test", m); BasicBlock *bb = BasicBlock::Create(m->getContext(), "EntryBlock", F); IRBuilder<> *builder = new IRBuilder<>(bb); builder->CreateRetVoid(); return F; } int main(int argc, char **argv) { LLVMContext &Context = getGlobalContext(); Type *intTy = Type::getInt32Ty(Context); Module *m = new Module("test", Context); Function *F = createFunc(m); Constant *Zero = ConstantInt::get(intTy, 0); BasicBlock *BB = F->begin(); Instruction *I = --(BB->end()); Type *types[] = {intTy}; Value *Idxs_[] = {Zero, Zero}; std::vector<Type*> fields(types, types+1); std::vector<Value*> Idxs(Idxs_, Idxs_+2); StructType* structTy = StructType::create(fields, "struct.x", false); AllocaInst *newinst = new AllocaInst(structTy); GetElementPtrInst *gep = GetElementPtrInst::CreateInBounds(newinst, Idxs); StoreInst *store = new StoreInst(ConstantInt::get(intTy, 10), gep); BB->getInstList().insert(I, newinst); BB->getInstList().insert(I, gep); BB->getInstList().insert(I, store); (*m).dump(); return 0; }
createFunc関数では以下の関数を生成しているが、無事alloca, gep, storeの命令が
挿入されていることが確認できた。
void test() { return; }
$ g++ a.cpp `llvm-config --cxxflags --libs core` && ./a.out ; ModuleID = 'test' %struct.x = type { i32 } define void @test() { EntryBlock: %0 = alloca %struct.x %1 = getelementptr inbounds %struct.x* %0, i32 0, i32 0 store i32 10, i32* %1 ret void }