Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在llvm中的我的IR代码中添加函数调用_C++_C_Clang_Llvm_Llvm Clang - Fatal编程技术网

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

C++ 在llvm中的我的IR代码中添加函数调用,c++,c,clang,llvm,llvm-clang,C++,C,Clang,Llvm,Llvm Clang,你能给我举个例子,说明如何添加一个简单的函数调用,比如 foo(x); < P>一个简单的方法是学习用输出选项作为 LLVM C++ API代码>/P> 两个关键注意事项: 确保foo的定义可用;否则你需要 首先对其进行界定。通常,您需要使用 getOrInsertFunction,然后使用IRBuilder插入主体 对于函数 创建CallInst,一个简单的方法是使用 CallInst*IRBuilder::CreateCall(Value*、ArrayRef、const-Twine&

你能给我举个例子,说明如何添加一个简单的函数调用,比如

foo(x); 

<我的IR代码中,我的LIVLM中的P< >

< P>一个简单的方法是学习用输出选项作为<强> LLVM C++ API代码>/P> 两个关键注意事项:

  • 确保
    foo
    的定义可用;否则你需要 首先对其进行界定。通常,您需要使用
    getOrInsertFunction
    ,然后使用
    IRBuilder
    插入主体 对于函数

  • 创建
    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<int(char *, ...), false>::get(getGlobalContext());
    
      Function *func = cast<Function>(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<int(int, char **), false>::get(getGlobalContext());
      Function *func = cast<Function>(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<Module>("example", ctx);
      IRBuilder<> builder(ctx);
      module->setDataLayout(
          "e-p: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<int, false>::get(getGlobalContext()));
      SmallVector<Value *, 4> 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<Value *, 4> assertArgs;
      assertArgs.push_back(utils::geti8StrVal(*module, "__assert_fail"));
      assertArgs.push_back(utils::geti8StrVal(*module, __FILE__));
      /// assertArgs.push_back(
      ///     ConstantInt::get(TypeBuilder<int, false>::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);
    }
    
    #包括“llvm/Analysis/Verifier.h”
    #包括“llvm/IR/DerivedTypes.h”
    #包括“llvm/IR/LLVMContext.h”
    #包括“llvm/IR/Module.h”
    #包括“llvm/IR/TypeBuilder.h”
    #包括“llvm/IR/IRBuilder.h”
    使用名称空间llvm;
    常量*geti8StrVal(模块和M、字符常量*str、绳线常量和名称){
    LLVMContext&ctx=getGlobalContext();
    常量*strConstant=ConstantDataArray::getString(ctx,str);
    全球可变*GVStr=
    新的全局变量(M,strConstant->getType(),true,
    全局值::内部链接,strConstant,name);
    常量*zero=Constant::getNullValue(IntegerType::getInt32Ty(ctx));
    常数*索引[]={0,0};
    常量*strVal=ConstantExpr::getElementPtr(GVStr,index,true);
    返回strVal;
    }
    静态函数*printf_原型(LLVMContext&ctx,模块*mod){
    函数类型*printf_类型=
    TypeBuilder::get(getGlobalContext());
    函数*func=cast(mod->getOrInsertFunction(
    “printf”,printf_类型,
    AttributeSet().addAttribute(mod->getContext(),1U,Attribute::NoAlias));
    返回函数;
    }
    静态函数*main_原型(LLVMContext&ctx,模块*mod){
    函数类型*foo_类型=
    TypeBuilder::get(getGlobalContext());
    函数*func=cast(mod->getOrInsertFunction(“main”,foo_类型));
    ///func->setLinkage(全局值::私有链接);
    返回函数;
    }
    int main(int argc,字符**argv){
    InitializeEnableTarget();
    LLVMContext&ctx=getGlobalContext();
    模块*模块=新模块(“示例”,ctx);
    ///自动模块=标准::使_唯一(“示例”,ctx);
    IRBuilder(ctx);
    模块->设置数据布局(
    “e-p:64:64:64-i1:8:8-i8:8-i16:16:16-i32: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”);
    模块->setTargetTriple(“x86_64-unknown-linux-gnu”);
    //
    //外部无效打印F(常量字符*fmt,…);
    //
    函数*printf_func=printf_原型(ctx,模块);
    //
    //int foo(无效)
    // {
    功能*main\u fn=主\u原型(ctx,模块);
    BasicBlock*block=BasicBlock::Create(ctx,“,main_fn,0);
    生成器。设置插入点(块);
    //
    //int32温度=15+。。。
    //
    常量*left=ConstantInt::get(ctx,APInt(32,15));
    AllocaInst*AllocaInst=
    CreateAlloca(TypeBuilder::get(getGlobalContext());
    小矢量加法器;
    对于(参数&arg:main\u fn->getArgumentList()){
    addsVect.push_back(&arg);
    }
    builder.CreateStore(addsVect[0],allocaInst);
    LoadInst*LoadInst=builder.CreateLoad(allocaInst);
    Value*add=builder.CreateAdd(左,loadInst);
    ///添加->getType()->dump();
    ///errs()getType());
    ///
    CreateICmpEQ(add,nullValue);
    CreateICmpNE(add,null值);
    ///
    Value*cmpResult=builder.CreateICmpUGT(add,nullValue);
    CreateICmpUGE(add,null值);
    CreateICmpULT(add,null值);
    CreateICmpULE(add,null值);
    ///
    CreateICmpSGT(add,null值);
    CreateICmpSGE(add,nullValue);
    CreateICmpSLT(add,nullValue);
    CreateICmpSLE(add,null值);
    ///
    基本块*br\u true=BasicBlock::Create(ctx,“br\u true”,main\u fn,0);
    基本块*br\u false=BasicBlock::Create(ctx,“br\u false”,main\u fn,0);
    CreateCondBr(cmpResult,br\u true,br\u false);
    builder.SetInsertPoint(br_false);
    CreateCall2(printf_func,utils::geti8StrVal(*模块,“%d\n”),add);
    小向量资产;
    assertArgs.push_back(utils::geti8StrVal(*模块,“u断言失败”);
    assertArgs.push_back(utils::geti8StrVal(*模块,u文件_u));
    ///assertArgs.push_返回(
    ///康斯坦丁::get(TypeBuilder::get(ctx),_行,false));
    assertArgs.推回(添加);
    assertArgs.push_back(utils::geti8StrVal(*模块,__函数__));
    函数*assertFunc=utils::getFn\u assert(*模块);
    ///errs()应该可以工作