在我的LLVM IR code添加一个函数调用 [英] Adding a function call in my IR code in llvm
问题描述
您可以给我一个例子,如何添加功能的一个简单的通话
Can you give me an example ,how to add a simple call of a function
foo(x);
在我的IR code。与我的LLVM通?
on my IR code with my pass in llvm?
推荐答案
一个简单的方法就是学会是使用 ELLCC 与输出选项的为 LLVM C ++ API code
A simple way is to learn is to use ELLCC with Output Options as LLVM C++ API Code.
两个重要注意事项:
-
确认
富
的定义可用;否则,你需要
首先定义它。通常情况下,你需要通过使用来获取原型getOrInsertFunction
,然后用IRBuilder
插入身体
对于该功能。
Make sure
foo
's definition is available; otherwise you need to define it firstly. Typically you need to get the prototype by usinggetOrInsertFunction
and then useIRBuilder
to insert the body for the function.
在 CallInst
,一个简单的方法是使用 CallInst * IRBuilder ::的createCall(价值*,数组引用<值*>中const的绳索和放大器;)
Create the CallInst
, an easy way is to use
CallInst*IRBuilder::CreateCall(Value*, ArrayRef<Value*>, const Twine &)
.
下面是我对llvm3.4之前写了一个段;希望它能帮助。
Here is a segment I wrote before for llvm3.4; hope it can help.
#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 IR code添加一个函数调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!