[LLVMdev] replacing instructions

Ralf Karrenberg Chareos at gmx.de
Thu Jan 22 09:33:22 PST 2009


John Criswell wrote:
> Yes, the Instruction class has a method for doing this (the method is
> technically inherited from the Value class).
>
> Calling the replaceAllUsesWith() method on an Instruction will replace
> every use of the old instruction with the new instruction.  As long as
> the type generated by the old and new instructions is identical (or
> maybe even similar), you shouldn't have any problems.  For example,
> replacing an add instruction that adds two i32's with a call instruction
> that returns an i32 should be as simple as:
>
> Instruction * OldInst = ... ;
> Instruction * NewInst = CallInst::Create (...);
> OldInst->replaceAllUsesWith (NewInst);
>
> This sort of code may not work if OldInst and NewInst are not SSA
> virtual registers of the same type (for example, if OldInst is a pointer
> to an array of i32 and NewInst is a pointer to a structure).  In that
> case, not only must the defining instruction be changed, but the
> instructions using it must be changed as well.  In that case, you will
> need to iterate over the uses of the old instruction and create a new
> instruction for each use, making whatever changes to each use are
> necessary for your transform to work.
>
>   
My problem is exactly that I replace instructions by others of different
type.
I currently do this the following way (in short):

Instruction* X;
for (Instruction::use_iterator U = X->use_begin(); U != X->use_end(); ) {
replaceInstruction(cast<Instruction>(I++));
}

void replaceInstruction(Instruction* I) {
Instruction* newI = generateNewInstructionOfDifferentType(I);
insertNewInstructionBeforeOld(newI, I);
I->uncheckedReplaceAllUsesWith(newInstr);
I->eraseFromParent();
}

that works, but it brings a lot of headache if replaceInstruction() is
recursive or does other nasty things on other instructions that might
also be uses - this can be as easy as a "%Y = mul <type> %X, %X" where I
already have to insert quite some ugly code to prevent the iteration
from segfaulting because Y is referenced twice in the use-list of X.
Modifying the old instruction itself would be much easier...

Cheers,
Ralf



More information about the llvm-dev mailing list