Fix up inlines for gcc 4.3
authorSimon Marlow <marlowsd@gmail.com>
Thu, 19 Jun 2008 10:08:49 +0000 (10:08 +0000)
committerSimon Marlow <marlowsd@gmail.com>
Thu, 19 Jun 2008 10:08:49 +0000 (10:08 +0000)
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.

includes/SMP.h
includes/SMPClosureOps.h
includes/Stg.h
rts/Inlines.c [new file with mode: 0644]
rts/ProfHeap.c
rts/sm/Evac.c
rts/sm/Scav.c

index 0e6322d..eaac770 100644 (file)
@@ -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");
index fe78168..a43222d 100644 (file)
@@ -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)
 
 /* -----------------------------------------------------------------------------
 
 #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 */
index 35f4eda..022b385 100644 (file)
 
 /*
  * '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
  */
 #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__)
 
 /* -----------------------------------------------------------------------------
diff --git a/rts/Inlines.c b/rts/Inlines.c
new file mode 100644 (file)
index 0000000..5d2be70
--- /dev/null
@@ -0,0 +1,5 @@
+// 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"
index 599b479..9aca5a9 100644 (file)
@@ -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) {
index 3b68c62..375cf81 100644 (file)
@@ -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;
index f61d6b7..ab55e8a 100644 (file)
@@ -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;