[LLVMdev] understanding DAG: node creation
Dmitri Kovalenko
dmitri.a.kovalenko at gmail.com
Mon Sep 1 07:39:48 PDT 2014
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.
I create Nodes inside SelectionDAGBuilder::visitIntrinicCall like that:
case Intrinsic::sparc_xmac: {
SDVTList nodeTys = DAG.getVTList(MVT::Other, MVT::i32);
SDValue Ops[3];
Ops[0] = getRoot();
Ops[1] = getValue(I.getArgOperand(0));
Ops[2] = getValue(I.getArgOperand(1));
SDValue xmacCall = DAG.getNode(ISD::XMAC, sdl, nodeTys, Ops);
DAG.setRoot(xmacCall.getValue(0));
return nullptr;
}
case Intrinsic::sparc_srxacc: {
SDVTList nodeTys = DAG.getVTList(MVT::Other, MVT::i32);
SDValue Ops[2];
Ops[0] = getRoot();
Ops[1] = getValue(I.getArgOperand(0));
SDValue srCall = DAG.getNode(ISD::SRXACC, sdl, nodeTys, Ops);
DAG.setRoot(srCall.getValue(0));
return nullptr;
}
case Intrinsic::sparc_lrxacc: {
SDVTList nodeTys = DAG.getVTList(MVT::Other,MVT::i32);
SDValue Ops[1];
Ops[0] = getRoot();
SDValue lrCall = DAG.getNode(ISD::LRXACC, sdl,
nodeTys, Ops);
DAG.setRoot(lrCall.getValue(0));
setValue(&I, lrCall.getValue(1));
return nullptr;
}
Then, lower them trivially.
setOperationAction(ISD::LRXACC, MVT::Other, Legal);
setOperationAction(ISD::SRXACC, MVT::Other, Legal);
setOperationAction(ISD::XMAC, MVT::Other, Legal);
Then, just set respective instr opcodes in SparcDAGToDAGISel::Select:
case ISD::SRXACC: {
SDVTList nodeTys = CurDAG->getVTList(MVT::Other);
SDValue Ops[2];
Ops[0] = N->getOperand(0);
Ops[1] = N->getOperand(1);
return CurDAG->SelectNodeTo(N, SP::SRXACC, nodeTys, Ops);
}
case ISD::XMAC: {
SDVTList nodeTys = CurDAG->getVTList(MVT::Other);
SDValue Ops[3];
Ops[0] = N->getOperand(0);
Ops[1] = N->getOperand(1);
Ops[2] = N->getOperand(2);
return CurDAG->SelectNodeTo(N, SP::XMAC, nodeTys, Ops);
}
case ISD::LRXACC: {
SDVTList nodeTys = CurDAG->getVTList(MVT::Other, MVT::i32);
SDValue Ops[1];
Ops[0] = N->getOperand(0);
return CurDAG->SelectNodeTo(N, SP::LRXACC, nodeTys, Ops);
}
They declared as:
def XMAC : F3_1<2, 0b111111,
(outs),
(ins IntRegs:$rs1, IntRegs:$rs2),
"xmac $rs1, $rs2, %xacc",
[]>;
let rs1 = 0, rd = 1, Uses=[XACC] in
def LRXACC : F3_1<2, 0b101110,
(outs IntRegs:$rd), (ins),
"lrxacc %xacc, $rd", []>;
let rd = 0, Defs=[XACC] in
def SRXACC : F3_1<2, 0b011101,
(outs), (ins IntRegs:$rs1),
"srxacc $rs1, %xacc", []>;
While my register is declared as:
def XACC : Ri<88, "XACC">, DwarfRegNum<[88]>;
Please, note:
My problem is of self-educational and investigative nature.
This instruction srxacc and register xacc are not real.
Produced code aren't supposed to work anywhere.
I just need llc to be able to output assembly file.
Thanks for your insights.
2014-09-01 18:26 GMT+04:00 Sam Parker <S.Parker3 at lboro.ac.uk>:
> Hi,
> 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,.
>
> cheers,
> sam
>
> Sam Parker
> Research Student
> Electronic System Design Group
> School of Electronic, Electrical and Systems Engineering
> Loughborough University
> UK
>
> On 01/09/14 14:35, Dmitri Kovalenko wrote:
>
> Before I wrote here, I tried both ways you decsribed, but none of them
> has worked out for me.
> 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)
>
> But I still receive strange errors. I received DAG which I happy with
> (DAG here: http://goo.gl/62tpkk), but everything goes broken on
> scheduling.
>
> 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:
>
> Def RegClass = TLI->getRepRegClassFor(VT)->getID();
> When VT is MVT::Other it returns 0x0, what results crash.
>
> 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.
>
> I'm struggling with this problem way to long for now, and I very
> appreciate yours help, Sam.
>
>
>
> 2014-09-01 1:50 GMT+04:00 Sam Parker <S.Parker3 at lboro.ac.uk>:
>
>> Hi,
>>
>> 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).
>>
>> cheers,
>> Sam
>>
>> Sam Parker
>> Research Student
>> Electronic Systems Design Group
>> Loughborough University
>> UK
>>
>> ________________________________________
>> From: Dmitri Kovalenko [dmitri.a.kovalenko at gmail.com]
>> Sent: 31 August 2014 21:53
>> To: Sam Parker
>> Cc: llvmdev at cs.uiuc.edu
>> Subject: Re: [LLVMdev] understanding DAG: node creation
>>
>> Sam, thanks for your answer.
>> That's a great suggestion.
>>
>> And excuse me for maybe dilettante question:
>> 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?
>>
>>
>> 2014-09-01 0:44 GMT+04:00 Sam Parker <S.Parker3 at lboro.ac.uk<mailto:
>> S.Parker3 at lboro.ac.uk>>:
>> Hi Dmitri,
>>
>> 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.
>>
>> Hope that helps,
>> Sam
>>
>> Sam Parker
>> Research Student
>> Electronic Systems Design Group
>> School of Electronic, Electrical and Systems Engineering
>> Loughborough University
>>
>> ----- Reply message -----
>> From: "Dmitri Kovalenko" <dmitri.a.kovalenko at gmail.com<mailto:
>> dmitri.a.kovalenko at gmail.com>>
>> To: <llvmdev at cs.uiuc.edu<mailto:llvmdev at cs.uiuc.edu>>
>> Subject: [LLVMdev] understanding DAG: node creation
>> Date: Sat, Aug 30, 2014 22:18
>>
>>
>> I have an intrinsic and it must be lowered to instruction, which works
>> with fixed register.
>> 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.
>>
>> What should I do in SelectionDAGBuilder::visitIntrinicCall to describe
>> such behaviour for a SDNode?
>>
>> Thank you for the ideas and insights.
>>
>> --
>> Sincerely,
>> Dmitri Kovalenko
>>
>>
>>
>> --
>> Sincerely,
>> Dmitri Kovalenko
>>
>
>
>
> --
> Sincerely,
> Dmitri Kovalenko
>
>
>
--
Sincerely,
Dmitri Kovalenko
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140901/3c6c5419/attachment.html>
More information about the llvm-dev
mailing list