[LLVMdev] Transforming ConstantExprs to Instructions

Eli Friedman eli.friedman at gmail.com
Tue Jun 17 16:33:49 PDT 2008

On Tue, Jun 17, 2008 at 8:50 AM, Matthijs Kooijman <matthijs at stdin.nl> wrote:
> Hi,
> I've been struggling with constantexprs for a bit. I'm working on a pass that
> transforms global variables to local variables, and in particular the
> GetElementPtrConstantExpr is a bit troublesome. For my transformation to
> properly work, a global value should only be used by Instructions, not by
> ConstantExprs.

This is a relatively difficult transformation to prove safe... you
have to prove that the global is only used by instructions (directly
or indirectly) in one function (or possibly a group of functions with
a single entry point), the address of the global doesn't escape, the
value from the previous call to a function isn't used (by either
ensuring the value is set before used, or ensuring that the value is
set to a known constant when the function returns), and that there
isn't any unsafe recursion.

> I was thinking to add a ConstantExpr::replaceWithInstr() virtual method, which
> translates all of the uses of a constantexpr with their Instruction
> equivalents, whenever possible. Each of the subclasses of ConstantExpr can
> implement this as appropriate. Or, thinking of it, it's probably better to
> have a protected and virtual replaceUseWithInstr method which is called for
> each use by replaceWithInstr().
> Is this a useful addition? Is this a sane approach?

I can't imagine any uses for a method like that besides a pass like
yours.  (This method is essentially the opposite of
ConstantFoldInstruction, and is therefore usually the opposite of what
we want to do.)  Anyone else have any ideas for uses?

That said, it should be pretty simple to write recursively: first,
transform all the constants that use the current constant (this must
be possible due to the constraint that the global is only used by
instructions and transformable constants), second, build the value to
replace the constant (inserted in the entry block immediately after
all the allocas), and third, call replaceAllUsesWith on the constant.

The bulk of the code, of course, is building the value.  In general,
it can take an arbitrary number of instructions to build a constant
(for example, if the constant is a ConstantStruct), so be careful not
to assume that a constant derivation maps to a single instruction.
The case for ConstantExpr is probably the longest, but there aren't
actually that many cases: you just have GetElementPtrInst, CastInst,
CmpInst, SelectInst, InsertValueInst, and ExtractValueInst (assuming
you wouldn't try to prove the legality for anything involving
ptrtoint).  (Okay, that list ended up a bit longer than I expected,
but it still isn't that long.)


More information about the llvm-dev mailing list