[LLVMdev] NEWBIE: deleting Instructions

Reid Spencer rspencer at reidspencer.com
Fri Mar 23 09:59:00 PDT 2007


Hi Heiko,

On Fri, 2007-03-23 at 02:00 -0700, Heiko Sturzrehm wrote:
> Hello,
> 
> i just tried to write some passes and in one of them i want to delete a call
> Instruction.
> I can identify the specific Instruction without a problem, but when i put
> the delete operation in the code i always get a error message while running
> opt. I already tried to rename my pass, but without any change.

Probably because you aren't using eraseFromParent (see below).

> 
> Another question i have is: why do i always get the "opt: CommandLine
> Error:"  how can i fix it?

This is a known problem. See PR780. From that bug:
Duplicate registration of command line options and passes occurs when
the
loadable module has linked in something from LLVM that is already linked into
the executable in which it is loaded. In general, loadable modules should not
link in anything from LLVM, just use things from LLVM.

> 
> Thanks for any help.
> 
> Ciao Heiko
> 
> Console OUTPUT:
> opt -load /home/sturzrehmh/llvm/llvm-1.9/Release/lib/TESTXYZ.so -TESTXYZ <
> test.bc > test.bc2
> opt: CommandLine Error: Argument 'track-memory' defined more than once!
> opt: CommandLine Error: Argument 'info-output-file' defined more than once!
> opt: CommandLine Error: Argument 'help' defined more than once!
> opt: CommandLine Error: Argument 'help-hidden' defined more than once!
> opt: CommandLine Error: Argument 'version' defined more than once!
> opt: Pass.cpp:346: void llvm::RegisterPassBase::registerPass(): Assertion
> `PassInfoMap->find(PIObj.getTypeInfo()) == PassInfoMap->end() && "Pass
> already registered!"' failed.
> Aborted

The problem is that you have linked into TESTXYZ.so things that are
already in the opt executable. Change the link line of your module so
that it doesn't link these things into the module.

> 
> PASS:
> virtual bool runOnFunction(Function &F) 
> {
>   bool change= false;
> 
>   Function* func = &F;
> 		
>   for(Function::iterator it = func->begin(), ite = func ->end(); it!=ite ;
> ++it)
>   {
>     BasicBlock* blk =it;
>     User* u;
>     Value* val;
>     std::string s1;
> 				
>     for (BasicBlock::iterator i = blk->begin(), e = blk->end(); i != e ; 
> ++i)
>     {
>       if(i->getOpcode()==33)

This will break in 2.0 because the instruction numbers are different.
You'd be better off testing against Instruction::Call (#include
"llvm/Instruction.h"). The instructions are defined in
include/llvm/Instruction.def

>       {
>         u = i;
>         val=u->getOperand(0);
>         s1 = val->getName();
>         if(s1 == "_Z7startv")
>         {
> //HERE is the problem							
>           blk->getInstList().erase(i);

Tyr this:
            i->replaceAllUsesWith(X)
            i->eraseFromParent();

If there are no uses of "i" (I haven't checked) then you can forgo the
call to replaceAllUsesWith. Otherwise, you need to come up with a
replacement (X) so that anything using the call instruction still
references something.

Reid.

> 
>           change=true;
>         }
>       }
>     }
>   }
>   return change;
> }




More information about the llvm-dev mailing list