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/