• 通过IRBuilder新建LLVM IR


    这一部分想给出一个完整的例子,来利用IRBuilder建立func_sum,并完成对齐的调用。(网上应该有完整的说明,忘记是哪里来的,留在这里方便记录,找到来源后附链接)来实现类似的功能:

    int sum(int n){
      int i = 1;
      int sum = 0;
      while(i<=n){
        sum += i;
        i++;
      }
      return sum;
    }
    
    int main(){
      return sum(10);
    }

    相似功能不做更多介绍,代码和注释已经很明确。

      1 #include "llvm/IR/LLVMContext.h"
      2 #include "llvm/IR/Module.h"
      3 #include "llvm/IR/Function.h"
      4 #include "llvm/IR/BasicBlock.h"
      5 #include "llvm/IR/IRBuilder.h"
      6 #include "llvm/ExecutionEngine/MCJIT.h"
      7 #include "llvm/Support/TargetSelect.h"
      8 #include "llvm/IR/TypeBuilder.h"
      9 #include "iostream"
     10 
     11 using namespace llvm;
     12 //c 
     13 
     14 int main(){
     15   static LLVMContext MyGlobalContext;
     16   LLVMContext &context = MyGlobalContext;
     17 
     18   //Create a module
     19   Module *module = new Module("test", context);
     20   IRBuilder<> builder(context);
     21 
     22   //create a function
     23   FunctionType *sum_type = TypeBuilder<int(int), false>::get(context);
     24   Function *sum_fun = cast<Function>(module->getOrInsertFunction("sum", sum_type));
     25 
     26   //create function's args
     27   Function::arg_iterator argsIt = sum_fun->arg_begin();
     28   Value *arg_n = argsIt++;
     29   arg_n->setName("n");
     30 
     31   //create two constant value
     32   Value *const_0 = ConstantInt::get(IntegerType::getInt32Ty(context), 0);
     33   Value *const_1 = ConstantInt::get(IntegerType::getInt32Ty(context), 1);
     34 
     35   //create entry basicblock
     36   BasicBlock *entry_sum = BasicBlock::Create(context, "entry", sum_fun);
     37   builder.SetInsertPoint(entry_sum);
     38 
     39   //Create 3 while BasicBlock
     40   BasicBlock *while_count = BasicBlock::Create(context, 
     41   "while_count", sum_fun);
     42   BasicBlock *while_body = BasicBlock::Create(context, "while_body", sum_fun);
     43   BasicBlock *while_end = BasicBlock::Create(context, "while_end", sum_fun);
     44 
     45 
     46   //Create variable i & sum
     47   Value *i_alloc = builder.CreateAlloca(Type::getInt32Ty(context));
     48   Value *sum_alloc = builder.CreateAlloca(Type::getInt32Ty(context));
     49   builder.CreateStore(const_1, i_alloc);
     50   builder.CreateStore(const_0, sum_alloc);
     51   builder.CreateBr(while_count);
     52 
     53   //while_count
     54   builder.SetInsertPoint(while_count);
     55   Value *i_load = builder.CreateLoad(Type::getInt32Ty(context), i_alloc);
     56   Value *cmp_value = builder.CreateICmpSLE(i_load, arg_n);
     57   builder.CreateCondBr(cmp_value, while_body, while_end);
     58 
     59   //while_body
     60   builder.SetInsertPoint(while_body);
     61   Value *sum_load = builder.CreateLoad(Type::getInt32Ty(context), sum_alloc);
     62   Value *temp_sum = builder.CreateAdd(sum_load, i_load);
     63   builder.CreateStore(temp_sum, sum_alloc);
     64   Value *temp_i = builder.CreateAdd(i_load, const_1);
     65   builder.CreateStore(temp_i, i_alloc);
     66   builder.CreateBr(while_count);
     67 
     68   builder.SetInsertPoint(while_end);
     69   Value *ret_sum = builder.CreateLoad(Type::getInt32Ty(context), sum_alloc);
     70   builder.CreateRet(ret_sum);
     71 
     72   //Function Decalare: int main()
     73   FunctionType *main_type = TypeBuilder<int(), false>::get(context);
     74   Function *main_fun = cast<Function>(module->getOrInsertFunction("main", main_type));
     75   BasicBlock *entry_main = BasicBlock::Create(context, "entry", main_fun);
     76   Value *n_value = ConstantInt::get(Type::getInt32Ty(context), 10);
     77 
     78   std::vector<Value*> putsargs;
     79   putsargs.push_back(n_value);
     80   ArrayRef<Value*> argsRef(putsargs);
     81   builder.SetInsertPoint(entry_main);
     82   Value *ret_value = builder.CreateCall(sum_fun, argsRef);
     83 
     84   builder.CreateRet(ret_value);
     85 
     86   module->dump();
     87 
     88   InitializeNativeTarget();
     89   InitializeNativeTargetAsmPrinter();
     90   InitializeNativeTargetAsmParser();
     91 
     92   //Create ExecutionEngine
     93   ExecutionEngine *ee = EngineBuilder(std::unique_ptr<Module>(module)).setEngineKind(EngineKind::JIT).create();
     94   void *mainAddr = ee->getPointerToFunction(main_fun);
     95 
     96   //execute
     97   typedef int (*FuncType)();
     98   FuncType mainFunc = (FuncType)mainAddr;
     99   ee->finalizeObject();
    100   std::cout << mainFunc() << std::endl;
    101 
    102   delete module;
    103   return 0;
    104 }
    View Code

    需要调用  clang++ -O3 IRBuilder.cpp -o irmain `llvm-config --cflags --ldflags` `llvm-config --libs` `llvm-config --system-libs`  进行编译

  • 相关阅读:
    【leetcode 968. 1028. 从先序遍历还原二叉树】解题报告[待完善...]
    【leetcode 3. 无重复字符的最长子串】解题报告
    【leetcode 76. 最小覆盖子串】解题报告
    【leetcode 239. 滑动窗口最大值】解题报告
    【leetcode 114. 二叉树展开为链表】解题报告
    【leetcode 105. 从前序与中序遍历序列构造二叉树】解题报告
    【leetcode 106. 从中序与后序遍历序列构造二叉树】解题报告
    【leetcode 968. 监控二叉树】解题报告
    【leetcode 145. 二叉树的后序遍历】解题报告
    linux springboot快捷启动脚本
  • 原文地址:https://www.cnblogs.com/jourluohua/p/15312366.html
Copyright © 2020-2023  润新知