<div dir="ltr"><br><div class="gmail_quote"><br><div dir="ltr">Sam, that helped. Thank you so much.<br></div><div class="gmail_extra"><br><br><div class="gmail_quote">2014-09-01 19:04 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>:<div>
<div class="h5"><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>
      <br>
      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.<br>
      <br>
      good luck,<div><br>
      sam<br>
      <br>
      <pre cols="72">Sam Parker
Research Student
Electronic System Design Group
School of Electronic, Electrical and Systems Engineering
Loughborough University
UK
</pre></div><div><div>
      On 01/09/14 15:39, Dmitri Kovalenko wrote:<br>
    </div></div></div><div><div>
    <blockquote type="cite">
      
      <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><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> On 01/09/14 14:35, Dmitri Kovalenko
                    wrote:<br>
                  </div>
                </div>
              </div>
              <div>
                <div>
                  <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>
    </blockquote>
    <br>
  </div></div></div>

</blockquote></div></div></div><span class="HOEnZb"><font color="#888888"><br><br clear="all"><br>-- <br><div>Sincerely,</div><div>Dmitri Kovalenko</div>
</font></span></div>
</div><br><br clear="all"><br>-- <br><div>Sincerely,</div><div>Dmitri Kovalenko</div>
</div>