[LLVMdev] Re: LLVMdev digest, Vol 1 #292 - 4 msgs

Chris Lattner sabre at nondot.org
Fri May 21 16:54:01 PDT 2004


On Fri, 21 May 2004, Zhang Qiuyu wrote:

> Hi,
>
> Following TraceBasicBlocks.cpp, I modified the code as below and could
> insert instruction or function I need into anywhere in Module. But it
> works well without BB->getInstList().push_back(InstrCall), and if I add
> the BB->getInstList().push_back() following new CallInst(), I got error
> information when runing opt. What is the reason for it? And is it
> necessary to add push_back() after new CallInst ? And if I used those
> two instructions , it works well. Thanks
>
> Instruction *InstrCall = new CallInst (InstrFn, Args , "");
> BB->getInstList().insert(InsertPos,InstrCall);

The key idea is that you need to put the instruction you create into a
basic block exactly once.  There are multiple ways of doing this: you can
either pass the instruction to insert before into the CallInst ctor as the
last argument, you can use the push_back method to add it to the basic
block, or you can use the insert method to insert it at an arbitrary
point.  If you use these calls:

 Instruction *InstrCall = new CallInst (InstrFn, Args , "");
 BB->getInstList().insert(InsertPos,InstrCall);

You create an instruction, which is not in a basic block, then you put it
into a basic block.  If you attempt to put it into another basic block, or
even the same one again, you'll get an assertion telling you this is
illegal.

I would recommend you use the CallInst ctor version that autoinserts, just
to make the code simpler.  This would change the two lines above to:

 Instruction *InstrCall = new CallInst (InstrFn, Args , "", InsertPos);

-Chris

>
>
> Error inforamtion:
> %opt -load ../../lib/Debug/libcntPass.so -cntPass<insert.bc -f -o i.bc
>
>
> BB name : entry
> opt: SymbolTableListTraitsImpl.h:53: void llvm::SymbolTableListTraits<ValueSubClass, ItemParentClass, SymTabClass, SubClass>::addNodeToList(ValueSubClass*) [with ValueSubClass = llvm::Instruction, ItemParentClass = llvm::BasicBlock, SymTabClass = llvm::Function, SubClass = llvm::ilist_traits<llvm::Instruction>]: Assertion `V->getParent() == 0 && "Value already in a container!!"' failed.
> opt[0x860c190]
> opt[0x860c39c]
> opt[0x42028c48]
> opt(abort+0x199)[0x4202a019]
> opt[0x42021cd6]
> opt(llvm::SymbolTableListTraits<llvm::Instruction, llvm::BasicBlock, llvm::Function, llvm::ilist_traits<llvm::Instruction> >::addNodeToList(llvm::Instruction*)+0x30)[0x85afb1e]
> opt(llvm::iplist<llvm::Instruction, llvm::ilist_traits<llvm::Instruction> >::insert(llvm::ilist_iterator<llvm::Instruction>,
> llvm::Instruction*)+0x8c)[0x839c3f4]
> opt(llvm::iplist<llvm::Instruction, llvm::ilist_traits<llvm::Instruction> >::push_back(llvm::Instruction*)+0x2b)[0x839bbab]
> ../../lib/Debug/libcntPass.so[0x400168bb]
> ../../lib/Debug/libcntPass.so((anonymous namespace)::cntPass::run(llvm::Module&)+0x102)[0x400169fc]
> opt(llvm::PassManagerTraits<llvm::Module>::runPass(llvm::Pass*, llvm::Module*)+0x1b)[0x85e6c0f]
> opt(llvm::PassManagerT<llvm::Module>::runOnUnit(llvm::Module*)+0x5e4)[0x85e0626]
> opt(llvm::PassManagerTraits<llvm::Module>::run(llvm::Module&)+0x1b)[0x85dfc8d]
> opt(llvm::PassManager::run(llvm::Module&)+0x1f)[0x8595fb1]
> opt(main+0x97f)[0x838273b]
> opt(__libc_start_main+0xa4)[0x420158d4]
> opt(dlopen+0x41)[0x8381d2d]
> Aborted
>
>
> Source code:
>
> static void InsertInstrumentationCall( BasicBlock *BB,
>            const std::string FnName,
>            unsigned BBnumber){
>   Module &M = *BB->getParent()->getParent();
>   Function *InstrFn = M.getOrInsertFunction (FnName , Type::VoidTy, Type::UIntTy,0);
>   std::vector<Value *> Args(1);
>   Args[0] = ConstantUInt::get(Type::UIntTy, BBnumber);
>
>   // Insert Call after first instruction
>   BasicBlock :: iterator InsertPos = BB->begin();
>
>   Instruction *InstrCall = new CallInst (InstrFn, Args , "",InsertPos);
>   BB->getInstList().push_back(InstrCall);
>   //BB->getInstList().insert(InsertPos,InstrCall);
>
>
> }
>
>
>
>
>
>
> > Hi llvmer,
> >
> > I am trying to learn how to use llvm. My question is
> > described as the following,
> > there has already a testcase code, and I get bytecode
> > by using llvmgcc. What I want to do is to insert a
> > call funcation into each basic block, which is for
> > statistic some information.
> > 1) I implement call function in another c/cpp file and
> > can I insert the external call function to existed
> > bytecode ? if it is valid. Can you give me a simple
> > example to show how to do it or just give me a url
> > which can show how to do it?
> >
> > 2) If I'd like to insert the function in the same
> > bytecode, how to do it?
> >
> > 3) for opt commamnd, there have -trace -tracem options
> > ,how can I see the detailed direction to use it.
> >
> > I went through a LowerInvoke.cpp and EdgeCode.cpp file
> > which have examples to do what I want. Although I can
> > learn the main flow how to insert a call funcation or
> > instruction, but I still cannot implement it. Shame.
> > Another thing is that I am not sure the method I used
> > is correct or not? Can you give me some suggestion?
> >
> >
> > Thanks in advance for any response.
> >
> > --fengy--
> >
> > The following code is what I do
> > #include "llvm/Pass.h"
> > #include "llvm/Function.h"
> > #include "llvm/BasicBlock.h"
> > #include "llvm/Instruction.h"
> > #include "llvm/iOther.h"
> >
> >
> > namespace llvm {
> >
> >
> >   struct cntPass : public FunctionPass{
> >     virtual bool runOnFunction(Function &F){
> >       std::cerr <<"funtion name : "<<
> > F.getName()<<"\n";
> >       for(Function::iterator BB = F.begin(),E=F.end();
> > BB != E;++BB){
> > std::cerr<< "BB name : "<<BB->getName()<<"\n";
> >       // here, the problem is how can I get external
> > function pointer.
> >       file://Instruction *callInst = new
> > CallInst(pCallfunction, "","");
> >       file://BB->getInstList().push_back(callInst);
> >       file://BB->getInstList().insert(callInst);
> >       }
> >
> >       return false;
> >     }
> >     // can I  insert print() function?
> >     void print(){
> >       printf("Insert test\n");
> >     }
> >   };
> >   RegisterOpt<cntPass> X("cntPass", "insert printf
> > function");
> > }
> >
> >
> >
> > Message: 3
> > Date: Wed, 19 May 2004 15:31:03 -0500
> > From: "Brian R. Gaeke" <gaeke at uiuc.edu>
> > To: llvmdev at cs.uiuc.edu
> > Subject: Re: [LLVMdev] Question about insert function or instruction.
> > Reply-To: llvmdev at cs.uiuc.edu
> >
> > > What I want to do is to insert a call funcation into each basic
> > > block, which is for statistic some information.
> >
> > I recommend that you look at the various pieces of code under
> > llvm/lib/Transforms/Instrumentation, e.g. BlockProfiling.cpp and
> > TraceBasicBlocks.cpp. They do essentially the same thing as you are
> > trying to do.
> >
> > > 1) I implement call function in another c/cpp file and
> > > can I insert the external call function to existed
> > > bytecode ? if it is valid. Can you give me a simple
> > > example to show how to do it or just give me a url
> > > which can show how to do it?
> >
> > Yes; in the case of BlockProfiling, it calls into the library defined
> > in llvm/runtime/libprofile, which is linked against the resulting LLVM
> > binary.
> >
> > > 2) If I'd like to insert the function in the same
> > > bytecode, how to do it?
> >
> > In the above example, you would generate a bytecode version of
> > libprofile using the standard Makefile, then link it with the bytecode
> > version of your program using gccld or llvm-link.
> >
> > > 3) for opt commamnd, there have -trace -tracem options
> > > ,how can I see the detailed direction to use it.
> >
> > Short answer:
> >
> > 1. Compile the program in question to bytecode using llvmgcc.
> > Assume the result is
> >
> > 2. Run the bytecode of the program through opt -tracem, and then
> > generate C code for the result.
> >  % opt -tracem bytecode.llvm.bc | llc -f -march=c -o bytecode.tracem.cbe.c
> >
> > 3. Compile the C code with tracing instrumentation using gcc.
> >  % gcc -o bytecode.tracem.cbe bytecode.tracem.cbe.c
> > You may have to link it with the libtrace library provided in
> > llvm/runtime/libtrace, in addition to any other libraries that
> > the program needs.
> >
> > >       // here, the problem is how can I get external
> > > function pointer.
> >
> > Look at the 'getOrInsertFunction' method of class llvm::Module.
> >
> > >       file://Instruction *callInst = new
> > > CallInst(pCallfunction, "","");
> > >       file://BB->getInstList().push_back(callInst);
> >
> > This is basically OK.
> >
> > >       file://BB->getInstList().insert(callInst);
> >
> > This second insert is not necessary.
> >
> > -Brian Gaeke
> >
> > --
> > gaeke at uiuc.edu
> >
> > --__--__--
> >
> > Message: 4
> > Date: Wed, 19 May 2004 15:36:10 -0500
> > From: "Brian R. Gaeke" <gaeke at uiuc.edu>
> > To: llvmdev at cs.uiuc.edu
> > Subject: Re: [LLVMdev] Question about insert function or instruction.
> > Reply-To: llvmdev at cs.uiuc.edu
> >
> > > 1. Compile the program in question to bytecode using llvmgcc.
> > > Assume the result is
> >
> > I meant to say "Assume the result is in the bytecode file named
> > bytecode.llvm.bc".
> >
> > > 2. Run the bytecode of the program through opt -tracem, and then
> > > generate C code for the result.
> > >  % opt -tracem bytecode.llvm.bc | llc -f -march=c -o bytecode.tracem.cbe.c
> >
> > -Brian
> >
> > --
> > gaeke at uiuc.edu
> >
> >
> > --__--__--
> >
> > _______________________________________________
> > LLVMdev mailing list
> > LLVMdev at cs.uiuc.edu
> > http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev
> >
> >
> > End of LLVMdev Digest
> >
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev
>

-Chris

-- 
http://llvm.cs.uiuc.edu/
http://www.nondot.org/~sabre/Projects/




More information about the llvm-dev mailing list