zoukankan      html  css  js  c++  java
  • llvm function expr

    想要什么:

    int add1(int p1) { return 1 + p1; }
    

    IR:

    define i32 @add1(i32 %p1) {
    entry:
      %retVal = add i32 1, %p1
      ret i32 %retVal
    }
    
    #include "llvm/ExecutionEngine/Orc/LLJIT.h"
    #include "llvm/IR/Function.h"
    #include "llvm/IR/IRBuilder.h"
    #include "llvm/IR/Module.h"
    #include "llvm/Support/CommandLine.h"
    #include "llvm/Support/InitLLVM.h"
    #include "llvm/Support/TargetSelect.h"
    #include "llvm/Support/raw_ostream.h"
    
    using namespace llvm;
    using namespace llvm::orc;
    
    ExitOnError ExitOnErr;
    
    ThreadSafeModule createTSM() {
      // context 拥有许多核心的 LLVM 数据结构,例如类型和常量值表
      auto Context = std::make_unique<LLVMContext>();
    
      // module 包含函数和全局变量的LLVM构造,它是 LLVM IR 用来包含代码的顶级结构。它将拥有我们生成的所有 IR 的内存
      auto M = std::make_unique<Module>("test", *Context);
    
      // 创建一个构建器,可以轻松生成 LLVM 指令
      IRBuilder<> builder(*Context);
    
      // 声明一个函数 int add1(int) 添加到module中
      auto funcType = FunctionType::get(Type::getInt32Ty(*Context), { Type::getInt32Ty(*Context) }, false);
      Function* Add1F = Function::Create(funcType, Function::ExternalLinkage, "add1", M.get());
    
      // 创建一个block添加到Add1F
      BasicBlock* BB = BasicBlock::Create(*Context, "entry", Add1F);
      
      // 构建器接下来的指令将插入到BB
      builder.SetInsertPoint(BB);
    
      // 获取指向常量“1”的指针
      Value* One = builder.getInt32(1);
    
      // 获取指向 add1 函数的整数参数的指针
      assert(Add1F->arg_size() == 1);        // 确保有一个 arg
      Argument* p1 = Add1F->getArg(0);   // 获取参数
      p1->setName("p1"); // 设置arg name, int add1(int p1);
    
      // 创建 add 指令,将其插入到 BB
      // 创建返回指令并将其添加到基本块
      builder.CreateRet(builder.CreateAdd(One, p1, "retVal")); // ret 1 + p1
      
      // 打印出所有生成的代码
      M->print(errs(), nullptr);
    
      // 返回线程模块
      return ThreadSafeModule(std::move(M), std::move(Context));
    }
    
    int main() {
      InitializeNativeTarget();
      InitializeNativeTargetAsmPrinter();
    
      // Create an LLJIT instance.
      auto _jit = ExitOnErr(LLJITBuilder().create());
      auto M = createTSM();
      
      ExitOnErr(_jit->addIRModule(std::move(M)));
    
      // 查找 JIT 函数,将其转换为函数指针,然后调用它.
      auto Add1Sym = ExitOnErr(_jit->lookup("add1"));
      int (*Add1)(int) = (int (*)(int))Add1Sym.getAddress();
      int Result = Add1(42);
      outs() << "add1(42) = " << Result << "
    ";
    
      return 0;
    }
    
  • 相关阅读:
    浙大版《C语言程序设计(第3版)》题目集 --总结
    | C语言I作业09
    c语言课本及pta作业中运用到的程序思维
    | C语言I作业08
    团队作业(四):描述设计
    实验三《敏捷开发与XP实践》_实验报告
    MyOD(课下作业,选做)
    实验二《面向对象程序设计》_实验报告
    20175226 2018-2019-2《java程序设计》结对编程-四则运算(第二周-阶段总结)
    20175226 类定义
  • 原文地址:https://www.cnblogs.com/ajanuw/p/14838829.html
Copyright © 2011-2022 走看看