Arnamoy Bhattacharyya
2012-Aug-22 17:35 UTC
[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 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20120822/b2095ec8/attachment.html>
Iaroslav Markov
2012-Aug-25 01:44 UTC
[LLVMdev] Insert Self Written Function Call from a FunctionPass?
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