当前位置:网站首页>Llvm - generate if else and pH
Llvm - generate if else and pH
2022-04-23 15:04:00 【Mrpre】
1、 Generating function
2、 Function has 4 individual basic block, One entry, One if-then the other one if-else, The last one is because it needs to be used ph, So create a merge.
3、 establish ph To deal with it if-else, Relevant concepts http://en.wikipedia.org/wiki/Static_single_assignment_form
4、 Use jit function
5、 In this case KaleidoscopeJIT The source code in ./llvm-8.0.1.src/examples/Kaleidoscope/include/KaleidoscopeJIT.h
#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 mycmp(double a, double b) *{ * if (a < b) { * return 1; * * } else { * return 2; * } * *} * */
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;
//mycmp has 2 args
ArgNames.push_back(string("a"));
ArgNames.push_back(string("b"));
//make the 2 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, "mycmp", 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);
}
//4 blocks
//fitst is function's entry
BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
//generate llvm function body:control-flow
//At least three blocks(MergeBB is not necessary)
//if's cond if(a > b)
//the if expression belongs to BB
//BB:
// if xxx then
// then-logic
// else
// else-logic
Builder.SetInsertPoint(BB);
Value *cond = Builder.CreateFCmpULT(innerargs[0], innerargs[1], "cmptmp");
//then block
BasicBlock *ThenBB = BasicBlock::Create(TheContext, "then", TheFunction);
//else block
BasicBlock *ElseBB = BasicBlock::Create(TheContext, "else");
//after control block
BasicBlock *MergeBB = BasicBlock::Create(TheContext, "ifcont");
//join three block
Builder.CreateCondBr(cond, ThenBB, ElseBB);
//then expression
//then:
// then-logic = ThenV
// goto MergeBB
Builder.SetInsertPoint(ThenBB);
Value *ThenV = ConstantFP::get(TheContext, APFloat(1.0));
//Builder.CreateRet(ThenV);
//We also could just CreateRet not CreateBr.
Builder.CreateBr(MergeBB);
//ElseBB has not been inserted because ElseBB doesn't
//created by Thefunction
TheFunction->getBasicBlockList().push_back(ElseBB);
//else expression and goto MergeBB
//else:
// else-logic = ElseV
// goto MergeBB
Builder.SetInsertPoint(ElseBB);
Value *ElseV = ConstantFP::get(TheContext, APFloat(2.0));
//Builder.CreateRet(ElseV);
Builder.CreateBr(MergeBB);
//MergeBB has not been inserted
TheFunction->getBasicBlockList().push_back(MergeBB);
//newly created code will go into the “merge” block
//ifcont
// ph
Builder.SetInsertPoint(MergeBB);
//need to construct MergeBB
PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, "iftmp");
// if from ThenBB then ph is ThenV
// if from ElseBB then ph is ElseV
PN->addIncoming(ThenV, ThenBB);
PN->addIncoming(ElseV, ElseBB);
Builder.CreateRet(PN);
//print LLVM IR
TheFunction->print(errs());
//using jit to run this code
auto H = TheJIT->addModule(std::move(TheModule));
auto ExprSymbol = TheJIT->findSymbol("mycmp");
double (*mycmp)(double, double) = (double (*)(double, double))(intptr_t)cantFail(ExprSymbol.getAddress());
cout <<mycmp(30, 40)<<endl;
}
It can also be done without ph, because if else The value of is relatively simple , So it can also be used directly ,Builder.CreateRet(ThenV);
perhaps Builder.CreateRet(ElseV);
Create return value .
#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 mycmp(double a, double b) *{ * if (a < b) { * return 1; * * } else { * return 2; * } * *} * */
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;
//mycmp has 2 args
ArgNames.push_back(string("a"));
ArgNames.push_back(string("b"));
//make the 2 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, "mycmp", 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);
}
//4 blocks
BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
//generate llvm function body:control-flow
//At least three blocks(MergeBB is not necessary)
//if's cond if(a > b)
//the if expression belongs to BB
Builder.SetInsertPoint(BB);
Value *cond = Builder.CreateFCmpULT(innerargs[0], innerargs[1], "cmptmp");
//then block
BasicBlock *ThenBB = BasicBlock::Create(TheContext, "then", TheFunction);
//else block
BasicBlock *ElseBB = BasicBlock::Create(TheContext, "else", TheFunction);
//after control block
BasicBlock *MergeBB = BasicBlock::Create(TheContext, "ifcont");
//join three block
Builder.CreateCondBr(cond, ThenBB, ElseBB);
//then expression and goto MergeBB
Builder.SetInsertPoint(ThenBB);
Value *ThenV = ConstantFP::get(TheContext, APFloat(1.0));
Builder.CreateRet(ThenV);
//We also could just CreateRet not CreateBr.
//Builder.CreateBr(MergeBB);
//ElseBB has been inserted
//TheFunction->getBasicBlockList().push_back(ElseBB);
//else expression and goto MergeBB
Builder.SetInsertPoint(ElseBB);
Value *ElseV = ConstantFP::get(TheContext, APFloat(2.0));
Builder.CreateRet(ElseV);
//Builder.CreateBr(MergeBB);
//MergeBB has not been inserted
//TheFunction->getBasicBlockList().push_back(MergeBB);
//newly created code will go into the “merge” block
//Builder.SetInsertPoint(MergeBB);
//need to construct MergeBB
//PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, "iftmp");
//PN->addIncoming(ThenV, ThenBB);
//PN->addIncoming(ElseV, ElseBB);
//Builder.CreateRet(PN);
//print LLVM IR
TheFunction->print(errs());
//using jit to run this code
auto H = TheJIT->addModule(std::move(TheModule));
auto ExprSymbol = TheJIT->findSymbol("mycmp");
double (*mycmp)(double, double) = (double (*)(double, double))(intptr_t)cantFail(ExprSymbol.getAddress());
cout <<mycmp(30, 40)<<endl;
}
版权声明
本文为[Mrpre]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204231409588146.html
边栏推荐
- Thinkphp5 + data large screen display effect
- Alexnet model
- 1-初识Go语言
- LeetCode 练习——396. 旋转函数
- My raspberry PI zero 2W tossing notes record some problems encountered and solutions
- Introduction to distributed transaction Seata
- Detailed comparison between asemi three-phase rectifier bridge and single-phase rectifier bridge
- Detailed explanation of C language knowledge points - data types and variables [2] - integer variables and constants [1]
- Achievements in science and Technology (21)
- Set up an AI team in the game world and start the super parametric multi-agent "chaos fight"
猜你喜欢
Leetcode149 - maximum number of points on a line - Math - hash table
Don't you know the usage scenario of the responsibility chain model?
Swift protocol Association object resource name management multithreading GCD delay once
UML学习_day2
What is the main purpose of PCIe X1 slot?
LeetCode153-寻找旋转排序数组中的最小值-数组-二分查找
分享 20 个不容错过的 ES6 的技巧
QT Detailed explanation of pro file
capacitance
Do (local scope), initializer, memory conflict, swift pointer, inout, unsafepointer, unsafebitcast, success
随机推荐
Leetcode exercise - 396 Rotation function
OPPO数据湖统一存储技术实践
How to design a good API interface?
Is asemi ultrafast recovery diode interchangeable with Schottky diode
One of the advanced applications of I / O reuse: non blocking connect -- implemented using select (or poll)
Leetcode153 - find the minimum value in the rotation sort array - array - binary search
Provided by Chengdu control panel design_ It's detailed_ Introduction to the definition, compilation and quotation of single chip microcomputer program header file
在游戏世界组建一支AI团队,超参数的多智能体「大乱斗」开赛
如何设计一个良好的API接口?
Set onedrive or Google drive as a drawing bed in upic for free
Resolve the conflict between computed attribute and input blur event
[proteus simulation] automatic range (range < 10V) switching digital voltmeter
[jz46 translate numbers into strings]
Achievements in science and Technology (21)
Async void caused the program to crash
帧同步 实现
买卖股票的最佳时机系列问题
How to write the keywords in the cover and title? As we media, why is there no video playback
Advanced version of array simulation queue - ring queue (real queuing)
Leetcode162 - find peak - dichotomy - array