当前位置:网站首页>LLVM - 生成局部变量
LLVM - 生成局部变量
2022-04-23 14:11:00 【Mrpre】
接上面一篇:https://wonderful.blog.csdn.net/article/details/106902005
上面一篇实现了如下函数,但是 都是对入参a的操作
double myfor(double a)
{
for(i = 0; i < a; i++) {
a = a + 1
}
return a
}
本例中,我们希望实现是局部变量的加减,然后return,如下
double myvar(double a)
{
double b = 0;
for(i = 0; i < a; i++) {
b = a + 1
}
return b
}
运行本例源码后,它生成的llvm ir如下:
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、创建函数
2、使用 CreateEntryBlockAlloca(TheFunction, "la");创建名为"la"的变量
3、使用
Value *StartVal = ConstantFP::get(TheContext, APFloat(0.0)); Builder.CreateStore(innerargs[0], Alloca);
初始化局部变量为0
源码:
#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://wonderful.blog.csdn.net/article/details/106902346
边栏推荐
猜你喜欢

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

MySQL-InnoDB-事务

多云数据流转?云上容灾?年前最后的价值内容分享

关于UDP接收icmp端口不可达(port unreachable)

MYSQL一种分表实现方案及InnoDB、MyISAM、MRG_MYISAM等各种引擎应用场景介绍

After entering the new company, the operation and maintenance engineer can understand the deployment of the system from the following items

Use the executors class to quickly create a thread pool

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

云迁移的六大场景

进入新公司,运维工程师从下面这几项了解系统的部署
随机推荐
SED 学以致用
bc的用法
Recyclerview advanced use (II) - simple implementation of vertical drag and drop sorting
进入新公司,运维工程师从下面这几项了解系统的部署
如何轻松做好一个项目
man man随记和crontab的@reboot用法
json date时间日期格式化
JS key value judgment
剑指offer刷题(1)--面向华为
浅谈skiplist在LevelDB的应用
获取线程返回值Future接口与FutureTask类使用介绍
编译Openssl
API Gateway/API 网关(四) - Kong的使用 - 集成Jwt和熔断插件
線程組ThreadGroup使用介紹+自定義線程工廠類實現ThreadFactory接口
Some experience of using dialogfragment and anti stepping pit experience (getactivity and getdialog are empty, cancelable is invalid, etc.)
krpano全景之vtour文件夹和tour
Web page, adaptive, proportional scaling
VMware installation 64 bit XP Chinese tutorial
Flop effect
处理 mkdir:无法创建目录“aaa“:只读文件系统