当前位置:网站首页>LLVM - 生成 if-else 以及 PH
LLVM - 生成 if-else 以及 PH
2022-04-23 14:11:00 【Mrpre】
1、生成函数
2、函数有4个basic block,一个entry,一个 if-then 另一个 if-else,最后一个是因为需要使用ph,所以创建一个merge。
3、创建ph来处理if-else,相关概念 http://en.wikipedia.org/wiki/Static_single_assignment_form
4、使用jit运行
5、本例中KaleidoscopeJIT源码在./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;
}
也可以不用ph,因为if else的值比较简单,所以也可以直接使用,Builder.CreateRet(ThenV);或者Builder.CreateRet(ElseV);创建返回值。
#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://wonderful.blog.csdn.net/article/details/106900611
边栏推荐
- Operation instructions of star boundary text automatic translator
- elk安装
- MySQL lock database lock
- MYSQL一种分表实现方案及InnoDB、MyISAM、MRG_MYISAM等各种引擎应用场景介绍
- Introduction to loan market quotation interest rate (LPR) and loan benchmark interest rate
- TUN 设备原理
- 金融行业云迁移实践 平安金融云整合HyperMotion云迁移解决方案,为金融行业客户提供迁移服务
- TLS/SSL 协议详解 (30) SSL中的RSA、DHE、ECDHE、ECDH流程与区别
- SED 学以致用
- tcp_diag 内核相关实现 1 调用层次
猜你喜欢

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

flannel 原理 之 TUN模式

TLS/SSL 协议详解 (28) TLS 1.0、TLS 1.1、TLS 1.2之间的区别

線程組ThreadGroup使用介紹+自定義線程工廠類實現ThreadFactory接口

在Clion中给主函数传入外部参数

XX project structure notes

sar命令详解

线程组ThreadGroup使用介绍+自定义线程工厂类实现ThreadFactory接口

man man随记和crontab的@reboot用法

某政务云项目业务系统迁移调研实践
随机推荐
Operation instructions of star boundary automatic text translator (advanced version)
TUN 设备原理
Algorithem_ReverseLinkedList
JS key value judgment
倒计时1天~2022云容灾产品线上发布会即将开始
TLS/SSL 协议详解 (30) SSL中的RSA、DHE、ECDHE、ECDH流程与区别
After entering the new company, the operation and maintenance engineer can understand the deployment of the system from the following items
js 抛物线运动方法封装
修改Firebase Emulators的默认侦听IP
浅谈skiplist在LevelDB的应用
Date的after时间判断
void*是怎样的存在?
百度笔试2022.4.12+编程题目:简单整数问题
openstack理论知识
JumpServer
Debug on TV screen
操作系统常见面试题目:
grep无法重定向到文件的问题
js 格式化时间
Web page, adaptive, proportional scaling