[LLVMdev] understanding DAG: node creation

Sam Parker S.Parker3 at lboro.ac.uk
Mon Sep 1 08:04:18 PDT 2014


Hi,

I would still switch chain operands to be the last ones and ensure that 
lxacc result type is (MVT::i32, MVT::other) and not the other way around.

good luck,
sam

Sam Parker
Research Student
Electronic System Design Group
School of Electronic, Electrical and Systems Engineering
Loughborough University
UK

On 01/09/14 15:39, Dmitri Kovalenko wrote:
> 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 
> <mailto: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
>>     <mailto: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
>>         <mailto:dmitri.a.kovalenko at gmail.com>]
>>         Sent: 31 August 2014 21:53
>>         To: Sam Parker
>>         Cc: llvmdev at cs.uiuc.edu <mailto: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><mailto: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><mailto: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><mailto: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/fa922212/attachment.html>


More information about the llvm-dev mailing list