<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>