千家信息网

LLVM IR中怎么实现简单循环

发表于:2025-01-23 作者:千家信息网编辑
千家信息网最后更新 2025年01月23日,这期内容当中小编将会给大家带来有关LLVM IR中怎么实现简单循环,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。LLVM实现IR共有三种方式,这是最笨拙的方式,但也
千家信息网最后更新 2025年01月23日LLVM IR中怎么实现简单循环

这期内容当中小编将会给大家带来有关LLVM IR中怎么实现简单循环,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

LLVM实现IR共有三种方式,这是最笨拙的方式,但也最与IR语义接近,是IR入门的最基础语法。本文实现了IR的For循环指令,具体实现的逻辑可参见代码的注释部分。运行指令可参见上一篇博文的结尾处。国内LLVM资料相对较少,分享出来代码,可以丰富网上LLVM IR相关的代码,有利于促进LLVM IR语法的理解,进而相关从业人员和相关行业的进步。代码虽粗陋,但功能进本完备可运行,还望各位海涵。

#include "llvm/IR/IRBuilder.h"#include "llvm/IR/Verifier.h"#include "llvm/Support/TargetSelect.h"#include "llvm/ExecutionEngine/ExecutionEngine.h"#include "llvm/IR/LLVMContext.h"#include "llvm/IR/Module.h"#include "llvm/IR/Function.h"#include "llvm/IR/BasicBlock.h"#include "llvm/ExecutionEngine/MCJIT.h"#include "llvm/IR/TypeBuilder.h"#include #include #include #include #include #include #include #include #include #include #include using namespace llvm;using namespace std;//===----------------------------------------------------------------------===////                         simple `for loop`  //===----------------------------------------------------------------------===//// //  int result ;// void foo(){//  for(int i=0;i<100000;i++){//  int condition = i%4;                       //              if(condition == 0) {//                       result +=10;//              }else if(condition == 1) {//                       result -= 2;//              }else if(condition == 1) {//                       result *= 6;//              }else if(condition == 1) {//                       result /= 3;//              }else {//                       result ++;//              }////   }//===----------------------------------------------------------------------===//int main(){        // initialize global context    static LLVMContext MyGlobalContext;    LLVMContext &context = MyGlobalContext;            //1. create module    Module *module = new Module("test", context);         { //set datalayout and Triples        module ->setDataLayout("e-m:e-i64:64-f80:128-n8:16:32:64-S128");        module ->setTargetTriple("x86_64-unknown-linux-gnu");    }//create LLVM constant     ConstantInt* const_int32_0 =  ConstantInt::get(module->getContext(), APInt(32, StringRef("0")StringRef("0"), 10));         ConstantInt* const_int32_1 =  ConstantInt::get(module->getContext(), APInt(32, StringRef("0")StringRef("1"), 10));     ConstantInt* const_int32_2 =  ConstantInt::get(module->getContext(), APInt(32, StringRef("0")StringRef("2"), 10));     ConstantInt* const_int32_3 =  ConstantInt::get(module->getContext(), APInt(32, StringRef("0")StringRef("3"), 10));     ConstantInt* const_int32_4 =  ConstantInt::get(module->getContext(), APInt(32, StringRef("0")StringRef("4"), 10));     ConstantInt* const_int32_6 =  ConstantInt::get(module->getContext(), APInt(32, StringRef("0")StringRef("6"), 10));     ConstantInt* const_int32_10 =  ConstantInt::get(module->getContext(), APInt(32, StringRef("10"), 10));     ConstantInt* const_int32_n =  ConstantInt::get(module->getContext(), APInt(32, StringRef("10000000"), 10));//2. create function     FunctionType *foo_type = TypeBuilder::get(context);      Function *func = Function::Create(foo_type, GlobalValue::LinkageTypes::ExternalLinkage, "compareExec", module);        func->setCallingConv(CallingConv::C);//3. basic block         BasicBlock* label_entry = BasicBlock::Create(module->getContext(), "entry",func);        BasicBlock* label_for_cond = BasicBlock::Create(module->getContext(), "for.cond",func);        BasicBlock* label_for_body = BasicBlock::Create(module->getContext(), "for.body",func);    BasicBlock* label_if_then = BasicBlock::Create(module->getContext(), "if.then",func);    BasicBlock* label_if_else = BasicBlock::Create(module->getContext(), "if.else",func);    BasicBlock* label_if_then3 = BasicBlock::Create(module->getContext(), "if.then3",func);    BasicBlock* label_if_else4 = BasicBlock::Create(module->getContext(), "if.else4",func);    BasicBlock* label_if_then6 = BasicBlock::Create(module->getContext(), "if.then6",func);    BasicBlock* label_if_else7 = BasicBlock::Create(module->getContext(), "if.else7",func);    BasicBlock* label_if_then9 = BasicBlock::Create(module->getContext(), "if.then9",func);    BasicBlock* label_if_else10 = BasicBlock::Create(module->getContext(), "if.else10",func);    BasicBlock* label_if_end = BasicBlock::Create(module->getContext(), "if.end",func);    BasicBlock* label_if_end11 = BasicBlock::Create(module->getContext(), "if.end11",func);    BasicBlock* label_if_end12 = BasicBlock::Create(module->getContext(), "if.end12",func);    BasicBlock* label_if_end13 = BasicBlock::Create(module->getContext(), "if.end13",func);    BasicBlock* label_for_inc = BasicBlock::Create(module->getContext(), "for.inc",func);    BasicBlock* label_for_end = BasicBlock::Create(module->getContext(), "for.end",func);//block entry(label entry)        AllocaInst* ptr_result =   new AllocaInst(IntegerType::get(module->getContext(), 32),module->getDataLayout().getAllocaAddrSpace(), "result", label_entry);    ptr_result->setAlignment(4); AllocaInst* ptr_i =   new AllocaInst(IntegerType::get(module->getContext(), 32),module->getDataLayout().getAllocaAddrSpace(), "i", label_entry);    ptr_i->setAlignment(4); AllocaInst* ptr_condition =   new AllocaInst(IntegerType::get(module->getContext(), 32),module->getDataLayout().getAllocaAddrSpace(), "condition", label_entry);    ptr_condition->setAlignment(4);       StoreInst* inst_0 =  new StoreInst(const_int32_0, ptr_i, false, label_entry);    inst_0->setAlignment(4);        BranchInst::Create(label_for_cond, label_entry);        //block for.cond (label_for_cond).LoadInst* int32_var = new LoadInst(ptr_i, "0", false, label_for_cond);int32_var->setAlignment(4);  ICmpInst* int1_cmp = new ICmpInst(*label_for_cond, ICmpInst::ICMP_SLT, int32_var, const_int32_n, "cmp");BranchInst::Create(label_for_body, label_for_end,  int1_cmp, label_for_cond);    //block for.body(label_for_body).    LoadInst* int32_var1 = new LoadInst(ptr_i, "1", false, label_for_body);        int32_var1->setAlignment(4);    BinaryOperator* rem = BinaryOperator::Create(Instruction::SRem, int32_var1 , const_int32_4, "srem", label_for_body);    StoreInst* void_rem = new StoreInst(rem, ptr_condition, false, label_for_body);        void_rem->setAlignment(4);    LoadInst* int32_var2 = new LoadInst(ptr_condition, "2", false, label_for_body);        int32_var2->setAlignment(4);     ICmpInst* int1_cmp0 = new ICmpInst(*label_for_body, ICmpInst::ICMP_EQ, int32_var2, const_int32_0, "cmpeq");    BranchInst::Create(label_if_then, label_if_else,  int1_cmp0, label_for_body);    //block if.then(label_if_then).    LoadInst* int32_var3 = new LoadInst(ptr_result, "3", false, label_if_then);        int32_var3->setAlignment(4);     BinaryOperator* int32_add = BinaryOperator::CreateNSW(Instruction::Add, int32_var3 , const_int32_10, "add",  label_if_then);    StoreInst* void_add = new StoreInst(int32_add, ptr_result, false, label_if_then);    void_add->setAlignment(4);        BranchInst::Create(label_if_end13, label_if_then);    //block if.else(label_if_else). LoadInst* int32_var4 = new LoadInst(ptr_condition, "4", false, label_if_else); int32_var4->setAlignment(4); ICmpInst* int1_cmp2 = new ICmpInst(*label_if_else, ICmpInst::ICMP_EQ, int32_var4, const_int32_1, "cmpeq2"); BranchInst::Create(label_if_then3, label_if_else4,  int1_cmp2, label_if_else);    //block if.then3(label_if_then3).LoadInst* int32_var5 = new LoadInst(ptr_result, "5", false, label_if_then3);int32_var5->setAlignment(4);BinaryOperator* int32_sub = BinaryOperator::CreateNSW(Instruction::Sub, int32_var5 , const_int32_2, "sub", label_if_then3);StoreInst* void_sub = new StoreInst(int32_sub, ptr_result, false, label_if_then3);void_sub->setAlignment(4);BranchInst::Create(label_if_end12, label_if_then3);        //block if.else4(label_if_else).    LoadInst* int32_var6 = new LoadInst(ptr_condition, "6", false, label_if_else4);    int32_var6->setAlignment(4);    ICmpInst* int1_cmp5 = new ICmpInst(*label_if_else4, ICmpInst::ICMP_EQ, int32_var6, const_int32_2, "cmpeq5");    BranchInst::Create(label_if_then6, label_if_else7,  int1_cmp5, label_if_else4);    //block if.then6(label_if_then6)    LoadInst* int32_var7 = new LoadInst(ptr_result, "7", false, label_if_then6);        int32_var7->setAlignment(4);    BinaryOperator* int32_mul = BinaryOperator::CreateNSW(Instruction::Mul, int32_var7 , const_int32_6, "Mul", label_if_then6);    StoreInst* void_mul = new StoreInst(int32_mul, ptr_result, false, label_if_then6);    void_mul->setAlignment(4);    BranchInst::Create(label_if_end11, label_if_then6);        //block if.else7(label_if_else7)    LoadInst* int32_var8 = new LoadInst(ptr_condition, "8", false, label_if_else7);    int32_var8->setAlignment(4);    ICmpInst* int1_cmp8 = new ICmpInst(*label_if_else7, ICmpInst::ICMP_EQ, int32_var8, const_int32_3, "cmpeq8");    BranchInst::Create(label_if_then9, label_if_else10,  int1_cmp8, label_if_else7);         //block if.then9(label_if_then9).    LoadInst* int32_var9 = new LoadInst(ptr_result, "9", false, label_if_then9);        int32_var9->setAlignment(4);    BinaryOperator* int32_div = BinaryOperator::Create(Instruction::SDiv, int32_var9 , const_int32_3, "div", label_if_then9);    StoreInst* void_div = new StoreInst(int32_div, ptr_result, false, label_if_then9);    void_div->setAlignment(4);    BranchInst::Create(label_if_end, label_if_then9);        //block if.else10(label_if_else10).    LoadInst* int32_var10 = new LoadInst(ptr_condition, "10", false, label_if_else10);    int32_var10->setAlignment(4);    BinaryOperator* int32_inc = BinaryOperator::CreateNSW(Instruction::Add, int32_var10 , const_int32_1, "inc", label_if_else10);        StoreInst* void_inc = new StoreInst(int32_inc, ptr_result, false,  label_if_else10);        void_inc->setAlignment(4);    BranchInst::Create(label_if_end, label_if_else10);//block if.end(label_if_end)    BranchInst::Create(label_if_end11, label_if_end);    //block if.end11(label_if_end11)        BranchInst::Create(label_if_end12, label_if_end11);        //block if.end12(label_if_end12)    BranchInst::Create(label_if_end13, label_if_end12);        //block if.end13(label_if_end13)        BranchInst::Create(label_for_inc, label_if_end13);    //block for.inc(label_for_inc)        LoadInst* int32_var11 = new LoadInst(ptr_i, "11", false, label_for_inc);    int32_var11->setAlignment(4);        BinaryOperator* int32_inc14 = BinaryOperator::CreateNSW(Instruction::Add, int32_var11 , const_int32_1, "inc14", label_for_inc);    StoreInst* void_12 = new StoreInst(int32_inc14, ptr_i, false, label_for_inc);    void_12->setAlignment(4);        BranchInst::Create(label_for_cond, label_for_inc);        //block for.end(label_for_end)        ReturnInst::Create(module->getContext(), const_int32_0, label_for_end);        //verify module    bool Result = llvm::verifyModule(*module);    if(Result) {       std::cout << "IR verify success" << std::endl;   }    module->dump();//Initialize native library        InitializeNativeTarget();        InitializeNativeTargetAsmPrinter();        InitializeNativeTargetAsmParser();        //printf("Hello, world\n");           ExecutionEngine *ee = EngineBuilder(std::unique_ptr(module)).setEngineKind(EngineKind::JIT).setOptLevel(CodeGenOpt::None).create();     void * funcAddr = ee->getPointerToFunction(func);   //Run the function     typedef int (*FuncType)();   FuncType firFunc = (FuncType)funcAddr;   firFunc();//   endst = clock();   std::cout << "calling consume time (s): " << "ssss" <<  std::endl;        return 0;}

上述就是小编为大家分享的LLVM IR中怎么实现简单循环了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注行业资讯频道。

0