当前位置:网站首页>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
边栏推荐
- Algorithem_ReverseLinkedList
- Gif to still image processing
- Introduction to the use of countdownlatch and cyclicbarrier for inter thread control
- TLS/SSL 协议详解 (30) SSL中的RSA、DHE、ECDHE、ECDH流程与区别
- Quickly understand the three ways of thread implementation
- 浅谈skiplist在LevelDB的应用
- grep无法重定向到文件的问题
- json date时间日期格式化
- Nacos作为配置中心(四) 使用Demo
- 如何轻松做好一个项目
猜你喜欢
困扰多年的系统调研问题有自动化采集工具了,还是开源免费的
Recyclerview advanced use (I) - simple implementation of sideslip deletion
Thread group ThreadGroup uses introduction + custom thread factory class to implement threadfactory interface
微信小程序客服接入,实现发送和接收消息
KVM学习资源
Tongxin UOS php7 2.3 upgrade to php7.0 two point two four
setcontext getcontext makecontext swapcontext
VMware installation 64 bit XP Chinese tutorial
MySQL数据库讲解(九)
线程组ThreadGroup使用介绍+自定义线程工厂类实现ThreadFactory接口
随机推荐
Get the thread return value. Introduction to the use of future interface and futuretask class
错误:无法远程查找到密钥 “428F7ECC7117F726“
MySQL数据库讲解(八)
mysql锁数据库锁
krpano全景之vtour文件夹和tour
Operation instructions of star boundary automatic text translator (advanced version)
Web page, adaptive, proportional scaling
云容灾是什么意思?云容灾和传统容灾的区别?
使用开源调研工具Prophet是一种什么体验?
Five ways of using synchronized to remove clouds and fog are introduced
Some experience of using dialogfragment and anti stepping pit experience (getactivity and getdialog are empty, cancelable is invalid, etc.)
倒计时1天~2022云容灾产品线上发布会即将开始
KVM学习资源
redis数据库讲解(四)主从复制、哨兵、Cluster群集
OpenStack如何跨版本升级
Flop effect
API Gateway/API 网关(三) - Kong的使用 - 限流rate limiting(redis)
Installation and use of postman pit
利用json-server在本地创建服务器请求
Date的after时间判断