<div dir="ltr"><div>Hi Charlotte,</div><div><br></div><div>Thanks for your reply!</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><br></div><div>There are some more restrictions to tail calls, namely it needs
      to be possible to restructure the function in such a way that the
      function epilogue has already been run. Local variables are scoped
      and go out of scope at the end of the function. The function
      epilogue is responsible for restoring the stack and (in C++)
      running the destructors of stack variables.</div></blockquote><div>I understand it now. So basically the restriction is that f() needs to be able to restore the stack to "as if" it has finished running, so "g"'s epilogue could clean up as if "f" has finished running, which means, no variables living on the stack can survive at the time the tail call to 'g' happens. <br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>non-cdecl calling conventions are highly architecture dependent. You
    are likely better off instructing LLVM to inline functions by
    choosing a higher optimization level (-O3) and Link Time
    Optimizations (-flto=thin)</div></blockquote><div>What you said is definitely true, but my use case is kind of special so inlining is not possible and also the functions are pretty small so likely the calling conventions are taking a significant amount of time, which is why I would like to understand better on the possible alternative options (and which is also why I haven't digged into it before, because what you said is for sure the solution for 99% use cases 😄). I have read the FTL javascript JIT was using non-cdecl calling convention for performance, which is why I wanted to understand more. Is there any good introduction article you could recommend?<br></div><div><br></div><div>Thanks!<br></div><div><br></div><div>Best,</div><div>Haoran<br></div><div><br></div><div><br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Charlotte Delenk via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> 于2020年9月25日周五 上午4:06写道:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
  
    
  
  <div>
    <p>Hi Haoran,<br>
    </p>
    <div>On 9/25/20 11:33 AM, Haoran Xu via
      llvm-dev wrote:<br>
    </div>
    <blockquote type="cite">
      
      <div dir="ltr">
        <div>Hi friendly LLVM Devs,</div>
        <div><br>
        </div>
        <div>I'm trying to understand the technical details of tail call
          optimization, but unfortunately I hit some issues that I
          couldn't figure out myself.</div>
        <div><br>
        </div>
        <div>So I tried the following two really simple functions:</div>
        <div>
          <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
            <div><span style="color:rgb(0,0,255)">extern</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(0,0,255)">void</span><span style="color:rgb(0,0,0)"> g(</span><span style="color:rgb(0,0,255)">int</span><span style="color:rgb(0,0,0)">*);</span></div>
            <div><span style="color:rgb(0,0,255)">void</span><span style="color:rgb(0,0,0)"> f1() {</span></div>
            <div><span style="color:rgb(0,0,0)">   </span><span style="color:rgb(0,0,255)">int</span><span style="color:rgb(0,0,0)"> x;</span></div>
            <div><span style="color:rgb(0,0,0)">   g(&x);</span></div>
            <div><span style="color:rgb(0,0,0)">}</span></div>
            <div><span style="color:rgb(0,0,255)">void</span><span style="color:rgb(0,0,0)"> f2(</span><span style="color:rgb(0,0,255)">int</span><span style="color:rgb(0,0,0)">* x) {</span></div>
            <div><span style="color:rgb(0,0,0)">   g(x);</span></div>
            <div><span style="color:rgb(0,0,0)">}</span></div>
          </blockquote>
        </div>
        <div>It turns out that 'f1' does not have tail call
          optimization, but 'f2' does. <br>
        </div>
        <div>My current really naive understanding is that a call
          happening as the last statement of the function can be
          optimized as a tail call. However, why cannot 'f1' do this? <br>
        </div>
      </div>
    </blockquote>
    <p>There are some more restrictions to tail calls, namely it needs
      to be possible to restructure the function in such a way that the
      function epilogue has already been run. Local variables are scoped
      and go out of scope at the end of the function. The function
      epilogue is responsible for restoring the stack and (in C++)
      running the destructors of stack variables.</p>
    <p><tt>x however can't be converted into a register variable as it
        can in f2, as the & operator requires the variable to be
        placed in memory.</tt><br>
    </p>
    <blockquote type="cite">
      <div dir="ltr">
        <div>Is there any recommended articles that I should read if I
          were to understand the internals of tail call optimization in
          LLVM, or more generally, performance optimization on reducing
          function calling overhead? I know there are a bunch of
          different calling conventions, optimized for different use
          cases, but I don't know any of the details. Can someone
          suggest a good introductory material that I should read to
          understand what are the pros and cons of each calling
          convention, and what should be the best calling convention for
          a given use case?</div>
      </div>
    </blockquote>
    non-cdecl calling conventions are highly architecture dependent. You
    are likely better off instructing LLVM to inline functions by
    choosing a higher optimization level (-O3) and Link Time
    Optimizations (-flto=thin)<br>
    <blockquote type="cite">
      <div dir="ltr">
        <div><br>
        </div>
        <div>Thanks!</div>
        <div><br>
        </div>
        <div>Best,</div>
        <div>Haoran<br>
        </div>
        <div><br>
        </div>
        <div>
          <div>
            <div><span style="color:rgb(0,0,0)"><br>
              </span></div>
            <br>
            <br>
          </div>
        </div>
      </div>
      <br>
      <fieldset></fieldset>
      <pre>_______________________________________________
LLVM Developers mailing list
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a>
</pre>
    </blockquote>
  </div>

_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div>