当前位置:网站首页>LLVM - 生成for循环
LLVM - 生成for循环
2022-04-23 14:11:00 【Mrpre】
1、生成函数
2、使用Phi表达式实现for循环
3、本例中,KaleidoscopeJIT源码位于./llvm-8.0.1.src/examples/Kaleidoscope/include/KaleidoscopeJIT.h
Phi的概念可参考https://stackoverflow.com/questions/11485531/what-exactly-phi-instruction-does-and-how-to-use-it-in-llvm
本例中,生成的llvm ir如下:
define double @myfor(double %a) {
myentry:
br label %loop
loop: ; preds = %loop, %myentry
%i = phi double [ 0.000000e+00, %myentry ], [ %nextvar, %loop ]
%a1 = fadd double %a, 2.000000e+00
%nextvar = fadd double 1.000000e+00, %i
%cmptmp = fcmp ult double %i, 1.000000e+01
br i1 %cmptmp, label %loop, label %afterloop
afterloop: ; preds = %loop
ret double %a1
}
phi的逻辑,如果从 myentry 来(比如刚进来),则 %i就是 0,否则%i 的值就是%nextvar(比如循环完一次)
代码:
#include "./llvm-8.0.1.src/examples/Kaleidoscope/include/KaleidoscopeJIT.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/InstCombine/InstCombine.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Scalar/GVN.h"
#include <string>
#include <vector>
#include <iostream>
using namespace std;
using namespace llvm;
using namespace llvm::orc;
//LLVM items
static LLVMContext TheContext;
static IRBuilder<> Builder(TheContext);
static std::unique_ptr<Module> TheModule;
//JIT
static std::unique_ptr<KaleidoscopeJIT> TheJIT;
/* *double myfor(double a) *{ * for(i = 0; i < a; i++) { * a = a + 1 * } * return a *} * */
int main()
{
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
//init module
TheModule = llvm::make_unique<Module>("myjit", TheContext);
//used to be runned by jit later
TheJIT = llvm::make_unique<KaleidoscopeJIT>();
TheModule->setDataLayout(TheJIT->getTargetMachine().createDataLayout());
//define the args
vector<std::string> ArgNames;
//myfor has 1 args
ArgNames.push_back(string("a"));
//make the 1 args attach to LLVM Type::double
std::vector<Type *> Doubles(ArgNames.size(), Type::getDoubleTy(TheContext));
//generate llvm function type
FunctionType *FT = FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false);
//Create function whose FunctionType is FT
Function *TheFunction = Function::Create(FT, Function::ExternalLinkage, "myfor", TheModule.get());
//give the name of Function args and save the args as innerargs
unsigned Idx = 0;
std::vector<Value *>innerargs;
for (auto &Arg : TheFunction->args()) {
Arg.setName(ArgNames[Idx++]);
innerargs.push_back(&Arg);
}
//this function's basic block
BasicBlock *BB = BasicBlock::Create(TheContext, "myentry", TheFunction);
//create the loop BasicBlock
BasicBlock *LoopBB = BasicBlock::Create(TheContext, "loop", TheFunction);
//exit the block
BasicBlock *AfterBB = BasicBlock::Create(TheContext, "afterloop", TheFunction);
Builder.SetInsertPoint(BB);
//add goto LoopBB in BB
Builder.CreateBr(LoopBB);
//start with LoopBB
Builder.SetInsertPoint(LoopBB);
//start with 0
Value *StartVal = ConstantFP::get(TheContext, APFloat(0.0));
//step is 1
Value *StepVal = ConstantFP::get(TheContext, APFloat(1.0));
//local Variable which name is a
PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(TheContext), 1, "i");
//if it's from start block, set Variable 0
Variable->addIncoming(StartVal, BB);
//do the body then do cond
//emit loop body in LoopBB
//body: arg_a += 1
Value *ret = Builder.CreateFAdd(innerargs[0], ConstantFP::get(TheContext, APFloat(2.0)), "a");
//do the cond,if Variable >= 2 then break(goto AfterBB)
Value *NextVar = Builder.CreateFAdd(StepVal, Variable, "nextvar");
//if Variable < 10 then goto LoopBB or gotot AfterBB
Value *cond = Builder.CreateFCmpULT(Variable, ConstantFP::get(TheContext, APFloat(10.0)), "cmptmp");
Builder.CreateCondBr(cond, LoopBB, AfterBB);
Builder.SetInsertPoint(AfterBB);
Variable->addIncoming(NextVar, LoopBB);
Builder.CreateRet(ret);
TheFunction->print(errs());
//using jit to run this code
auto H = TheJIT->addModule(std::move(TheModule));
auto ExprSymbol = TheJIT->findSymbol("myfor");
double (*myfor)(double) = (double (*)(double))(intptr_t)cantFail(ExprSymbol.getAddress());
cout <<myfor(40)<<endl;
}
版权声明
本文为[Mrpre]所创,转载请带上原文链接,感谢
https://wonderful.blog.csdn.net/article/details/106902005
边栏推荐
- PySide2
- squid代理
- 云迁移的六大场景
- json date时间日期格式化
- A table splitting implementation scheme of MySQL and InnoDB, MyISAM and MRG_ Introduction to MyISAM and other engine application scenarios
- 如何轻松做好一个项目
- VMware 15pro mounts the hard disk of the real computer in the deepin system
- 微信小程序将原生请求通过es6的promise来进行优化
- 时间复杂度计算举例
- 百度笔试2022.4.12+编程题目:简单整数问题
猜你喜欢

HyperBDR云容灾V3.2.1版本发布|支持更多云平台,新增监控告警功能

多云数据流转?云上容灾?年前最后的价值内容分享

VMware 15pro mounts the hard disk of the real computer in the deepin system

Processing MKDIR: unable to create directory 'AAA': read only file system

API Gateway/API 网关(三) - Kong的使用 - 限流rate limiting(redis)

Visio画拓扑图随记

Operation instructions of star boundary automatic text translator (advanced version)

MYSQL一种分表实现方案及InnoDB、MyISAM、MRG_MYISAM等各种引擎应用场景介绍

使用Executors类快速创建线程池

After entering the new company, the operation and maintenance engineer can understand the deployment of the system from the following items
随机推荐
Five ways of using synchronized to remove clouds and fog are introduced
js 格式化时间
Uni app message push
MySQL数据库讲解(七)
第四届“传智杯”全国大学生IT技能大赛(决赛B组) 题解
Flop effect
容灾有疑问?点这里
Tongxin UOS uninstall php7 2.24, install php7 4.27 ; Uninstall and then install PHP 7.2.34
微信小程序轮播图swiper
mysql 5.1升级到5.611
使用Executors类快速创建线程池
squid代理
操作系统常见面试题目:
ie8 浏览器提示是否 阻止访问js脚本
一些小小小小记录~
SED 学以致用
Operation instructions of star boundary text automatic translator
Thread group ThreadGroup uses introduction + custom thread factory class to implement threadfactory interface
yml引用其他变量
获取线程返回值Future接口与FutureTask类使用介绍