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-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140901/e97a4b6f/attachment.html>
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>
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>
Sam, that helped. Thank you so much. 2014-09-01 19:04 GMT+04:00 Sam Parker <S.Parker3 at lboro.ac.uk>: 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>: > >> 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 > > >-- Sincerely, Dmitri Kovalenko -- Sincerely, Dmitri Kovalenko -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140902/7bf3b7e8/attachment.html>