通过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`  进行编译

原文地址:https://www.cnblogs.com/jourluohua/p/15312366.html