[LLVMdev] How to change the type of an Instruction?

John Criswell criswell at illinois.edu
Mon Jan 24 10:24:16 PST 2011


On 1/24/11 12:05 PM, Douglas do Couto Teixeira wrote:
>
>
> On Mon, Jan 24, 2011 at 3:01 PM, Nick Lewycky <nicholas at mxc.ca 
> <mailto:nicholas at mxc.ca>> wrote:
>
>     On 01/24/2011 04:41 AM, Douglas do Couto Teixeira wrote:
>
>         Hi,
>
>         Nick, thanks for the reply.
>         I still have a problem: I only need to "clone" an Instruction,
>         changing
>         its type. That is, I would like to keep all characteristics of
>         the old
>         Instruction and create a new one only with a different type.
>
>
>     Sure, but what about its operands? An "add" instruction must have
>     the same type as its operands, what do you want to do with them? 
>
>
> I also need to convert the type of the operands. But I want to do this 
> when they are created instead of inserting "trunc" instructions before 
> performing an operation. But it seems hard to me.

Actually, I don't think it will be that difficult.  You basically need 
to do the following:

1) Take the backwards, intra-procedural slice of the instruction (i.e., 
find the instructions, operands, the operands' operands, the operands' 
operands' operands, etc.).

2) Visit all of the instructions in the slice and convert them.  You 
want to visit definitions before uses.  To do that,
      a) Make new phi instructions for all phis in the slice.  The 
operands of the phis should be the Undef value.
     b) Use the dominator tree analysis and traverse basic blocks in 
dominator tree order (i.e., start at the top of the dominator tree and 
process each node breadth first).  Convert all of the instructions in 
each basic block (except phis).
     c) Revisit all the phis and plug in their new operands.

3) Delete all the old instructions.

This is a variation of the SSA construction algorithm in Zadeck et. 
al.'s paper (Effeciently Computing Single Static Assignment Form and the 
Control Dependence Graph).

The only tricky part is handling non-instruction operands (e.g., 
function arguments, global variables, etc.).  Some might be trivial to 
convert.  Others may be difficult.  You should look over all the classes 
derived from llvm::Value and decide how difficult it would be to convert 
them.

-- John T.


>     Suppose you're going from a 32-bit add to a 64-bit add, do the old
>     operands get zero extended? Sign extended? You'll need to insert
>     instructions for that (unless they're constants in which case you
>     can use constant expressions). Similarly, what if the old type is
>     a float and the new one is an int? float to signed int, float to
>     unsigned int, or bitcast (only legal sometimes)?
>
>
> I believe I don't need worry about it because I only create smaller 
> instructions. So I never convert a 32-bit instruction in a 64-bit 
> instruction.
>
>
>
>      I am trying
>
>         create a new Instruction thus:
>
>         %3 = add nsw i32 %1, %2 ; <i16> [#uses=2]  //Old Instruction
>
>         Value* Op0 = I->getOperand(0);
>         Value* Op1 = I->getOperand(1);
>         Value* V0 = new Value(Type::getInt16Ty(Op0->getContext()),
>         Op0->getValueID());
>
>
>     Hunh, Value's constructor is protected.
>
>     In any event, Value is pure base. Constructing one this way will
>     never get you what you want. If the ValueID indicates an
>     Instruction, go through Instruction to create one.
>
>
>         Value* V1 = new Value(Type::getInt16Ty(Op1->getContext()),
>         Op1->getValueID());
>         Instruction* newInst = BinaryOperator::CreateNSWAdd(V0, V1,
>         "test");
>         errs() << "NewInst:\n" << *newInst << "\n";
>
>
>         But I get something like this:
>
>         %test = add nsw i16 <badref>, <badref> ; <i16> [#uses=0]
>
>
>     The two instructions V0 and V1 you created were never inserted
>     into the BasicBlock so they can't be numbered, and also they don't
>     have names.
>
>
>         What I am doing wrong?
>
>
>     Suppose that you're going from i32 to i16. Your only choice with
>     that particular pair of types is a truncate. So:
>
>      IRBuilder builder(OldInst);
>      Value *V0 = builder.CreateTrunc(Op0, Type::getInt16Ty());
>      Value *V1 = builder.CreateTrunc(Op1, Type::getInt16Ty());
>      Value *Add = builder.CreateNSWAdd(V0, V1, "test");
>
>     The IRBuilder will take care of the distinction between
>     instructions and constants for you. Note that I have not tested
>     the above code, it may need some fixing before it compiles.
>
>     Nick
>
>
>
>         Best,
>
>         Douglas
>
>         On Fri, Jan 21, 2011 at 8:25 PM, Nick Lewycky
>         <nlewycky at google.com <mailto:nlewycky at google.com>
>         <mailto:nlewycky at google.com <mailto:nlewycky at google.com>>> wrote:
>
>            On 21 January 2011 12:56, Douglas do Couto Teixeira
>         <douglasdocouto at gmail.com <mailto:douglasdocouto at gmail.com>
>         <mailto:douglasdocouto at gmail.com
>         <mailto:douglasdocouto at gmail.com>>> wrote:
>
>                Hello guys,
>
>                I wonder how I can change the type of an integer
>         variable. For
>                instance, given the instruction "%3 = add i32 %1, %2" I
>         would
>                like to alter the instruction to "%3 = add i16 %1, %2".
>         Is there
>                any way to do this?
>
>
>            No. Instead you create a new Instruction, in this case with
>            BinaryOperator::CreateAdd, then
>         OldInst->replaceAllUsesWith(NewInst)
>            to update all the users, then OldInst->eraseFromParent()
>         since it's
>            now dead code.
>
>            Also, all values have types immutably assigned at creation, so
>            you'll need to insert casts (trunc instructions in your
>         case) to
>            cast %1 and %2 from i32 to i16 for the smaller add.
>
>            Nick
>
>
>
>
>         _______________________________________________
>         LLVM Developers mailing list
>         LLVMdev at cs.uiuc.edu <mailto:LLVMdev at cs.uiuc.edu>
>         http://llvm.cs.uiuc.edu
>         http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110124/acf9bc56/attachment.html>


More information about the llvm-dev mailing list