<div dir="ltr">Well, the setjmp site still has to notionally save and restore all the callee-save registers; it just might be able to take advantage of having saved them in the prologue if the function's not using them for anything else, and as you say, it can schedule the saves and restores more efficiently than setjmp/longjmp do. Also, it eliminates a call, and if you're naively using setjmp instead of _setjmp it avoids saving quite a bit of extra state.<div><br></div><div>John.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Mar 3, 2015 at 8:50 AM, Hal Finkel <span dir="ltr"><<a href="mailto:hfinkel@anl.gov" target="_blank">hfinkel@anl.gov</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">----- Original Message -----<br>
> From: "Joerg Sonnenberger" <<a href="mailto:joerg@britannica.bec.de">joerg@britannica.bec.de</a>><br>
> To: "John McCall" <<a href="mailto:rjmccall@gmail.com">rjmccall@gmail.com</a>><br>
</span><span class="">> Cc: "Hal Finkel" <<a href="mailto:hfinkel@anl.gov">hfinkel@anl.gov</a>>, "<<a href="mailto:hans@hanshq.net">hans@hanshq.net</a>>" <<a href="mailto:hans@hanshq.net">hans@hanshq.net</a>>, "cfe-commits" <<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a>><br>
> Sent: Tuesday, March 3, 2015 9:16:46 AM<br>
> Subject: Re: r230255 - Only lower __builtin_setjmp / __builtin_longjmp to<br>
><br>
</span><div><div class="h5">> On Tue, Mar 03, 2015 at 12:05:53AM -0800, John McCall wrote:<br>
> > >> Ruby has no target-specific configuration.<br>
> ><br>
> > Literally the first google result for "Ruby __builtin_setjmp" is a<br>
> > core<br>
> > commit turning it off for a target. Am I misunderstanding<br>
> > something?<br>
><br>
> The general logic is "test if it compiles and use it", of course, it<br>
> can<br>
> be overriden by patching configure or command line, but that's hardly<br>
> appropiate...<br>
><br>
> > GCC implements this builtin with much more generality than we do,<br>
> > probably because GCC predates widespread adoption of libUnwind and<br>
> > we<br>
> > don't. Hal's comment about not trying to match GCC on PPC aside<br>
> > (and<br>
> > I find that comment pretty troubling!), my understanding of the<br>
> > general<br>
> > intent of this builtin is that's for implementing extremely<br>
> > lightweight<br>
> > context-saving (on the assumption that the platform doesn't have<br>
> > that<br>
> > many callee-save registers; it would probably be awful on e.g.<br>
> > AArch64)<br>
> > and that the amount of state it saves is so small (PC, SP, FP if<br>
> > it's<br>
> > not rederivable from SP) that there's no reason [i]not[/i] to match<br>
> > GCC.<br>
><br>
> Actually, it is a bit more complicated. A good setjmp/longjmp<br>
> implementation in libc saves exactly the same set of registers. The<br>
> only<br>
> reason the GCC implementation can be better is that it forces<br>
> register<br>
> spilling to fixed locations and makes longjmp depend on that.<br>
<br>
</div></div>No, this is not quite right. __builtin_setjmp can save many fewer registers than setjmp, because it does not need to save registers that don't need to be restored at that particular call site (the function might not be using all available registers). Furthermore, those saves, and the restores, can be scheduled to hide their latency (not all clumped together in the longjmp implementation).<br>
<span class="HOEnZb"><font color="#888888"><br>
-Hal<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
> I'm not<br>
> even sure there is any optimisation for detecting that longjmp<br>
> doesn't<br>
> need to restore all registers.<br>
><br>
> > The fact that it's poorly documented and poorly implemented doesn't<br>
> > mean that breaking compatibility arbitrarily is acceptable. It<br>
> > might<br>
> > be an unfortunate and obscure bit of ABI, but absent other<br>
> > information,<br>
> > I consider it ABI. So I am not inclined to accept this, for trunk<br>
> > or<br>
> > for the branch. I think it would be a much more modest and<br>
> > reasonable<br>
> > fix to just implement the builtin correctly in the ARM backend and<br>
> > wherever else you see the need. Presumably Ruby is using this<br>
> > because<br>
> > they actually care about the performance.<br>
><br>
> "Implement it" comes with a quite a cost as it requires implementing<br>
> a<br>
> good chunk of SJ/LJ functionality AND detecting when the landing pads<br>
> need to be added, even if no exceptions are used. That's why ARM<br>
> fails<br>
> currently even on Darwin, which does use SJ/LJ for exception<br>
> handling.<br>
> From what I have seen, I don't believe in a performance benefit<br>
> compared<br>
> to a proper libc implementation. That was already a fallacity of HP's<br>
> libunwind -- for the platforms at the time, only Itanium had an<br>
> insane<br>
> enough callee-save register set, mostly the FP registert. But that's<br>
> not<br>
> gong to help with SJ/LJ in this context either.<br>
><br>
> > But if you can get the LLVM list to agree with Hal that<br>
> > compatibility<br>
> > (even across compiler versions) is a non-goal, and you can show me<br>
> > more<br>
> > convincingly that e.g. Ruby only uses this in their core<br>
> > implementation<br>
> > and it is not used directly in the compiled code of native gems,<br>
> > then<br>
> > I am willing to change my mind.<br>
><br>
> As I said, I don't care about ABI compatibility enough to spend the<br>
> time<br>
> to fix all backends. What I do care is that we currently silently<br>
> produce obviously bad code. If the ABI contract is supposed to be<br>
> "uses<br>
> 6 longs or less", which even GCC doesn't seem to get right, I am<br>
> perfectly fine with just creating a failure in this case. That should<br>
> be<br>
> a trivial change.<br>
><br>
> Joerg<br>
><br>
<br>
</div></div><div class="HOEnZb"><div class="h5">--<br>
Hal Finkel<br>
Assistant Computational Scientist<br>
Leadership Computing Facility<br>
Argonne National Laboratory<br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature">I suppose you'd like my real thoughts as well.</div>
</div>