当前位置:网站首页>Llvm - generate for loop
Llvm - generate for loop
2022-04-23 15:04:00 【Mrpre】
1、 Generating function
2、 Use Phi Expression implementation for loop
3、 In this case ,KaleidoscopeJIT The source code is located in ./llvm-8.0.1.src/examples/Kaleidoscope/include/KaleidoscopeJIT.h
Phi The concept of can be referred to https://stackoverflow.com/questions/11485531/what-exactly-phi-instruction-does-and-how-to-use-it-in-llvm
In this case , Generated llvm ir as follows :
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 The logic of , If from myentry Come on ( Like just coming in ), be %i Namely 0, otherwise %i The value is %nextvar( For example, after a cycle )
Code :
#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://yzsam.com/2022/04/202204231409588105.html
边栏推荐
- 编程哲学——自动加载、依赖注入与控制反转
- Leetcode151 - invert words in string - String - simulation
- Is asemi ultrafast recovery diode interchangeable with Schottky diode
- Async void caused the program to crash
- go基础 反射
- 【thymeleaf】处理空值和使用安全操作符
- How to upload large files quickly?
- Share 3 tools, edit 5 works at home and earn more than 400
- Brute force of DVWA low -- > High
- Share 20 tips for ES6 that should not be missed
猜你喜欢
8.4 realization of recurrent neural network from zero
OC to swift conditional compilation, marking, macro, log, version detection, expiration prompt
capacitance
For 22 years, you didn't know the file contained vulnerabilities?
Detailed explanation of C language knowledge points -- first understanding of C language [1] - vs2022 debugging skills and code practice [1]
[untitled]
Leetcode151 - invert words in string - String - simulation
LeetCode165-比较版本号-双指针-字符串
thinkphp5+数据大屏展示效果
What is the effect of Zhongfu Jinshi wealth class 29800? Walk with professional investors to make investment easier
随机推荐
capacitance
Redis主从同步
[NLP] HMM hidden Markov + Viterbi word segmentation
epoll 的EPOLLONESHOT 事件———实例程序
Leetcode151 - invert words in string - String - simulation
LeetCode165-比较版本号-双指针-字符串
What is the main purpose of PCIe X1 slot?
January 1, 1990 is Monday. Define the function date_ to_ Week (year, month, day), which realizes the function of returning the day of the week after inputting the year, month and day, such as date_ to
Flink DataStream 类型系统 TypeInformation
Set onedrive or Google drive as a drawing bed in upic for free
8.2 text preprocessing
Swift protocol Association object resource name management multithreading GCD delay once
SQL中HAVING和WHERE的区别
Epoll's et, lt working mode -- example program
Advanced version of array simulation queue - ring queue (real queuing)
脏读、不可重复读和幻读介绍
Introduction to distributed transaction Seata
Sqlserver transaction and lock problem
Go basic reflection
Bingbing learning notes: take you step by step to realize the sequence table