[LLVMdev] Insert Self Written Function Call from a FunctionPass?
Iaroslav Markov
ymarkov at cs.stonybrook.edu
Fri Aug 24 18:44:13 PDT 2012
I think, your check should get it's value like this:
check = M->getFunction(*name);
if (!check) {
check = Function::Create(
/*Type=*/FuncTy,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/*name, M); // (external, no body)
check->setCallingConv(CallingConv::C);
}
// The following two lines are not necessary
AttrListPtr check_PAL;
check->setAttributes(check_PAL);
Where M is a Module where this function was declared
--
Yaroslav Markov
PhD student in Computer Science
Stony Brook University
________________________________________
From: llvmdev-bounces at cs.uiuc.edu [llvmdev-bounces at cs.uiuc.edu] on behalf of Arnamoy Bhattacharyya [arnamoy at ualberta.ca]
Sent: Friday, August 24, 2012 8:44 PM
To: llvmdev at cs.uiuc.edu
Subject: [LLVMdev] Insert Self Written Function Call from a FunctionPass?
Hello all;
So my goal is to insert some (self-written) function calls in the LLVM IR. I can achieve it with a ModulePass and using the getOrInsertFunction() call. For a ModulePass I follow the steps-
1. Compile the code (in which call instructions are to be inserted) to LLVM IR
2. Compile the file (which contains the *called* external function ) to LLVM IR
3. Link them together and run the transformation pass to insert function calls.
But I have to use LoopInfo pass in my transformation pass as well and for that I have to have a FunctionPass (LoopInfo fails in a ModulePass). So I am trying to follow the above steps for a FunctionPass class (with relevant modifications, as I can't use getOrInsertFunction() now (or can I)). And when I run my optimization pass now (step 3) to instrument, I am getting -
Referencing function in another module!
%1 = call i32 @print(i32 %0)
Broken module found, compilation aborted!
My Code:
#include "llvm/Pass.h"
#include "llvm/Module.h"
#include "llvm/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Type.h"
#include "llvm/Instructions.h"
#include "llvm/Instruction.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/IRBuilder.h"
using namespace llvm;
Module * M;
LLVMContext Context;
Twine * name = new Twine("print");
FunctionType *STy=FunctionType::get(Type::getInt32Ty(Context),Type::getInt32Ty(Context), false);
Function *check = Function::Create(STy, Function::ExternalLinkage, *name ,M);
AllocaInst* count;
namespace{
struct bishe_insert : public FunctionPass{
static char ID;
bishe_insert() : FunctionPass(ID) {}
virtual bool runOnFunction(Function &func)
{
count = new AllocaInst(IntegerType::getInt32Ty(Context), 0, "count");
count->setAlignment(4);
for(Function::iterator F = func.begin(), E = func.end(); F!= E; ++F)
{
if(F == func.begin())
{
bishe_insert::insertOnFirstBlock(F);
}
bishe_insert::runOnBasicBlock(F);
}
return false;
}
/*insert alloca instruction in the start of the first basic block*/
virtual bool insertOnFirstBlock(Function::iterator &BB)
{
for(BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE; ++BI)
{
if(BI == BB->begin())
{
BB->getInstList().insert((Instruction*)BI, count);
break;
}//end of if
}
return true;
}
virtual bool runOnBasicBlock(Function::iterator &BB)
{
for(BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE; ++BI)
{
if(isa<LoadInst>(&(*BI)))
{
LoadInst *CI = dyn_cast<LoadInst>(BI);
/*load count*/
LoadInst* load_count = new LoadInst(count, "", false);
load_count->setAlignment(4);
/*call print(count)*/
CallInst* call_print = CallInst::Create(check, load_count, "");
/*insert the instructions*/
BB->getInstList().insert((Instruction*)CI, load_count);
BB->getInstList().insert((Instruction*)CI, call_print);
}//end of if
}
return true;
}
};
}
char bishe_insert::ID = 0;
static RegisterPass<bishe_insert> X("bishe_insert", "insert print calls");
Thanks a lot;
--
Arnamoy Bhattacharyya
Athabasca Hall 143
Department of Computing Science - University of Alberta
Edmonton, Alberta, Canada, T6G 2E8
587-710-7073
More information about the llvm-dev
mailing list