在llvm中的IR代码中添加函数调用

你能举个例子,如何添加函数的简单调用

foo(x); 

我在我的IR代码中使用llvm中的传递?

一种简单的方法是学习使用ELLCC和输出选项作为LLVM C ++ API代码

两个关键说明:

  1. 确保foo的定义可用; 否则你需要先定义它。 通常,您需要使用getOrInsertFunction获取原型,然后使用IRBuilder插入函数的主体。

  2. 创建CallInst ,一种简单的方法是使用CallInst*IRBuilder::CreateCall(Value*, ArrayRef, const Twine &)

这是我之前为llvm3.4写的一段; 希望它可以提供帮助。

 #include "llvm/Analysis/Verifier.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/TypeBuilder.h" #include "llvm/IR/IRBuilder.h" using namespace llvm; Constant* geti8StrVal(Module& M, char const* str, Twine const& name) { LLVMContext& ctx = getGlobalContext(); Constant* strConstant = ConstantDataArray::getString(ctx, str); GlobalVariable* GVStr = new GlobalVariable(M, strConstant->getType(), true, GlobalValue::InternalLinkage, strConstant, name); Constant* zero = Constant::getNullValue(IntegerType::getInt32Ty(ctx)); Constant* indices[] = {zero, zero}; Constant* strVal = ConstantExpr::getGetElementPtr(GVStr, indices, true); return strVal; } static Function *printf_prototype(LLVMContext &ctx, Module *mod) { FunctionType *printf_type = TypeBuilder::get(getGlobalContext()); Function *func = cast(mod->getOrInsertFunction( "printf", printf_type, AttributeSet().addAttribute(mod->getContext(), 1U, Attribute::NoAlias))); return func; } static Function *main_prototype(LLVMContext &ctx, Module *mod) { FunctionType *foo_type = TypeBuilder::get(getGlobalContext()); Function *func = cast(mod->getOrInsertFunction("main", foo_type)); /// func->setLinkage(GlobalValue::PrivateLinkage); return func; } int main(int argc, char **argv) { InitializeNativeTarget(); LLVMContext &ctx = getGlobalContext(); Module *module = new Module("example", ctx); /// auto module = std::make_unique("example", ctx); IRBuilder<> builder(ctx); module->setDataLayout( "ep:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-" "a0:0:64-s0:64:64-f80:128:128"); module->setTargetTriple("x86_64-unknown-linux-gnu"); // // extern void printf(const char *fmt, ...); // Function *printf_func = printf_prototype(ctx, module); // // int foo(void) // { Function *main_fn = main_prototype(ctx, module); BasicBlock *block = BasicBlock::Create(ctx, "", main_fn, 0); builder.SetInsertPoint(block); // // int32_t temp = 15 + ... // Constant *left = ConstantInt::get(ctx, APInt(32, 15)); AllocaInst *allocaInst = builder.CreateAlloca(TypeBuilder::get(getGlobalContext())); SmallVector addsVect; for (Argument &arg : main_fn->getArgumentList()) { addsVect.push_back(&arg); } builder.CreateStore(addsVect[0], allocaInst); LoadInst *loadInst = builder.CreateLoad(allocaInst); Value *add = builder.CreateAdd(left, loadInst); /// add->getType()->dump(); /// errs() << "\n"; // // printf("%d\n", temp); // Constant *nullValue = Constant::getNullValue(add->getType()); /// builder.CreateICmpEQ(add, nullValue); builder.CreateICmpNE(add, nullValue); /// Value *cmpResult = builder.CreateICmpUGT(add, nullValue); builder.CreateICmpUGE(add, nullValue); builder.CreateICmpULT(add, nullValue); builder.CreateICmpULE(add, nullValue); /// builder.CreateICmpSGT(add, nullValue); builder.CreateICmpSGE(add, nullValue); builder.CreateICmpSLT(add, nullValue); builder.CreateICmpSLE(add, nullValue); /// BasicBlock *br_true = BasicBlock::Create(ctx, "br_true", main_fn, 0); BasicBlock *br_false = BasicBlock::Create(ctx, "br_false", main_fn, 0); builder.CreateCondBr(cmpResult, br_true, br_false); builder.SetInsertPoint(br_false); builder.CreateCall2(printf_func, utils::geti8StrVal(*module, "%d\n"), add); SmallVector assertArgs; assertArgs.push_back(utils::geti8StrVal(*module, "__assert_fail")); assertArgs.push_back(utils::geti8StrVal(*module, __FILE__)); /// assertArgs.push_back( /// ConstantInt::get(TypeBuilder::get(ctx), __LINE__, false)); assertArgs.push_back(add); assertArgs.push_back(utils::geti8StrVal(*module, __FUNCTION__)); Function *assertFunc = utils::getFn_assert(*module); /// errs() << *assertFunc; builder.CreateCall(assertFunc, assertArgs); /// builder.CreateBr(br_true); ConstantInt *zero = ConstantInt::get(IntegerType::getInt32Ty(ctx), 0); builder.CreateRet(zero); // // return 0; // } // builder.SetInsertPoint(br_true); builder.CreateRet(zero); }