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

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 (LLVM Language Reference Manual — LLVM 18.0.0git documentation).

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.

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 (LLVM Language Reference Manual — LLVM 18.0.0git documentation).

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 :slight_smile:

Carlos