r230255 - Only lower __builtin_setjmp / __builtin_longjmp to

Joerg Sonnenberger joerg at britannica.bec.de
Tue Mar 3 07:16:46 PST 2015


On Tue, Mar 03, 2015 at 12:05:53AM -0800, John McCall wrote:
> >> Ruby has no target-specific configuration.
> 
> Literally the first google result for "Ruby __builtin_setjmp" is a core
> commit turning it off for a target.  Am I misunderstanding something?

The general logic is "test if it compiles and use it", of course, it can
be overriden by patching configure or command line, but that's hardly
appropiate...

> GCC implements this builtin with much more generality than we do,
> probably because GCC predates widespread adoption of libUnwind and we
> don't.  Hal's comment about not trying to match GCC on PPC aside (and
> I find that comment pretty troubling!), my understanding of the general
> intent of this builtin is that's for implementing extremely lightweight
> context-saving (on the assumption that the platform doesn't have that
> many callee-save registers; it would probably be awful on e.g. AArch64)
> and that the amount of state it saves is so small (PC, SP, FP if it's
> not rederivable from SP) that there's no reason [i]not[/i] to match GCC.

Actually, it is a bit more complicated. A good setjmp/longjmp
implementation in libc saves exactly the same set of registers. The only
reason the GCC implementation can be better is that it forces register
spilling to fixed locations and makes longjmp depend on that. I'm not
even sure there is any optimisation for detecting that longjmp doesn't
need to restore all registers.

> The fact that it's poorly documented and poorly implemented doesn't
> mean that breaking compatibility arbitrarily is acceptable.  It might
> be an unfortunate and obscure bit of ABI, but absent other information,
> I consider it ABI.  So I am not inclined to accept this, for trunk or
> for the branch.  I think it would be a much more modest and reasonable
> fix to just implement the builtin correctly in the ARM backend and
> wherever else you see the need.  Presumably Ruby is using this because
> they actually care about the performance.

"Implement it" comes with a quite a cost as it requires implementing a
good chunk of SJ/LJ functionality AND detecting when the landing pads
need to be added, even if no exceptions are used. That's why ARM fails
currently even on Darwin, which does use SJ/LJ for exception handling.
>From what I have seen, I don't believe in a performance benefit compared
to a proper libc implementation. That was already a fallacity of HP's
libunwind -- for the platforms at the time, only Itanium had an insane
enough callee-save register set, mostly the FP registert. But that's not
gong to help with SJ/LJ in this context either.

> But if you can get the LLVM list to agree with Hal that compatibility
> (even across compiler versions) is a non-goal, and you can show me more
> convincingly that e.g. Ruby only uses this in their core implementation
> and it is not used directly in the compiled code of native gems, then
> I am willing to change my mind.

As I said, I don't care about ABI compatibility enough to spend the time
to fix all backends. What I do care is that we currently silently
produce obviously bad code. If the ABI contract is supposed to be "uses
6 longs or less", which even GCC doesn't seem to get right, I am
perfectly fine with just creating a failure in this case. That should be
a trivial change.

Joerg



More information about the cfe-commits mailing list