<div dir="ltr"><div>Hi Alexey,</div><div><br></div><div>Thanks for the explanation! That's really a tricky case, I understand it now.</div><div><br></div><div>Best,</div><div>Haoran<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Alexey <<a href="mailto:avl.lapshin@gmail.com">avl.lapshin@gmail.com</a>> 于2020年10月3日周六 上午3:35写道:<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,</p>
<div>On 03.10.2020 12:02, Haoran Xu via
llvm-dev wrote:<br>
</div>
<blockquote type="cite">
<div dir="ltr">
<div>Hello,</div>
<div><br>
</div>
<div>Could anyone kindly explain to me why the 'g()' in the
following function cannot have tail call optimization?</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div>
<div>
<div><span style="color:rgb(0,0,255)">void</span><span style="color:rgb(0,0,0)"> f(</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,255)">void</span><span style="color:rgb(0,0,0)"> g();</span></div>
<div><span style="color:rgb(0,0,255)">void</span><span style="color:rgb(0,0,0)"> h(</span><span style="color:rgb(0,0,255)">int</span><span style="color:rgb(0,0,0)"> v) {</span></div>
<div><span style="color:rgb(0,0,0)"> f(&v);</span></div>
<div><span style="color:rgb(0,0,0)"> g();</span></div>
<div><span style="color:rgb(0,0,0)">}</span></div>
</div>
</div>
</blockquote>
<div>
<div>A while ago I was taught that tail call optimization
cannot apply if local variables needs to be kept alive, but
'g()' doesn't seem to require anything to be alive on the
stack.</div>
<div>I tried to manually add 'tail' to the emitted LLVM IR and
it appears to work. <br>
</div>
<div><br>
</div>
<div>Any idea how I could fix this and let clang automatically
generate tail call?</div>
</div>
</div>
</blockquote>
<p><br>
</p>
<p>In that test case the pointer to "v" could escape through call to
f();<br>
That prevents from doing tail call for g().<br>
If it is already known that f() does not capture its parameter <br>
then it could be declared with attribute noescape :<br>
<br>
<a href="https://clang.llvm.org/docs/AttributeReference.html#noescape" target="_blank">https://clang.llvm.org/docs/AttributeReference.html#noescape</a><br>
<br>
In this case tailcall happens:<br>
<br>
cat test.cpp<br>
void f(__attribute__((noescape)) int* x);<br>
void g();<br>
void h(int v) {<br>
f(&v);<br>
g();<br>
}<br>
<br>
clang++ -O3 -S test.cpp<br>
<br>
grep _Z1gv test.s<br>
<br>
jmp _Z1gv # TAILCALL</p>
<p><br>
</p>
<br>
<blockquote type="cite">
<div dir="ltr">
<div>
<div>Thanks!</div>
<div><br>
</div>
<div>Best,</div>
<div>Haoran<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>
</blockquote></div>