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 ;) 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 http://llvm.org/doxygen/classllvm_1_1Value.html for more information on replaceAllUsesWith(). -- John T.> I hope I could describe my problem well enough ;) > > Regards, > Ralf > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >
On 2009-01-22, at 10:02, Ralf Karrenberg wrote:> 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...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