(original) (raw)

Most instructions produced by isel use a vreg(virtual register) as their inputs and destination. The register allocator is responsible for assigning these virtual registers to specific physical registers later. Each virtual register is assigned a specific register class and the register allocator has the freedom to allocate a physical register for it within the class. The CopyToReg and CopyFromReg nodes exist to place constraints on the register allocator.

Most CopyToReg nodes will appear on the return value of a function or just before a call to another function. These are used to ensure that things are placed in the right registers to match the calling convention. It appears that your calling convention requires result to be returned in R5 so the CopyToReg was created to make sure the return value is in R5.

Most CopyFromReg nodes appear on the inputs to a function where the physical register represent the input registers defined by the calling convention.

The register allocator will see the CopyToReg after the DAG has been converted to machine instructions at that point it will be TargetOpcode::COPY with a physical register output and a virtual register input. In your case the virtual register input comes from the output of your LI instruction. If the register allocator is able to it will allocate this virtual register to the same physical register as the output of the COPY as it did in your case. But in more complicated functions it might not be able to do that and will instead create a register to register move to get the register into the right place.

\~Craig

On Sun, Nov 5, 2017 at 5:23 PM, Robert Baruch <robert.c.baruch@gmail.com> wrote:
Hmm, well that seems to have worked, but I'm a little suspicious. This is my instruction def:

// Load Immediate (LI)
def LI : IImmReg<0x010, (outs REG16:$dst), (ins i16imm:$src),
\[(set REG16:$dst, imm:$src)\], "LI\\t$dst, src">;</font></div><div><br></div><div><br></div><div>Therestofthedebugoutput:</div><div><br></div><div><spanclass=""><div><fontface="monospace">Selecting:t3:ch,glue=CopyToRegt0,Register:i16src">;</font></div><div><br></div><div><br></div><div>The rest of the debug output:</div><div><br></div><div><span class=""><div><font face="monospace">Selecting: t3: ch,glue = CopyToReg t0, Register:i16 %R5, Constant:i16<127></font></div></span><span class=""><div><font face="monospace">Selecting: t2: i16 = Register %R5</font></div><div><font face="monospace">Selecting: t1: i16 = Constant<127></font></div><div><font face="monospace"><br></font></div><div><font face="monospace">ISEL: Starting pattern match on root node: t1: i16 = Constant<127></font></div></span><div><font face="monospace"> Initial Opcode index to 16</font></div><div><span style="font-family:monospace">Creating constant: t5: i16 = TargetConstant<127></span><br></div><div><font face="monospace"> Morphed node: t1: i16 = LI TargetConstant:i16<127></font></div><div><font face="monospace">ISEL: Match complete!</font></div></div><div><font face="monospace"><br></font></div><div><font face="monospace"><div>Selected selection DAG: BB#0 'my\_func:entry'</div><div>SelectionDAG has 6 nodes:</div><div> t0: ch = EntryToken</div><div> t1: i16 = LI TargetConstant:i16<127></div><div> t3: ch,glue = CopyToReg t0, Register:i16 %R5, t1</div><div> t4: ch,glue = RTWP Register:i16 %R5, t3</div><div><br></div></font></div><div>So at this point, t3 is still a CopyToReg with R5 and another node that is an LI with the constant. That doesn't make sense to me. Shouldn't the LI node end up being a parent of R5 and the constant?</div><div><br></div><div>The phases proceed, and this makes even less sense:</div><div><br></div><div><div><font face="monospace"># Machine code for function my\_func: IsSSA, TracksLiveness</font></div><div><font face="monospace"><br></font></div><div><font face="monospace">BB#0: derived from LLVM BB %entry</font></div><div><font face="monospace"><span style="white-space:pre-wrap"> </span>%vreg0<def> = LI 127; REG16:%vreg0</font></div><div><font face="monospace"><span style="white-space:pre-wrap"> </span>%R5<def> = COPY %vreg0; REG16:%vreg0</font></div><div><font face="monospace"><span style="white-space:pre-wrap"> </span>RTWP %R5</font></div><div><font face="monospace"><br></font></div><div><font face="monospace"># End machine code for function my\_func.</font></div></div><div><br></div><div>I'm not complaining too hard, though, because in the end I get the assembly output I expect:</div><div><br></div><div><div><font face="monospace"># BB#0: # %entry</font></div><div><font face="monospace"><span style="white-space:pre-wrap"> </span>LI<span style="white-space:pre-wrap"> </span>src">;</font></div><div><br></div><div><br></div><div>Therestofthedebugoutput:</div><div><br></div><div><spanclass=""><div><fontface="monospace">Selecting:t3:ch,glue=CopyToRegt0,Register:i16r5, 127
RTWP

What I'm complaining about is that I still don't know how the DAG nodes work. Here's the -view-sched-dags output:


dags.jpg

I just don't understand the LI node. From a dataflow perspective, LI does depend on the constant, and not on the register R5\. Is this just how LLVM represents data stores? With a CopyToReg node?

There's something that I'm missing, but I don't know what it is :(

--Rob

On Sun, Nov 5, 2017 at 1:22 AM 陳韋任 <chenwj.cs97g@g2.nctu.edu.tw> wrote:
Try match your instruction with (set REG16:$dst, i16imm:$src). Just give it a shot. :)

2017-11-05 12:56 GMT+08:00 Robert Baruch via llvm-dev <llvm-dev@lists.llvm.org>:
Well, that's the thing: I thought that was CopyToReg. I don't know what the name of the node is to load one value into a register, so I don't know how to construct such a pattern.

On Sat, Nov 4, 2017 at 9:23 PM Craig Topper <craig.topper@gmail.com> wrote:
Do you have a pattern for loading an i16 immediate into a 16-bit register?

\~Craig

On Sat, Nov 4, 2017 at 8:00 PM, Robert Baruch <robert.c.baruch@gmail.com> wrote:
Hmm, okay. Then what's the problem being reported here? I'm not sure what I'm supposed to do with "LLVM ERROR: Cannot select: t1: i16 = Constant<127>".BTW, the function is:

; ModuleID = 'return.c'
source\_filename = "return.c"
target datalayout = "E-m:e-p:16:16:16-i1:16:16-i8:16:16-i16:16:16-i32:16:16-i64:16:16-S16-n16"
target triple = "tms9900"

; Function Attrs: noinline nounwind optnone
define signext i16 @my\_func() #0 {
entry:
ret i16 127
}

------- debug output --------

Optimized legalized selection DAG: BB#0 'my\_func:entry'
SelectionDAG has 5 nodes:
t0: ch = EntryToken
t3: ch,glue = CopyToReg t0, Register:i16 %R5, Constant:i16<127>
t4: ch = TMS9900ISD::Ret t3, Register:i16 %R5, t3:1

===== Instruction selection begins: BB#0 'entry'
Selecting: t4: ch = TMS9900ISD::Ret t3, Register:i16 %R5, t3:1

ISEL: Starting pattern match on root node: t4: ch = TMS9900ISD::Ret t3, Register:i16 %R5, t3:1

Morphed node: t4: ch,glue = Retr Register:i16 %R5, t3

ISEL: Match complete!
Selecting: t3: ch,glue = CopyToReg t0, Register:i16 %R5, Constant:i16<127>

Selecting: t2: i16 = Register %R5

Selecting: t1: i16 = Constant<127>

ISEL: Starting pattern match on root node: t1: i16 = Constant<127>

Initial Opcode index to 0
Match failed at index 0
LLVM ERROR: Cannot select: t1: i16 = Constant<127>
In function: my\_func


On Sat, Nov 4, 2017 at 7:22 PM Craig Topper <craig.topper@gmail.com> wrote:
CopyToReg is not handle by patterns. It should be passed through isel unchanged. It’s part of a special list of ISD opcodes that don’t change in SelectioDAGISel::SelectCodeCommon

It will then be turned into a TargetOpcode::COPY in InstrEmitter::EmitSpecialNode when the DAG is turned into MachineInstrs.

On Sat, Nov 4, 2017 at 7:02 PM Robert Baruch via llvm-dev <llvm-dev@lists.llvm.org> wrote:
So there's a DAG that looks like this in the debug output:

Selecting: t3: ch,glue = CopyToReg t0, Register:i16 %R5, Constant:i16<127>

In the instruction selection phase, what pattern would that match? I've constructed this so far:

(??? REG16:$dst, i16imm:$src)

but the problem is, I can't determine what to use as ???. There is an ISD::CopyToReg enum value, but I don't know how that translates to the string to use in the pattern.

And more generally, how do I find out from a DAG diagram like the ones output by -view-isel-dags which node type corresponds to which pattern string?

Thanks,

--Rob

\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
LLVM Developers mailing list
llvm-dev@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
--
\~Craig


\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
LLVM Developers mailing list
llvm-dev@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev




--
Wei-Ren Chen (陳韋任)
Homepage: https://people.cs.nctu.edu.tw/\~chenwj