summaryrefslogtreecommitdiff
path: root/includes
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2008-06-19 10:08:49 +0000
committerSimon Marlow <marlowsd@gmail.com>2008-06-19 10:08:49 +0000
commit24ad9cf0325bb5fedc9f0ca8bd70f78096d8d326 (patch)
tree0842c597aaf44db82f49d43cd9f8f14ee09f16a7 /includes
parent067ec969bb0bdc4c88582e53b040fa2925cbcc56 (diff)
downloadhaskell-24ad9cf0325bb5fedc9f0ca8bd70f78096d8d326.tar.gz
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.
Diffstat (limited to 'includes')
-rw-r--r--includes/SMP.h12
-rw-r--r--includes/SMPClosureOps.h25
-rw-r--r--includes/Stg.h28
3 files changed, 44 insertions, 21 deletions
diff --git a/includes/SMP.h b/includes/SMP.h
index 0e6322d40b..eaac770107 100644
--- a/includes/SMP.h
+++ b/includes/SMP.h
@@ -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");
diff --git a/includes/SMPClosureOps.h b/includes/SMPClosureOps.h
index fe78168011..a43222d232 100644
--- a/includes/SMPClosureOps.h
+++ b/includes/SMPClosureOps.h
@@ -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 */
diff --git a/includes/Stg.h b/includes/Stg.h
index 35f4eda631..022b385e2d 100644
--- a/includes/Stg.h
+++ b/includes/Stg.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__)
/* -----------------------------------------------------------------------------