NEWBIE: deleting Instructions

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.

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

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

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

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

Hi Heiko,

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.