[LLVMdev] Implicit defs

Chris Lattner sabre at nondot.org
Sun Oct 15 19:24:27 PDT 2006


On Sat, 14 Oct 2006, Roman Levenstein wrote:
>> On Sat, 14 Oct 2006, Roman Levenstein wrote:
>>> Is it possible to dynamically define implicit defs for some
>>> instructions?
>>
>> Yes!  This is what explicit operands are :).  Specifically, if you
>> want to
>> vary on a per-opcode basis what registers are used/def'd by the
>> instruction, you can just add those registers as explicit use/def
>> operands
>> in the machine instruction with the physical registers directly
>> filled in.
>
> OK. I have not explained in my first email about DEFs everything I
> wanted, the second one was a bit more specific ;) Of course, I realize
> that I can add explicit DEFs to the machine instruction. But is it
> possible to do it at the higher level, e.g. in the ISelLowering passes,
> where no machine insns are generated yet. Basically, it is currently
> possible at this level to do the mapping of virtual registers for
> parameters to the physical registers, and this can be done without any
> problems. It is usually done in  LowerCALL or something like that. I'd
> like to do the same for return registers at the same place, to keep all
> these related things together and because of certain symmetry of goals.
> But if I would do it as you propose, I'll need to put somewhere else,
> where we can operate at  the MI level, right? So the question is
> actually about possibility of doing it in LowerCALL, where MIs are not
> generated yet.

This is certainly possible, but requires some C++ code.  I assume you have 
something like the PPC backend right now.  If so, you have this in your 
lowering code:

   // Add argument registers to the end of the list so that they are known live
   // into the call.
   for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
     Ops.push_back(DAG.getRegister(RegsToPass[i].first,
                                   RegsToPass[i].second.getValueType()));
   if (InFlag.Val)
     Ops.push_back(InFlag);
   Chain = DAG.getNode(CallOpc, NodeTys, &Ops[0], Ops.size());

This creates a call node with a list of input registers, these are marked 
as uses.  In the PPC backend, this is matched with this pattern:

...
   def BLA : IForm<18, 1, 1, (ops aaddr:$func, variable_ops),
                             "bla $func", BrB, [(PPCcall (i32 imm:$func))]>;
...

The "variable_ops" part of the operation list causes all those registers 
to be added to the node when the isel turns the isel graph into the sched 
graph.  Unfortunately, this will not work with extra definitions (call 
clobbered regs in your case).

Perhaps the easiest way to handle this whole thing is to add an integer 
operand to the DAG call node that indicates the calling convention used. 
You can then use a 'usesCustomDAGSchedInserter' inserter to create the 
machine instr any way you like based on this information.  See the PPC 
backend and how it inserts SELECT_CC_I4, for example.  In your case, you 
would result in one machine instr (instead of the many SELECT_CC_I4 
produces).

> P.S. Chris, have you seen this mail from me on the mailing list?
> http://lists.cs.uiuc.edu/pipermail/llvmdev/2006-October/006937.html
> There was no reply, so I'm not sure if it is because there are no
> comments or may be because it was overseen.

I missed it, I'll respond now.

-Chris

-- 
http://nondot.org/sabre/
http://llvm.org/



More information about the llvm-dev mailing list