Carlos Sánchez de La Lama
2011-Oct-21 16:15 UTC
[LLVMdev] Replacing uses within a function
Hi all, I am trying to replace all uses of a value1 *inside of a given function* to use value2. My strategy was to iterate all the basic blocks, again iterating all the instructions in each basic block, and using replaceUsesOfWith(value1, value2) for every instruction. This used to work all right, but now I am finding some problems. There are instructions like this: store i32 0, i32* getelementptr inbounds ([3 x i32]* @value1, i32 0, i32 0) So the store itself is not a user of value1, and the usage does not get replaced. I had a similar problem with PHI nodes recently (http://lists.cs.uiuc.edu/pipermail/llvmdev/2011-October/043954.html) and I was suggested using value1->replaceAllUsesWith. But again I cannot cause I want only to replace uses within a given function. I could iterate value1->use_iterator and replace those which are inside of the desired function, but with cases as the mentioned one it is not so easy to find whether a given value is within a function (the GEP in to store is not inside the function, but used by an instruction that is). Is there an easy way to achieve this? I find it would be better to force all instructions (like the GEP above) to be directly place on the function, and not as operands of other instructions, unless there is a good & known reason not to. BR Carlos
On 10/21/11 11:15 AM, Carlos Sánchez de La Lama wrote:> Hi all, > > I am trying to replace all uses of a value1 *inside of a given function* > to use value2. My strategy was to iterate all the basic blocks, again > iterating all the instructions in each basic block, and using > replaceUsesOfWith(value1, value2) for every instruction. > > This used to work all right, but now I am finding some problems. There > are instructions like this: > > store i32 0, i32* getelementptr inbounds ([3 x i32]* @value1, i32 0, i32 > 0) > > So the store itself is not a user of value1, and the usage does not get > replaced.The issue here is that the store instruction is using a constant expression (ConstExpr) which is using the value that you wish to replace. The GEP that you see here is not a GEP instruction but a GEP constant expression (http://llvm.org/docs/LangRef.html#constantexprs).> > I had a similar problem with PHI nodes recently > (http://lists.cs.uiuc.edu/pipermail/llvmdev/2011-October/043954.html) > and I was suggested using value1->replaceAllUsesWith. But again I cannot > cause I want only to replace uses within a given function. > > I could iterate value1->use_iterator and replace those which are inside > of the desired function, but with cases as the mentioned one it is not > so easy to find whether a given value is within a function (the GEP in > to store is not inside the function, but used by an instruction that > is). > > Is there an easy way to achieve this? I find it would be better to force > all instructions (like the GEP above) to be directly place on the > function, and not as operands of other instructions, unless there is a > good& known reason not to.There's a few options. First, you could use something like the BreakConstantGEP pass from SAFECode to convert constant expression GEPs into GEP instructions. Then your old approach will work properly. However, the speed of the code may suffer because GEP constant expressions are replaced with constant values during code generation while GEP instructions most likely will not. You could, of course, modify the code to selectively convert GEP constant expressions used within the function that you care about. A second approach is to simply search for constant expressions that are used within the function you care about and replace them with a new constant expression that uses your new value. I think constants are unique in LLVM, so you can't just call ConstantExpr::replaceUsesOfWith(); you'll need to create a new constant expression that is identical to the old one but using the new value, and then replace the specific use of the old constant expression with the new one that you've created. -- John T.> > BR > > Carlos > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Carlos Sánchez de La Lama
2011-Oct-21 17:03 UTC
[LLVMdev] Replacing uses within a function
Hi John,> > store i32 0, i32* getelementptr inbounds ([3 x i32]* @value1, i32 0, i32 > > 0) > > The issue here is that the store instruction is using a constant > expression (ConstExpr) which is using the value that you wish to > replace. The GEP that you see here is not a GEP instruction but a GEP > constant expression (http://llvm.org/docs/LangRef.html#constantexprs).Ok, got the point.> First, you could use something like the BreakConstantGEP pass from > SAFECode to convert constant expression GEPs into GEP instructions. > Then your old approach will work properly. However, the speed of the > code may suffer because GEP constant expressions are replaced with > constant values during code generation while GEP instructions most > likely will not. You could, of course, modify the code to selectively > convert GEP constant expressions used within the function that you care > about.As you say this looks like some de-optimization, I prefer constants to remain constants for more efficient code.> A second approach is to simply search for constant expressions that are > used within the function you care about and replace them with a new > constant expression that uses your new value. I think constants are > unique in LLVM, so you can't just call > ConstantExpr::replaceUsesOfWith(); you'll need to create a new constant > expression that is identical to the old one but using the new value, and > then replace the specific use of the old constant expression with the > new one that you've created.Actually I have found ConstantExpr::replaceUsesOfWithOnConstant on the API, which does the trick. Now my only problem is how to find all the ConstantExprs within a function (as I guess ConstantExprs can have more ConstantExprs as operands) but that is doable. You made it pretty clear, thank you :) Carlos