Hello everyone,
is there any way to replace an instruction inside LLVM that is more
elegant than creating a new one, replacing uses and deleting the old one
if I only want to modify the type? It is generally not a big deal, but
the issue gets really messy if I am in the middle of iterating over uses
and start deleting some of them...
I hope I could describe my problem well enough ![:wink: :wink:](https://emoji.discourse-cdn.com/google/wink.png?v=12)
Regards,
Ralf
Ralf Karrenberg wrote:
Hello everyone,
is there any way to replace an instruction inside LLVM that is more
elegant than creating a new one, replacing uses and deleting the old one
if I only want to modify the type? It is generally not a big deal, but
the issue gets really messy if I am in the middle of iterating over uses
and start deleting some of them...
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.
See LLVM: llvm::Value Class Reference for more information
on replaceAllUsesWith().
-- John T.
Hi Ralf,
There is not. LLVM Values are of immutable type. There is a method, Value::replaceAllUsesWith(), to do the replacement for you, however.
http://llvm.org/doxygen/classllvm_1_1Value.html#3ab5fc45117b450e8bb04e564cb6e5f2
— Gordon
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