当前位置:网站首页>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
边栏推荐
猜你喜欢
你还不知道责任链模式的使用场景吗?
What is the main purpose of PCIe X1 slot?
Tencent has written a few words, Ali has written them all for a month
Detailed explanation of C language knowledge points -- data types and variables [1] - carry counting system
Model location setting in GIS data processing -cesium
Thinkphp5 + data large screen display effect
三、梯度下降求解最小θ
[untitled]
编程哲学——自动加载、依赖注入与控制反转
Set up an AI team in the game world and start the super parametric multi-agent "chaos fight"
随机推荐
Lotus DB design and Implementation - 1 Basic Concepts
How does eolink help telecommuting
分享 20 个不容错过的 ES6 的技巧
Difference between like and regexp
Detailed explanation of C language knowledge points -- data types and variables [1] - carry counting system
SQL中HAVING和WHERE的区别
select 同时接收普通数据 和 带外数据
2-GO variable operation
js——實現點擊複制功能
【thymeleaf】处理空值和使用安全操作符
The art of automation
A series of problems about the best time to buy and sell stocks
ffmpeg安装遇错:nasm/yasm not found or too old. Use --disable-x86asm for a crippled build.
eolink 如何助力遠程辦公
Async keyword
How to design a good API interface?
冰冰学习笔记:一步一步带你实现顺序表
What is the main purpose of PCIe X1 slot?
Frame synchronization implementation
分布式事务Seata介绍