C++ 在llvm中的我的IR代码中添加函数调用
你能给我举个例子,说明如何添加一个简单的函数调用,比如C++ 在llvm中的我的IR代码中添加函数调用,c++,c,clang,llvm,llvm-clang,C++,C,Clang,Llvm,Llvm Clang,你能给我举个例子,说明如何添加一个简单的函数调用,比如 foo(x); < P>一个简单的方法是学习用输出选项作为 LLVM C++ API代码>/P> 两个关键注意事项: 确保foo的定义可用;否则你需要 首先对其进行界定。通常,您需要使用 getOrInsertFunction,然后使用IRBuilder插入主体 对于函数 创建CallInst,一个简单的方法是使用 CallInst*IRBuilder::CreateCall(Value*、ArrayRef、const-Twine&
foo(x);
<我的IR代码中,我的LIVLM中的P< > < P>一个简单的方法是学习用输出选项作为<强> LLVM C++ API代码>/P> 两个关键注意事项:
foo
的定义可用;否则你需要
首先对其进行界定。通常,您需要使用
getOrInsertFunction
,然后使用IRBuilder
插入主体
对于函数CallInst
,一个简单的方法是使用
CallInst*IRBuilder::CreateCall(Value*、ArrayRef、const-Twine&)
#include "llvm/Analysis/Verifier.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/TypeBuilder.h"
#include "llvm/IR/IRBuilder.h"
using namespace llvm;
Constant* geti8StrVal(Module& M, char const* str, Twine const& name) {
LLVMContext& ctx = getGlobalContext();
Constant* strConstant = ConstantDataArray::getString(ctx, str);
GlobalVariable* GVStr =
new GlobalVariable(M, strConstant->getType(), true,
GlobalValue::InternalLinkage, strConstant, name);
Constant* zero = Constant::getNullValue(IntegerType::getInt32Ty(ctx));
Constant* indices[] = {zero, zero};
Constant* strVal = ConstantExpr::getGetElementPtr(GVStr, indices, true);
return strVal;
}
static Function *printf_prototype(LLVMContext &ctx, Module *mod) {
FunctionType *printf_type =
TypeBuilder<int(char *, ...), false>::get(getGlobalContext());
Function *func = cast<Function>(mod->getOrInsertFunction(
"printf", printf_type,
AttributeSet().addAttribute(mod->getContext(), 1U, Attribute::NoAlias)));
return func;
}
static Function *main_prototype(LLVMContext &ctx, Module *mod) {
FunctionType *foo_type =
TypeBuilder<int(int, char **), false>::get(getGlobalContext());
Function *func = cast<Function>(mod->getOrInsertFunction("main", foo_type));
/// func->setLinkage(GlobalValue::PrivateLinkage);
return func;
}
int main(int argc, char **argv) {
InitializeNativeTarget();
LLVMContext &ctx = getGlobalContext();
Module *module = new Module("example", ctx);
/// auto module = std::make_unique<Module>("example", ctx);
IRBuilder<> builder(ctx);
module->setDataLayout(
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
"i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
"a0:0:64-s0:64:64-f80:128:128");
module->setTargetTriple("x86_64-unknown-linux-gnu");
//
// extern void printf(const char *fmt, ...);
//
Function *printf_func = printf_prototype(ctx, module);
//
// int foo(void)
// {
Function *main_fn = main_prototype(ctx, module);
BasicBlock *block = BasicBlock::Create(ctx, "", main_fn, 0);
builder.SetInsertPoint(block);
//
// int32_t temp = 15 + ...
//
Constant *left = ConstantInt::get(ctx, APInt(32, 15));
AllocaInst *allocaInst =
builder.CreateAlloca(TypeBuilder<int, false>::get(getGlobalContext()));
SmallVector<Value *, 4> addsVect;
for (Argument &arg : main_fn->getArgumentList()) {
addsVect.push_back(&arg);
}
builder.CreateStore(addsVect[0], allocaInst);
LoadInst *loadInst = builder.CreateLoad(allocaInst);
Value *add = builder.CreateAdd(left, loadInst);
/// add->getType()->dump();
/// errs() << "\n";
//
// printf("%d\n", temp);
//
Constant *nullValue = Constant::getNullValue(add->getType());
///
builder.CreateICmpEQ(add, nullValue);
builder.CreateICmpNE(add, nullValue);
///
Value *cmpResult = builder.CreateICmpUGT(add, nullValue);
builder.CreateICmpUGE(add, nullValue);
builder.CreateICmpULT(add, nullValue);
builder.CreateICmpULE(add, nullValue);
///
builder.CreateICmpSGT(add, nullValue);
builder.CreateICmpSGE(add, nullValue);
builder.CreateICmpSLT(add, nullValue);
builder.CreateICmpSLE(add, nullValue);
///
BasicBlock *br_true = BasicBlock::Create(ctx, "br_true", main_fn, 0);
BasicBlock *br_false = BasicBlock::Create(ctx, "br_false", main_fn, 0);
builder.CreateCondBr(cmpResult, br_true, br_false);
builder.SetInsertPoint(br_false);
builder.CreateCall2(printf_func, utils::geti8StrVal(*module, "%d\n"), add);
SmallVector<Value *, 4> assertArgs;
assertArgs.push_back(utils::geti8StrVal(*module, "__assert_fail"));
assertArgs.push_back(utils::geti8StrVal(*module, __FILE__));
/// assertArgs.push_back(
/// ConstantInt::get(TypeBuilder<int, false>::get(ctx), __LINE__, false));
assertArgs.push_back(add);
assertArgs.push_back(utils::geti8StrVal(*module, __FUNCTION__));
Function *assertFunc = utils::getFn_assert(*module);
/// errs() << *assertFunc;
builder.CreateCall(assertFunc, assertArgs);
/// builder.CreateBr(br_true);
ConstantInt *zero = ConstantInt::get(IntegerType::getInt32Ty(ctx), 0);
builder.CreateRet(zero);
//
// return 0;
// }
//
builder.SetInsertPoint(br_true);
builder.CreateRet(zero);
}
#包括“llvm/Analysis/Verifier.h”
#包括“llvm/IR/DerivedTypes.h”
#包括“llvm/IR/LLVMContext.h”
#包括“llvm/IR/Module.h”
#包括“llvm/IR/TypeBuilder.h”
#包括“llvm/IR/IRBuilder.h”
使用名称空间llvm;
常量*geti8StrVal(模块和M、字符常量*str、绳线常量和名称){
LLVMContext&ctx=getGlobalContext();
常量*strConstant=ConstantDataArray::getString(ctx,str);
全球可变*GVStr=
新的全局变量(M,strConstant->getType(),true,
全局值::内部链接,strConstant,name);
常量*zero=Constant::getNullValue(IntegerType::getInt32Ty(ctx));
常数*索引[]={0,0};
常量*strVal=ConstantExpr::getElementPtr(GVStr,index,true);
返回strVal;
}
静态函数*printf_原型(LLVMContext&ctx,模块*mod){
函数类型*printf_类型=
TypeBuilder::get(getGlobalContext());
函数*func=cast(mod->getOrInsertFunction(
“printf”,printf_类型,
AttributeSet().addAttribute(mod->getContext(),1U,Attribute::NoAlias));
返回函数;
}
静态函数*main_原型(LLVMContext&ctx,模块*mod){
函数类型*foo_类型=
TypeBuilder::get(getGlobalContext());
函数*func=cast(mod->getOrInsertFunction(“main”,foo_类型));
///func->setLinkage(全局值::私有链接);
返回函数;
}
int main(int argc,字符**argv){
InitializeEnableTarget();
LLVMContext&ctx=getGlobalContext();
模块*模块=新模块(“示例”,ctx);
///自动模块=标准::使_唯一(“示例”,ctx);
IRBuilder(ctx);
模块->设置数据布局(
“e-p:64:64:64-i1:8:8-i8:8-i16:16:16-i32:32——”
“i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128——”
“a0:0:64-s0:64:64-f80:128:128”);
模块->setTargetTriple(“x86_64-unknown-linux-gnu”);
//
//外部无效打印F(常量字符*fmt,…);
//
函数*printf_func=printf_原型(ctx,模块);
//
//int foo(无效)
// {
功能*main\u fn=主\u原型(ctx,模块);
BasicBlock*block=BasicBlock::Create(ctx,“,main_fn,0);
生成器。设置插入点(块);
//
//int32温度=15+。。。
//
常量*left=ConstantInt::get(ctx,APInt(32,15));
AllocaInst*AllocaInst=
CreateAlloca(TypeBuilder::get(getGlobalContext());
小矢量加法器;
对于(参数&arg:main\u fn->getArgumentList()){
addsVect.push_back(&arg);
}
builder.CreateStore(addsVect[0],allocaInst);
LoadInst*LoadInst=builder.CreateLoad(allocaInst);
Value*add=builder.CreateAdd(左,loadInst);
///添加->getType()->dump();
///errs()getType());
///
CreateICmpEQ(add,nullValue);
CreateICmpNE(add,null值);
///
Value*cmpResult=builder.CreateICmpUGT(add,nullValue);
CreateICmpUGE(add,null值);
CreateICmpULT(add,null值);
CreateICmpULE(add,null值);
///
CreateICmpSGT(add,null值);
CreateICmpSGE(add,nullValue);
CreateICmpSLT(add,nullValue);
CreateICmpSLE(add,null值);
///
基本块*br\u true=BasicBlock::Create(ctx,“br\u true”,main\u fn,0);
基本块*br\u false=BasicBlock::Create(ctx,“br\u false”,main\u fn,0);
CreateCondBr(cmpResult,br\u true,br\u false);
builder.SetInsertPoint(br_false);
CreateCall2(printf_func,utils::geti8StrVal(*模块,“%d\n”),add);
小向量资产;
assertArgs.push_back(utils::geti8StrVal(*模块,“u断言失败”);
assertArgs.push_back(utils::geti8StrVal(*模块,u文件_u));
///assertArgs.push_返回(
///康斯坦丁::get(TypeBuilder::get(ctx),_行,false));
assertArgs.推回(添加);
assertArgs.push_back(utils::geti8StrVal(*模块,__函数__));
函数*assertFunc=utils::getFn\u assert(*模块);
///errs()应该可以工作