Commit 24ad9cf0 authored by Simon Marlow's avatar Simon Marlow
Browse files

Fix up inlines for gcc 4.3

gcc 4.3 emits warnings for static inline functions that its heuristics
decided not to inline.  The workaround is to either mark appropriate
functions as "hot" (a new attribute in gcc 4.3), or sometimes to use
"extern inline" instead.

With this fix I can validate with gcc 4.3 on Fedora 9.
parent 067ec969
......@@ -41,7 +41,7 @@
* Used for locking closures during updates (see lockClosure() below)
* and the MVar primops.
*/
INLINE_HEADER StgWord xchg(StgPtr p, StgWord w);
EXTERN_INLINE StgWord xchg(StgPtr p, StgWord w);
/*
* Compare-and-swap. Atomically does this:
......@@ -52,13 +52,13 @@ INLINE_HEADER StgWord xchg(StgPtr p, StgWord w);
* return r;
* }
*/
INLINE_HEADER StgWord cas(StgVolatilePtr p, StgWord o, StgWord n);
EXTERN_INLINE StgWord cas(StgVolatilePtr p, StgWord o, StgWord n);
/*
* Prevents write operations from moving across this call in either
* direction.
*/
INLINE_HEADER void write_barrier(void);
EXTERN_INLINE void write_barrier(void);
/* ----------------------------------------------------------------------------
Implementations
......@@ -67,7 +67,7 @@ INLINE_HEADER void write_barrier(void);
* NB: the xchg instruction is implicitly locked, so we do not need
* a lock prefix here.
*/
INLINE_HEADER StgWord
EXTERN_INLINE StgWord
xchg(StgPtr p, StgWord w)
{
StgWord result;
......@@ -106,7 +106,7 @@ xchg(StgPtr p, StgWord w)
* CMPXCHG - the single-word atomic compare-and-exchange instruction. Used
* in the STM implementation.
*/
INLINE_HEADER StgWord
EXTERN_INLINE StgWord
cas(StgVolatilePtr p, StgWord o, StgWord n)
{
#if i386_HOST_ARCH || x86_64_HOST_ARCH
......@@ -159,7 +159,7 @@ cas(StgVolatilePtr p, StgWord o, StgWord n)
* control in C, and optionally a memory barrier instruction on CPUs
* that require it (not x86 or x86_64).
*/
INLINE_HEADER void
EXTERN_INLINE void
write_barrier(void) {
#if i386_HOST_ARCH || x86_64_HOST_ARCH
__asm__ __volatile__ ("" : : : "memory");
......
......@@ -9,6 +9,9 @@
#ifndef SMPCLOSUREOPS_H
#define SMPCLOSUREOPS_H
EXTERN_INLINE StgInfoTable *lockClosure(StgClosure *p);
EXTERN_INLINE void unlockClosure(StgClosure *p, const StgInfoTable *info);
#if defined(THREADED_RTS)
/* -----------------------------------------------------------------------------
......@@ -19,16 +22,9 @@
#define SPIN_COUNT 4000
#ifdef KEEP_LOCKCLOSURE
// We want a callable copy of lockClosure() so that we can refer to it
// from .cmm files compiled using the native codegen.
extern StgInfoTable *lockClosure(StgClosure *p);
INLINE_ME
#else
INLINE_HEADER
#endif
StgInfoTable *
lockClosure(StgClosure *p)
EXTERN_INLINE StgInfoTable *lockClosure(StgClosure *p)
{
StgWord info;
do {
......@@ -41,8 +37,7 @@ lockClosure(StgClosure *p)
} while (1);
}
INLINE_HEADER void
unlockClosure(StgClosure *p, const StgInfoTable *info)
EXTERN_INLINE void unlockClosure(StgClosure *p, const StgInfoTable *info)
{
// This is a strictly ordered write, so we need a write_barrier():
write_barrier();
......@@ -51,21 +46,23 @@ unlockClosure(StgClosure *p, const StgInfoTable *info)
#else /* !THREADED_RTS */
INLINE_HEADER StgInfoTable *
EXTERN_INLINE StgInfoTable *
lockClosure(StgClosure *p)
{ return (StgInfoTable *)p->header.info; }
INLINE_HEADER void
EXTERN_INLINE void
unlockClosure(StgClosure *p STG_UNUSED, const StgInfoTable *info STG_UNUSED)
{ /* nothing */ }
#endif /* THREADED_RTS */
// Handy specialised versions of lockClosure()/unlockClosure()
INLINE_HEADER void lockTSO(StgTSO *tso)
EXTERN_INLINE void lockTSO(StgTSO *tso);
EXTERN_INLINE void lockTSO(StgTSO *tso)
{ lockClosure((StgClosure *)tso); }
INLINE_HEADER void unlockTSO(StgTSO *tso)
EXTERN_INLINE void unlockTSO(StgTSO *tso);
EXTERN_INLINE void unlockTSO(StgTSO *tso)
{ unlockClosure((StgClosure*)tso, (const StgInfoTable *)&stg_TSO_info); }
#endif /* SMPCLOSUREOPS_H */
......@@ -75,21 +75,41 @@
/*
* 'Portable' inlining:
* INLINE_HEADER is for inline functions in header files
* INLINE_HEADER is for inline functions in header files (macros)
* STATIC_INLINE is for inline functions in source files
* EXTERN_INLINE is for functions that we want to inline sometimes
*/
#if defined(__GNUC__) || defined( __INTEL_COMPILER)
# define INLINE_HEADER static inline
# define INLINE_ME inline
# define STATIC_INLINE INLINE_HEADER
# if defined(KEEP_INLINES)
# define EXTERN_INLINE inline
# else
# define EXTERN_INLINE extern inline
# endif
#elif defined(_MSC_VER)
# define INLINE_HEADER __inline static
# define INLINE_ME __inline
# define STATIC_INLINE INLINE_HEADER
# if defined(KEEP_INLINES)
# define EXTERN_INLINE __inline
# else
# define EXTERN_INLINE __inline extern
# endif
#else
# error "Don't know how to inline functions with your C compiler."
#endif
/*
* GCC attributes
*/
......@@ -105,6 +125,12 @@
#define GNUC3_ATTRIBUTE(at)
#endif
#if __GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 3
#define GNUC_ATTR_HOT __attribute__((hot))
#else
#define GNUC_ATTR_HOT /* nothing */
#endif
#define STG_UNUSED GNUC3_ATTRIBUTE(__unused__)
/* -----------------------------------------------------------------------------
......
// all functions declared with EXTERN_INLINE in the header files get
// compiled for real here, just in case the definition was not inlined
// at some call site:
#define KEEP_INLINES
#include "Rts.h"
......@@ -182,7 +182,7 @@ static char *type_names[] = {
* the band to which this closure's heap space is attributed in the
* heap profile.
* ------------------------------------------------------------------------- */
STATIC_INLINE void *
static void *
closureIdentity( StgClosure *p )
{
switch (RtsFlags.ProfFlags.doHeapProfile) {
......
......@@ -86,7 +86,7 @@ alloc_for_copy (nat size, step *stp)
The evacuate() code
-------------------------------------------------------------------------- */
STATIC_INLINE void
STATIC_INLINE GNUC_ATTR_HOT void
copy_tag(StgClosure **p, const StgInfoTable *info,
StgClosure *src, nat size, step *stp, StgWord tag)
{
......@@ -218,7 +218,7 @@ spin:
/* Copy wrappers that don't tag the closure after copying */
STATIC_INLINE void
STATIC_INLINE GNUC_ATTR_HOT void
copy(StgClosure **p, const StgInfoTable *info,
StgClosure *src, nat size, step *stp)
{
......@@ -267,7 +267,7 @@ copy(StgClosure **p, const StgInfoTable *info,
extra reads/writes than we save.
------------------------------------------------------------------------- */
REGPARM1 void
REGPARM1 GNUC_ATTR_HOT void
evacuate(StgClosure **p)
{
bdescr *bd = NULL;
......
......@@ -140,7 +140,7 @@ scavenge_arg_block (StgFunInfoTable *fun_info, StgClosure **args)
return p;
}
STATIC_INLINE StgPtr
STATIC_INLINE GNUC_ATTR_HOT StgPtr
scavenge_PAP_payload (StgClosure *fun, StgClosure **payload, StgWord size)
{
StgPtr p;
......@@ -179,7 +179,7 @@ scavenge_PAP_payload (StgClosure *fun, StgClosure **payload, StgWord size)
return p;
}
STATIC_INLINE StgPtr
STATIC_INLINE GNUC_ATTR_HOT StgPtr
scavenge_PAP (StgPAP *pap)
{
evacuate(&pap->fun);
......@@ -230,7 +230,7 @@ scavenge_large_srt_bitmap( StgLargeSRT *large_srt )
* srt field in the info table. That's ok, because we'll
* never dereference it.
*/
STATIC_INLINE void
STATIC_INLINE GNUC_ATTR_HOT void
scavenge_srt (StgClosure **srt, nat srt_bitmap)
{
nat bitmap;
......@@ -270,7 +270,7 @@ scavenge_srt (StgClosure **srt, nat srt_bitmap)
}
STATIC_INLINE void
STATIC_INLINE GNUC_ATTR_HOT void
scavenge_thunk_srt(const StgInfoTable *info)
{
StgThunkInfoTable *thunk_info;
......@@ -281,7 +281,7 @@ scavenge_thunk_srt(const StgInfoTable *info)
scavenge_srt((StgClosure **)GET_SRT(thunk_info), thunk_info->i.srt_bitmap);
}
STATIC_INLINE void
STATIC_INLINE GNUC_ATTR_HOT void
scavenge_fun_srt(const StgInfoTable *info)
{
StgFunInfoTable *fun_info;
......@@ -304,7 +304,7 @@ scavenge_fun_srt(const StgInfoTable *info)
idea.
-------------------------------------------------------------------------- */
static void
static GNUC_ATTR_HOT void
scavenge_block (bdescr *bd)
{
StgPtr p, q;
......
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