<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <p>This doesn't directly address your question, but the context
      might be useful.</p>
    <p>At the moment, we have two distinct ways of handling callee saved
      register spill/restore.  <br>
    </p>
    <p>The first one is the one used by most calling conventions/targets
      and uses the PrologEpilogIinserter logic to insert spills in the
      prolog and epilog if the live range needs to be spilled.  The
      reasoning is that some exception propagation mechanisms and
      debuggers expect to be able to find the value of the CSR and this
      is the convention that arose.  Within this mechanism, an
      optimization was added to reduce spill range to just include
      callees, but I believe it still uses the globally assigned spill
      slots.  The key point here is that the register allocator doesn't
      see vregs for these and thus never really gets a chance to split
      them intelligently.  <br>
    </p>
    <p>The second one is called "split CSR".  If you search for that
      term in the code you'll find it's rarely used.  The basic idea
      here is that CSRs are just vregs with assigned physical
      constraints on entry and exit.  This version goes through the
      normal register allocation logic.  (But, good luck getting it to
      work with dwarf, etc...)  This implementation is also just
      generally less mature, so there might be more bugs to be
      found/fixed.  Here's one cleanup I started, but haven't gotten
      around to completing yet which might help you understand the code
      (<a class="moz-txt-link-freetext" href="https://reviews.llvm.org/D27293">https://reviews.llvm.org/D27293</a>).  <br>
    </p>
    <p>Personally, I'm of the belief that the second mechanism should be
      our default, but today, it is not.</p>
    <p>Philip<br>
    </p>
    <br>
    <div class="moz-cite-prefix">On 01/13/2017 06:28 AM, Nemanja
      Ivanovic via llvm-dev wrote:<br>
    </div>
    <blockquote
cite="mid:CAObEeNibGNXd8sqPAF6Hx4sbyAPhVSGwsz23p60-uTpMt1vkCg@mail.gmail.com"
      type="cite">
      <div dir="ltr">
        <div>
          <div>I have an issue that I've been wrestling with for quite
            some time and I'm hoping that someone with a deeper
            understanding of the register allocator can help me with.<br>
            <br>
          </div>
          Namely, I am trying to teach RA to split a live range rather
          than allocating a CSR. I've attempted a very large number of
          tweaks to the costs (both existing and experimental ones that
          I've added). However, despite all of that, I can't seem to get
          RA to split the following:<br>
          <span style="font-family:monospace,monospace"><br>
              1 BB#0: derived from LLVM BB %entry <br>
              2     Live Ins: %X3<br>
              3         %vreg15<def> = COPY %X3; G8RC:%vreg15<br>
              4         %vreg4<def> = CMPLDI %vreg15, 0;
            CRRC:%vreg4 G8RC:%vreg15<br>
              5         %vreg11:sub_32<def,read-undef> = LI 0;
            G8RC:%vreg11<br>
              6         BCC 68, %vreg4, <BB#1>; CRRC:%vreg4<br>
              7     Successors according to CFG: BB#4(0x30000000 /
            0x80000000 = 37.50%) BB#1(0x50000000 / 0x80000000 = 62.50%)<br>
              8         <br>
              9 BB#4:   <br>
             10     Predecessors according to CFG: BB#0<br>
             11         B <BB#3><br>
             12     Successors according to CFG: BB#3(?%)<br>
             13     <br>
             14 BB#1: derived from LLVM BB %if.end<br>
             15     Predecessors according to CFG: BB#0<br>
             16         %vreg6<def> = ADDIStocHA %X2,
            <ga:@a>; G8RC_and_G8RC_NOX0:%vreg6<br>
             17         %vreg7<def> = LDtocL <ga:@a>,
            %vreg6, %X2<imp-use>; mem:LD8[GOT]
            G8RC_and_G8RC_NOX0:%vreg7,%vreg6<br>
             18         %vreg8<def> = LWA 0, %vreg7;
            mem:LD4[@a](tbaa=!3)(dereferenceable) G8RC:%vreg8
            G8RC_and_G8RC_NOX0:%vreg7<br>
             19         %vreg9<def> = CMPLD %vreg8, %vreg15;
            CRRC:%vreg9 G8RC:%vreg8,%vreg15<br>
             20         BCC 68, %vreg9, <BB#3>; CRRC:%vreg9<br>
             21         B <BB#2><br>
             22     Successors according to CFG: BB#2(0x30000000 /
            0x80000000 = 37.50%) BB#3(0x50000000 / 0x80000000 = 62.50%)<br>
             23         <br>
             24 BB#2: derived from LLVM BB %if.then2<br>
             25     Predecessors according to CFG: BB#1<br>
             26         ADJCALLSTACKDOWN 96, %R1<imp-def,dead>,
            %R1<imp-use><br>
             27         %vreg16<def> = COPY %vreg15;
            G8RC:%vreg16,%vreg15<br>
             28         BL8_NOP <ga:@callVoid>, <regmask **LONG
            LIST**>, %X3<imp-def,dead><br>
             29         ADJCALLSTACKUP 96, 0, %R1<imp-def,dead>,
            %R1<imp-use><br>
             30         ADJCALLSTACKDOWN 96, %R1<imp-def,dead>,
            %R1<imp-use> 31         %X3<def> = COPY %vreg16;
            G8RC:%vreg16<br>
             32         BL8_NOP <ga:@callNonVoid>, <regmask
            **LONG LIST**>, %X3<imp-use>, %X2<imp-use>,
            %R1<imp-def>, %X3<imp-def><br>
             33         ADJCALLSTACKUP 96, 0, %R1<imp-def,dead>,
            %R1<imp-use><br>
             34         %vreg11<def> = COPY %X3; G8RC:%vreg11
            35     Successors according to CFG: BB#3(?%)<br>
             36         <br>
             37 BB#3: derived from LLVM BB %return<br>
             38     Predecessors according to CFG: BB#1 BB#2 BB#4<br>
             39         %vreg12<def> = EXTSW_32_64 %vreg11:sub_32;
            G8RC:%vreg12,%vreg11<br>
             40         %X3<def> = COPY %vreg12; G8RC:%vreg12<br>
             41         BLR8 %LR8<imp-use>, %RM<imp-use>,
            %X3<imp-use></span><br>
          <br>
        </div>
        <div>No matter what I do, vreg15 will get a Callee-Saved
          Register assigned to it. However, this is suboptimal. So what
          I am trying to accomplish is to split the live range of vreg15
          into the paths without the call and the path with the call
          (BL8_NOP is a call). Then the physical register X3 can be used
          in the paths <span style="font-family:monospace,monospace">BB#0
            -> BB#1 -> BB#3</span> and <span
            style="font-family:monospace,monospace">BB#0 -> BB#4
            -> BB#3</span> and it can be copied to a Callee-Saved
          Register in <span style="font-family:monospace,monospace">BB#2</span>.<br>
          <br>
        </div>
        <div>Without such a split, vreg15 is assigned a CSR for the
          entire live range and there is no way to avoid having to
          save/restore the CSR in the prologue/epilogue. If one of the
          two paths that did not actually have the call turn out to be
          the hottest path through the function, there is a lot of
          wasted cycles in the save/restore because we weren't able to
          shrink-wrap this function due to the choice RA made.<br>
          <br>
        </div>
        <div>If anyone can offer some ideas on what I should do here, I
          would truly appreciate it. <br>
          <br>
        </div>
        <div>Nemanja<br>
        </div>
      </div>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <br>
      <pre wrap="">_______________________________________________
LLVM Developers mailing list
<a class="moz-txt-link-abbreviated" href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>
<a class="moz-txt-link-freetext" href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a>
</pre>
    </blockquote>
    <br>
  </body>
</html>