<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Sep 28, 2016 at 12:54 PM, Krzysztof Parzyszek <span dir="ltr"><<a target="_blank" href="mailto:kparzysz@codeaurora.org">kparzysz@codeaurora.org</a>></span> wrote:<br><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote"><span class="gmail-">On 9/28/2016 2:44 PM, Phil Tomson wrote:<br>
<blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">
And map it to a load.idx instruction with the following semantics:<br>
load.idx r1,r2,r3,SIZE        r1 <- mem[r2 + (r3 << sizeof(operand))]<br>
<br>
That somehow the pattern matching dag fragment would need to be<br>
something like I had in ADDR_SHLI definition:<br>
  def ADDR_SHLI : Addr< 2, "SelectAddrShlImm",<br>
                      (ops GPRC:$base, ( shl GPRC:$offsetreg, (i64 3))) >;<br>
<br>
<br>
Now If I have to create a subclass of Operand and define it's<br>
EncoderMethod in C++, does that mean the pattern matching (matching the<br>
shift left and add) now happens on the C++ side as well?<br>
</blockquote>
<br></span>
Actually the EncoderMethod is probably not needed for this case. I thought you had a scaled immediate that needs to be shifted during encoding.<br>
<br>
Regarding pattern matching in the C++ code---yes, that's what ComplexPattern implies. The function whose name you provide will be used to match the DAG and generate the output.<br>
<br>
The instruction definition would have 3 inputs: register, register and immediate:<br>
<br>
def ADDR_SHLI: Addr<3, "SelectAddrShlImm",<br>
    (ops GPRC:$base, GPRC:$offsetreg, i64imm:$shift)>;<br>
<br>
The matching function would then need to match DAG and generate these 3 values if the match succeeded.</blockquote><div><br></div><div>What I'm finding is that the matching function for 3 arguments (the SelectAddrShlImm) is never tried for this particular case. This one is tried:<br><br>   def ADDR_RR : Addr< 2, "SelectAddrRegReg",<br>                      (ops GPRC:$base, GPRC:$offsetreg) >;<br><br><br></div><div>I've added some debugging statements to show some of the output from llc with -debug below:<br><br>          0x2385bb0: i64,ch = load 0x2356e90, 0x2388b60, 0x2385880<LD8[getelementptr ([0 x i64] addrspace(2)* @SpM_use_row, i64 0, i64 undef)(addrspace=2)](tbaa=<0x2335188>)> [ORD=2] [ID=12]<br><br>          0x2385990: i64 = Constant<3> [ID=2]<br><br>        0x2385dd0: i64 = shl 0x2385bb0, 0x2385990 [ORD=3] [ID=13]<br><br>      0x2385ee0: i64 = add 0x2386650, 0x2385dd0 [ORD=3] [ID=14]<br><br>      0x2385880: <multiple use><br>    <b>0x2386540</b>: i32,ch = load 0x2356e90, 0x2385ee0, 0x2385880<LD4[%arrayidx16(addrspace=4)](align=8)(tbaa=<0x2335188>)> [ORD=4] [ID=15]<br><br>  0x2386320: ch,glue = CopyToReg 0x2356e90, 0x2386210, 0x2386540 [ORD=6]<br><br>    0x2386210: <multiple use><br>    0x2386320: <multiple use><br>    0x2386320: <multiple use><br>  0x2386430: ch = RET 0x2386210, 0x2386320, 0x2386320:1 [ORD=6]<br><br><br>SelectAddrRegReg called: <b>0x2386540:</b> i32,ch = load 0x2356e90, 0x2385ee0, 0x2385880<LD4[%arrayidx16(addrspace=4)](align=8)(tbaa=<0x2335188>)> [ORD=4] [ID=15]<br><br>SelectAddrRegRegCommon called:<br>  Morphed node: 0x2386540: i32,ch = LOADI32_RR 0x2386650, 0x2385dd0, 0x2356e90<Mem:LD4[%arrayidx16(addrspace=4)](align=8)(tbaa=<0x2335188>)> [ORD=4]<br><br></div><div>ISEL: Match complete!<br><br><br><br></div><div>If I set a breakpoint in SelectAddrRegRegCommon I can see that this is true:<br><br></div><div>gdb> p Addr.getOperand(1).Node->getOpcode() == ISD::SHL)<br></div><div>true<br><br></div><div>So I've added that as a case to check for there, here's the function:<br><br>bool<br>XSTGDAGToDAGISel::SelectAddrRegRegCommon( SDValue Addr,<br>                                          SDValue &Base,<br>                                          SDValue &Offset ) {<br>  // If add operation, we can optimize.<br>  DEBUG(errs() << "SelectAddrRegRegCommon called: \n");<br>  if (Addr.getOpcode() == ISD::ADD) {<br>    if (Addr.getOperand(0).getOpcode() == ISD::TargetJumpTable) {`<br>      Base   = Addr.getOperand(0);<br>      Offset = Addr.getOperand(1);<br><br>      return true;<br>    }<br><br>    if (Addr.getOperand(1).getOpcode() == ISD::TargetJumpTable) {<br>      Base   = Addr.getOperand(1);<br>      Offset = Addr.getOperand(0);<br><br>      return true;<br>    }<br><br>    // operand 1 can't be a constant.<br>    if (dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {<br>      return false;<br>    }<br>    <br>    //possibly a load.idx<br>    if(Addr.getOperand(1).Node->getOpcode() == ISD::SHL) {<br></div><div>       // Not sure what should go here?<br></div><div>    }<br><br>    // set address and offset.<br>    Base   = Addr.getOperand(0);<br>    Offset = Addr.getOperand(1);<br><br>    return true;<br>  }<br>  return false;<br></div><div>} //end SelectAddrRegRegCommon<br><br></div><div>As the comment says, I'm not sure what code should go into the case where it's possibly a load.idx - Base and Offset are SDValues not SDNodes so I don't see how I could modify the DAG here to eliminate the shl - any ideas?<br><br></div><div>Phil<br></div><div><br><br><br></div><div><br><br></div><div><br></div><div><br></div><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote"><div class="gmail-HOEnZb"><div class="gmail-h5"><br>
<br>
-Krzysztof<br>
<br>
-- <br>
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation<br>
</div></div></blockquote></div><br></div></div>