[LLVMdev] Insert Self Written Function Call from a FunctionPass?

Arnamoy Bhattacharyya arnamoy at ualberta.ca
Wed Aug 22 10:35:40 PDT 2012


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>


More information about the llvm-dev mailing list