RE: jhc vs ghc and the surprising result involving ghcgeneratedassembly.

On 02 November 2005 13:59, Florian Weimer wrote:
However, beginning with GCC 3.4, you can use:
extern void bar();
void foo() { void (*p)(void) = bar; p(); }
Interesting.. though I'm not sure I'm comfortable with relying on gcc's tail call optimisation to do the right thing. Aren't there side conditions that might prevent it from kicking in?
And the indirect call is turned into a direct jump. Tail recursive calls and really indirect tail calls are also optimzed. Together with -fomit-frame-pointer, this could give you what you need, without post-processing the generated assembler code (which is desirable because the asm volatile statements inhibit further optimization).
Is it correct that you use indirect gotos across functions? Such gotos aren't supported by GCC and work only by accident.
Yes, but cross-function gotos are always to the beginning of a function. Also, our post-processor removes the function prologue from the asm. GHC via C has always worked "by accident" :-) But it has worked for a long time with careful tweaking of the post-processor (known as the mangler) for each new version of gcc. Yes, we're living dangerously, and it's getting harder, but we're still alive (just). Cheers, Simon

* Simon Marlow:
However, beginning with GCC 3.4, you can use:
extern void bar();
void foo() { void (*p)(void) = bar; p(); }
Interesting.. though I'm not sure I'm comfortable with relying on gcc's tail call optimisation to do the right thing. Aren't there side conditions that might prevent it from kicking in?
It's a target-specific optimization. For i386, the requirements are roughly speaking, (a) it works with -fPIC only for very special cases (direct calls within the same module), (b) the return values must be the same, (c) for indirect calls, there must be a free register (currently, this means that regparam must be less than 3; irrelevant if you don't pass any arguments). AMD64 has only very few restrictions, none of which seem particularly relevant. ia64 may need additional hints before the optimization is performed (non-default visibility of the target function), otherwise the optimization is only performed within the same translation unit. PowerPC and SPARC cannot optimize indirect calls. Common MIPS targets should be fine. So your concern is valid; this optimization is not always available. It might be possible to extend GCC with something that violates the ABI and fits your needs, though, in case the current goto hack no longer works.

Simon Marlow wrote:
Is it correct that you use indirect gotos across functions? Such gotos aren't supported by GCC and work only by accident.
Yes, but cross-function gotos are always to the beginning of a function.
Is that enough to ensure that the constant pool base register is reloaded on the Alpha? -- Lennart

* Lennart Augustsson:
Simon Marlow wrote:
Is it correct that you use indirect gotos across functions? Such gotos aren't supported by GCC and work only by accident. Yes, but cross-function gotos are always to the beginning of a function.
Is that enough to ensure that the constant pool base register is reloaded on the Alpha?
Good point, most of the restrictions I mentioned result from the need to update the GP pointer.
participants (3)
-
Florian Weimer
-
Lennart Augustsson
-
Simon Marlow