<div dir="ltr"><div><div><div>Yes, I'm going to provide it. I believe there must be no additional work on the scheduling phase. It's just some mistake in the instruction definition or DAG.<br><br></div>I create Nodes inside <code>SelectionDAGBuilder::visitIntrinicCall like that:<br>
<br> case Intrinsic::sparc_xmac: {<br> SDVTList nodeTys = DAG.getVTList(MVT::Other, MVT::i32);<br> SDValue Ops[3];<br> Ops[0] = getRoot();<br> Ops[1] = getValue(I.getArgOperand(0));<br> Ops[2] = getValue(I.getArgOperand(1));<br>
SDValue xmacCall = DAG.getNode(ISD::XMAC, sdl, nodeTys, Ops);<br> DAG.setRoot(xmacCall.getValue(0));<br> return nullptr;<br> }<br> case Intrinsic::sparc_srxacc: {<br> SDVTList nodeTys = DAG.getVTList(MVT::Other, MVT::i32);<br>
SDValue Ops[2];<br> Ops[0] = getRoot();<br> Ops[1] = getValue(I.getArgOperand(0));<br> SDValue srCall = DAG.getNode(ISD::SRXACC, sdl, nodeTys, Ops);<br> DAG.setRoot(srCall.getValue(0));<br> return nullptr;<br>
}<br> case Intrinsic::sparc_lrxacc: {<br> SDVTList nodeTys = DAG.getVTList(MVT::Other,MVT::i32);<br> SDValue Ops[1];<br> Ops[0] = getRoot();<br> SDValue lrCall = DAG.getNode(ISD::LRXACC, sdl,<br> nodeTys, Ops);<br>
DAG.setRoot(lrCall.getValue(0));<br> setValue(&I, lrCall.getValue(1));<br> return nullptr;<br> }<br><br>Then, lower them trivially.<br><br>setOperationAction(ISD::LRXACC, MVT::Other, Legal);<br>setOperationAction(ISD::SRXACC, MVT::Other, Legal);<br>
setOperationAction(ISD::XMAC, MVT::Other, Legal);<br><br></code></div><code>Then, just set respective instr opcodes in SparcDAGToDAGISel::Select:<br><br> case ISD::SRXACC: {<br> SDVTList nodeTys = CurDAG->getVTList(MVT::Other);<br>
<br> SDValue Ops[2];<br> Ops[0] = N->getOperand(0);<br> Ops[1] = N->getOperand(1);<br><br> return CurDAG->SelectNodeTo(N, SP::SRXACC, nodeTys, Ops);<br> }<br> case ISD::XMAC: {<br> SDVTList nodeTys = CurDAG->getVTList(MVT::Other);<br>
<br> SDValue Ops[3];<br> Ops[0] = N->getOperand(0);<br> Ops[1] = N->getOperand(1);<br> Ops[2] = N->getOperand(2);<br> <br> return CurDAG->SelectNodeTo(N, SP::XMAC, nodeTys, Ops);<br> }<br> case ISD::LRXACC: {<br>
SDVTList nodeTys = CurDAG->getVTList(MVT::Other, MVT::i32);<br> SDValue Ops[1];<br> Ops[0] = N->getOperand(0);<br> return CurDAG->SelectNodeTo(N, SP::LRXACC, nodeTys, Ops);<br> }<br><br></code></div>
<code>They declared as:<br>def XMAC : F3_1<2, 0b111111,<br> (outs),<br> (ins IntRegs:$rs1, IntRegs:$rs2),<br> "xmac $rs1, $rs2, %xacc",<br> []>;<br>
<br>let rs1 = 0, rd = 1, Uses=[XACC] in<br>def LRXACC : F3_1<2, 0b101110,<br> (outs IntRegs:$rd), (ins),<br> "lrxacc %xacc, $rd", []>;<br><br>let rd = 0, Defs=[XACC] in<br>
def SRXACC : F3_1<2, 0b011101,<br>
(outs), (ins IntRegs:$rs1),<br> "srxacc $rs1, %xacc", []>;<br><br></code><div><div><div>While my register is declared as:<br>def XACC : Ri<88, "XACC">, DwarfRegNum<[88]>;<br>
<br></div><div>Please, note:<br><div>My problem is of self-educational and investigative nature.<br>
</div><div>This instruction srxacc and register xacc are not real.<br></div><div>Produced code aren't supposed to work anywhere.<br></div><div>I just need llc to be able to output assembly file.<br></div>Thanks for your insights.</div>
</div></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">2014-09-01 18:26 GMT+04:00 Sam Parker <span dir="ltr"><<a href="mailto:S.Parker3@lboro.ac.uk" target="_blank">S.Parker3@lboro.ac.uk</a>></span>:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div text="#000000" bgcolor="#FFFFFF">
<div>Hi,<br>
I'm not sure. But in your lowered DAG the chain nodes are the
first operands for you custom nodes, however for the other nodes
the chain is the last operand. I seem to remember that during
targetlowering the chain is the first operand and then it seems to
switch over after ISelDAG, this confused me and may have something
to do with the issue that you are seeing. I really don't know much
about scheduling, do you want to post your instruction definitions
again to see if someone else has some ideas,.<br>
<br>
cheers,<br>
sam<span class="HOEnZb"><font color="#888888"><br>
<pre cols="72">Sam Parker
Research Student
Electronic System Design Group
School of Electronic, Electrical and Systems Engineering
Loughborough University
UK
</pre></font></span><div><div class="h5">
On 01/09/14 14:35, Dmitri Kovalenko wrote:<br>
</div></div></div><div><div class="h5">
<blockquote type="cite">
<div dir="ltr">
<div>
<div>
<div>
<div>
<div>
<div>Before I wrote here, I tried both ways you
decsribed, but none of them has worked out for me.<br>
</div>
With yours sugesstions I was able to move a bit
further with the first approach (when we don't create
regclass and just hard-code it in .td)<br>
<br>
</div>
But I still receive strange errors. I received DAG which
I happy with (DAG here: <a href="http://goo.gl/62tpkk" target="_blank">http://goo.gl/62tpkk</a>),
but everything goes broken on scheduling.<br>
<br>
</div>
I had to chain mine nodes, because otherwise nodes xmac
and srxacc got removed on first combine. But since they
are chained, they have MVT::Other return type, and that
causes strange crash inside func GetCostFor in
ScheduleDAGRRList.cpp:<br>
<br>
Def RegClass = TLI->getRepRegClassFor(VT)->getID();<br>
</div>
When VT is MVT::Other it returns 0x0, what results crash.<br>
<br>
</div>
It got me confused, because reading documentation on CodeGen
gave me an idea, that chain edges are control flow edges, not
data edges. So I don't understand why scheduler tries to
assign some register to it.<br>
<br>
</div>
I'm struggling with this problem way to long for now, and I very
appreciate yours help, Sam.<br>
<div>
<div>
<div>
<div>
<div>
<div><br>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="gmail_extra"><br>
<br>
<div class="gmail_quote">
2014-09-01 1:50 GMT+04:00 Sam Parker <span dir="ltr"><<a href="mailto:S.Parker3@lboro.ac.uk" target="_blank">S.Parker3@lboro.ac.uk</a>></span>:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi,<br>
<br>
Yes, that's what I would do. If you want LLVM and the
register allocator to also know that the instruction
explicitly defines the register, I would designate the
register into it's own register class and have your
instruction write to that class (and there will be only a
single option for RA).<br>
<br>
cheers,<br>
<div>Sam<br>
<br>
Sam Parker<br>
Research Student<br>
Electronic Systems Design Group<br>
</div>
Loughborough University<br>
UK<br>
<br>
________________________________________<br>
From: Dmitri Kovalenko [<a href="mailto:dmitri.a.kovalenko@gmail.com" target="_blank">dmitri.a.kovalenko@gmail.com</a>]<br>
Sent: 31 August 2014 21:53<br>
To: Sam Parker<br>
Cc: <a href="mailto:llvmdev@cs.uiuc.edu" target="_blank">llvmdev@cs.uiuc.edu</a><br>
Subject: Re: [LLVMdev] understanding DAG: node creation<br>
<div><br>
Sam, thanks for your answer.<br>
That's a great suggestion.<br>
<br>
And excuse me for maybe dilettante question:<br>
To hard-code use of the global register means to hard-code
it in the 'asm string' argument of the instruction
definition in the .td file?<br>
<br>
<br>
</div>
2014-09-01 0:44 GMT+04:00 Sam Parker <<a href="mailto:S.Parker3@lboro.ac.uk" target="_blank">S.Parker3@lboro.ac.uk</a><mailto:<a href="mailto:S.Parker3@lboro.ac.uk" target="_blank">S.Parker3@lboro.ac.uk</a>>>:<br>
<div>Hi Dmitri,<br>
<br>
If you have such a simple intrinsic which operates on a
single register, just lower the intrinsic to a target
specific node which is only implemented by a single
instruction. Like you were doing before and by using a
chain operand. Hard code the instruction to use and define
the global register and only pass the instruction the
actual variable argument.<br>
<br>
Hope that helps,<br>
Sam<br>
<br>
Sam Parker<br>
Research Student<br>
Electronic Systems Design Group<br>
School of Electronic, Electrical and Systems Engineering<br>
Loughborough University<br>
<br>
----- Reply message -----<br>
</div>
<div>
<div>From: "Dmitri Kovalenko" <<a href="mailto:dmitri.a.kovalenko@gmail.com" target="_blank">dmitri.a.kovalenko@gmail.com</a><mailto:<a href="mailto:dmitri.a.kovalenko@gmail.com" target="_blank">dmitri.a.kovalenko@gmail.com</a>>><br>
To: <<a href="mailto:llvmdev@cs.uiuc.edu" target="_blank">llvmdev@cs.uiuc.edu</a><mailto:<a href="mailto:llvmdev@cs.uiuc.edu" target="_blank">llvmdev@cs.uiuc.edu</a>>><br>
Subject: [LLVMdev] understanding DAG: node creation<br>
Date: Sat, Aug 30, 2014 22:18<br>
<br>
<br>
I have an intrinsic and it must be lowered to
instruction, which works with fixed register.<br>
So, it takes contents of this register and another
argument as input. After execution, the result of the
instruction is placed into that same fixed register.<br>
<br>
What should I do in
SelectionDAGBuilder::visitIntrinicCall to describe such
behaviour for a SDNode?<br>
<br>
Thank you for the ideas and insights.<br>
<br>
--<br>
Sincerely,<br>
Dmitri Kovalenko<br>
<br>
<br>
<br>
--<br>
Sincerely,<br>
Dmitri Kovalenko</div>
</div>
</blockquote>
</div>
<br>
<br clear="all">
<br>
-- <br>
<div>Sincerely,</div>
<div>Dmitri Kovalenko</div>
</div>
</blockquote>
<br>
</div></div></div>
</blockquote></div><br><br clear="all"><br>-- <br><div>Sincerely,</div><div>Dmitri Kovalenko</div>
</div>