当前位置:网站首页>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
边栏推荐
- like和regexp差别
- How do I open the win10 startup folder?
- 如何设计一个良好的API接口?
- Alexnet model
- Lotus DB design and Implementation - 1 Basic Concepts
- Flink datastream type system typeinformation
- The art of automation
- Detailed comparison between asemi three-phase rectifier bridge and single-phase rectifier bridge
- Advanced application of I / O multiplexing: Processing TCP and UDP services at the same time
- Async void caused the program to crash
猜你喜欢
UML project example -- UML diagram description of tiktok
Progress in the treatment of depression
3、 Gradient descent solution θ
Leetcode167 - sum of two numbers II - double pointer - bisection - array - Search
Redis主从同步
win10 任务栏通知区图标不见了
How does eolink help telecommuting
Introduction to Arduino for esp8266 serial port function
Detailed explanation of C language knowledge points - data types and variables [2] - integer variables and constants [1]
Comment eolink facilite le télétravail
随机推荐
Leetcode167 - sum of two numbers II - double pointer - bisection - array - Search
MySQL error packet out of order
Leetcode151 - invert words in string - String - simulation
Explanation and example application of the principle of logistic regression in machine learning
UML project example -- UML diagram description of tiktok
Leetcode162 - find peak - dichotomy - array
LeetCode151-颠倒字符串中的单词-字符串-模拟
Pnpm installation and use
Leetcode exercise - 396 Rotation function
Thinkphp5 + data large screen display effect
3、 Gradient descent solution θ
Leetcode149 - maximum number of points on a line - Math - hash table
填充每个节点的下一个右侧节点指针 II [经典层次遍历 | 视为链表 ]
Role of asemi rectifier module mdq100-16 in intelligent switching power supply
Redis主从同步
Five data types of redis
Introduction to distributed transaction Seata
async void 导致程序崩溃
JUC learning record (2022.4.22)
Don't you know the usage scenario of the responsibility chain model?