Commit 2b977d98 authored by Simon Marlow's avatar Simon Marlow
Browse files

Remove most of TailCalls.h

it was only needed for registerised compilation.
parent 2e8c7694
......@@ -217,12 +217,11 @@ typedef StgFunPtr F_;
/* -----------------------------------------------------------------------------
Tail calls
This needs to be up near the top as the register line on alpha needs
to be before all procedures (inline & out-of-line).
-------------------------------------------------------------------------- */
#include "stg/TailCalls.h"
#define JMP_(cont) return((StgFunPtr)(cont))
#define FB_
#define FE_
/* -----------------------------------------------------------------------------
Other Stg stuff...
......
/* -----------------------------------------------------------------------------
*
* (c) The GHC Team, 1998-2009
*
* Stuff for implementing proper tail jumps.
*
* Do not #include this file directly: #include "Rts.h" instead.
*
* To understand the structure of the RTS headers, see the wiki:
* http://hackage.haskell.org/trac/ghc/wiki/Commentary/SourceTree/Includes
*
* ---------------------------------------------------------------------------*/
#ifndef TAILCALLS_H
#define TAILCALLS_H
/* -----------------------------------------------------------------------------
Unmangled tail-jumping: use the mini interpretter.
-------------------------------------------------------------------------- */
#ifdef USE_MINIINTERPRETER
#define JMP_(cont) return((StgFunPtr)(cont))
#define FB_
#define FE_
#else
extern void __DISCARD__(void);
/* -----------------------------------------------------------------------------
Tail calling on x86
-------------------------------------------------------------------------- */
#if i386_HOST_ARCH
/* Note about discard: possibly there to fool GCC into clearing up
before we do the jump eg. if there are some arguments left on the C
stack that GCC hasn't popped yet. Also possibly to fool any
optimisations (a function call often acts as a barrier). Not sure
if any of this is necessary now -- SDM
Comment to above note: I don't think the __DISCARD__() in JMP_ is
necessary. Arguments should be popped from the C stack immediately
after returning from a function, as long as we pass -fno-defer-pop
to gcc. Moreover, a goto to a first-class label acts as a barrier
for optimisations in the same way a function call does.
-= chak
*/
/* The goto here seems to cause gcc -O2 to delete all the code after
it - including the FE_ marker and the epilogue code - exactly what
we want! -- SDM
*/
#define JMP_(cont) \
{ \
void *__target; \
__DISCARD__(); \
__target = (void *)(cont); \
goto *__target; \
}
#endif /* i386_HOST_ARCH */
/* -----------------------------------------------------------------------------
Tail calling on x86_64
-------------------------------------------------------------------------- */
#if x86_64_HOST_ARCH
/*
NOTE about __DISCARD__():
On x86_64 this is necessary to work around bugs in the register
variable support in gcc. Without the __DISCARD__() call, gcc will
silently throw away assignements to global register variables that
happen before the jump.
Here's the example:
extern void g(void);
static void f(void) {
R1 = g;
__DISCARD__()
goto *R1;
}
without the dummy function call, gcc throws away the assignment to R1
(gcc 3.4.3) gcc bug #20359.
*/
#define JMP_(cont) \
{ \
__DISCARD__(); \
goto *(void *)(cont); \
}
#endif /* x86_64_HOST_ARCH */
/* -----------------------------------------------------------------------------
Tail calling on Sparc
-------------------------------------------------------------------------- */
#ifdef sparc_HOST_ARCH
#define JMP_(cont) ((F_) (cont))()
/* Oh so happily, the above turns into a "call" instruction,
which, on a SPARC, is nothing but a "jmpl" with the
return address in %o7 [which we don't care about].
*/
/* Don't need these for sparc mangling */
#define FB_
#define FE_
#endif /* sparc_HOST_ARCH */
/* -----------------------------------------------------------------------------
Tail calling on PowerPC
-------------------------------------------------------------------------- */
#ifdef powerpc_HOST_ARCH
#define JMP_(cont) \
{ \
void *target; \
target = (void *)(cont); \
__DISCARD__(); \
goto *target; \
}
/*
The __DISCARD__ is there because Apple's April 2002 Beta of GCC 3.1
sometimes generates incorrect code otherwise.
It tends to "forget" to update global register variables in the presence
of decrement/increment operators:
JMP_(*(--Sp)) is wrongly compiled as JMP_(Sp[-1]).
Calling __DISCARD__ in between works around this problem.
*/
/*
I would _love_ to use the following instead,
but some versions of Apple's GCC fail to generate code for it
if it is called for a casted data pointer - which is exactly what
we are going to do...
#define JMP_(cont) ((F_) (cont))()
*/
#endif /* powerpc_HOST_ARCH */
#ifdef powerpc64_HOST_ARCH
#define JMP_(cont) ((F_) (cont))()
#endif
/* -----------------------------------------------------------------------------
FUNBEGIN and FUNEND.
These are markers indicating the start and end of Real Code in a
function. All instructions between the actual start and end of the
function and these markers is shredded by the mangler.
-------------------------------------------------------------------------- */
/* The following __DISCARD__() has become necessary with gcc 2.96 on x86.
* It prevents gcc from moving stack manipulation code from the function
* body (aka the Real Code) into the function prologue, ie, from moving it
* over the --- BEGIN --- marker. It should be noted that (like some
* other black magic in GHC's code), there is no essential reason why gcc
* could not move some stack manipulation code across the __DISCARD__() -
* it just doesn't choose to do it at the moment.
* -= chak
*/
#ifndef FB_
#define FB_ __asm__ volatile ("--- BEGIN ---"); __DISCARD__ ();
#endif
#ifndef FE_
#define FE_ __asm__ volatile ("--- END ---");
#endif
#endif /* !USE_MINIINTERPRETER */
#endif /* TAILCALLS_H */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment