当前位置:网站首页>Llvm - generate local variables
Llvm - generate local variables
2022-04-23 15:04:00 【Mrpre】
Follow the above article :https://wonderful.blog.csdn.net/article/details/106902005
The above article implements the following functions , however Are all pairs of input parameters a The operation of
double myfor(double a)
{
for(i = 0; i < a; i++) {
a = a + 1
}
return a
}
In this case , What we want to achieve is the addition and subtraction of local variables , then return, as follows
double myvar(double a)
{
double b = 0;
for(i = 0; i < a; i++) {
b = a + 1
}
return b
}
After running the source code of this example , It generates llvm ir as follows :
define fastcc double @myvar(double %a) {
myentry:
%cmptmp = fcmp ult double %a, 1.000000e+01
br i1 %cmptmp, label %then, label %else
then: ; preds = %myentry
br label %end
else: ; preds = %myentry
br label %end
end: ; preds = %else, %then
%la.0 = phi double [ 7.000000e+00, %then ], [ 9.000000e+00, %else ]
ret double %la.0
}
1、 Create a function
2、 Use CreateEntryBlockAlloca(TheFunction, "la");
Create a "la" The variable of
3、 Use
Value *StartVal = ConstantFP::get(TheContext, APFloat(0.0)); Builder.CreateStore(innerargs[0], Alloca);
Initialize local variable to 0
Source 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/Instructions.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 "llvm/Transforms/Utils.h"
#include <algorithm>
#include <cassert>
#include <cctype>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <map>
#include <memory>
#include <string>
#include <utility>
#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;
static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
const std::string &VarName) {
IRBuilder<> TmpB(&TheFunction->getEntryBlock(),
TheFunction->getEntryBlock().begin());
return TmpB.CreateAlloca(Type::getDoubleTy(TheContext), 0,
VarName.c_str());
}
/* *double myvar(double a) *{ * double b = 0; * for(i = 0; i < a; i++) { * b = a + 1 * } * return b *} * */
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());
static std::unique_ptr<legacy::FunctionPassManager> TheFPM;
TheFPM = llvm::make_unique<legacy::FunctionPassManager>(TheModule.get());
TheFPM->add(createPromoteMemoryToRegisterPass());
//define the args
vector<std::string> ArgNames;
//mycfor 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, "myvar", 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);
BasicBlock *ThenBB = BasicBlock::Create(TheContext, "then");
BasicBlock *ElseBB = BasicBlock::Create(TheContext, "else");
BasicBlock *EndBB = BasicBlock::Create(TheContext, "end");
Builder.SetInsertPoint(BB);
//create local var la and inited to 0
AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, "la");
Value *StartVal = ConstantFP::get(TheContext, APFloat(0.0));
Builder.CreateStore(innerargs[0], Alloca);
//if a < 0 ThenBB else ElseBB
Value *CondV = Builder.CreateFCmpULT(innerargs[0], ConstantFP::get(TheContext, APFloat(10.0)), "cmptmp");
Builder.CreateCondBr(CondV, ThenBB, ElseBB);
TheFunction->getBasicBlockList().push_back(ThenBB);
Builder.SetInsertPoint(ThenBB);
Value *NextVar = ConstantFP::get(TheContext, APFloat(7.0));
Builder.CreateStore(NextVar, Alloca);
Builder.CreateBr(EndBB);
TheFunction->getBasicBlockList().push_back(ElseBB);
Builder.SetInsertPoint(ElseBB);
NextVar = ConstantFP::get(TheContext, APFloat(9.0));
Builder.CreateStore(NextVar, Alloca);
Builder.CreateBr(EndBB);
TheFunction->getBasicBlockList().push_back(EndBB);
Builder.SetInsertPoint(EndBB);
Builder.CreateRet( Builder.CreateLoad(Alloca, "la") );
TheFunction->setCallingConv(llvm::CallingConv::Fast);
verifyFunction(*TheFunction);
//will opt the code into phi even we haven't use it.
TheFPM->run(*TheFunction);
TheFunction->print(errs());
//using jit to run this code
auto H = TheJIT->addModule(std::move(TheModule));
auto ExprSymbol = TheJIT->findSymbol("myvar");
double (*myvar)(double) = (double (*)(double))(intptr_t)cantFail(ExprSymbol.getAddress());
cout <<myvar(9)<<endl;
}
版权声明
本文为[Mrpre]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204231409588064.html
边栏推荐
- Sword finger offer II 019 Delete at most one character to get palindrome (simple)
- 我的 Raspberry Pi Zero 2W 折腾笔记,记录一些遇到的问题和解决办法
- Leetcode151 - invert words in string - String - simulation
- 1990年1月1日是星期一,定义函数date_to_week(year,month,day),实现功能输入年月日后返回星期几,例如date_to_week(2020,11,1),返回:星期日。 提示:
- 帧同步 实现
- nuxt项目:全局获取process.env信息
- Select receives both normal data and out of band data
- Async void caused the program to crash
- [stc8g2k64s4] introduction of comparator and sample program of comparator power down detection
- LeetCode 练习——396. 旋转函数
猜你喜欢
win10 任务栏通知区图标不见了
[untitled]
Mds55-16-asemi rectifier module mds55-16
博睿数据携手F5共同构建金融科技从代码到用户的全数据链DNA
每日一题-LeetCode396-旋转函数-递推
Introduction to distributed transaction Seata
Explain TCP's three handshakes in detail
Programming philosophy - automatic loading, dependency injection and control inversion
What is the role of the full connection layer?
中富金石财富班29800效果如何?与专业投资者同行让投资更简单
随机推荐
Alexnet model
js——實現點擊複制功能
Leetcode151 - invert words in string - String - simulation
Brute force of DVWA low -- > High
买卖股票的最佳时机系列问题
Leetcode162 - find peak - dichotomy - array
剑指 Offer II 019. 最多删除一个字符得到回文(简单)
Select receives both normal data and out of band data
免费在upic中设置OneDrive或Google Drive作为图床
Is asemi ultrafast recovery diode interchangeable with Schottky diode
Daily question - leetcode396 - rotation function - recursion
Programming philosophy - automatic loading, dependency injection and control inversion
eolink 如何助力远程办公
Contraction mapping theorem
What is the effect of Zhongfu Jinshi wealth class 29800? Walk with professional investors to make investment easier
Detailed explanation of C language knowledge points -- first understanding of C language [1] - vs2022 debugging skills and code practice [1]
2-GO variable operation
【thymeleaf】处理空值和使用安全操作符
For 22 years, you didn't know the file contained vulnerabilities?
UML project example -- UML diagram description of tiktok