[commit: ghc] master: RTS: Fix & refactor "portable inline" macros (882179d)

git at git.haskell.org git at git.haskell.org
Sat Mar 26 08:02:10 UTC 2016


Repository : ssh://git@git.haskell.org/ghc

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/882179de09f9bd466b0e7ca83522aee0d3d7144a/ghc

>---------------------------------------------------------------

commit 882179de09f9bd466b0e7ca83522aee0d3d7144a
Author: Herbert Valerio Riedel <hvr at gnu.org>
Date:   Sat Mar 26 00:59:31 2016 +0100

    RTS: Fix & refactor "portable inline" macros
    
    Turns out the current macros for gnu90-style inline
    semantics stopped working with GCC 5
    (and possibly also with Apple's GCC) which switched on
    `__GNUC_STDC_INLINE__` by default falling back to using the
    suboptimal `static inline` mode.
    
    However, C99 supports an equivalent (as far as our
    use-case is concerned) `extern inline` mode.
    
    See also
    http://www.greenend.org.uk/rjk/tech/inline.html
    for a write-up of gnu90 vs C99 semantics.
    
    This patch also removes the MSVC case as VS2015 is supposed
    to finally catch up to C99 (and C11), so we don't need any
    special care for MSVC anymore.
    
    Reviewed By: erikd, austin
    
    Differential Revision: https://phabricator.haskell.org/D2039


>---------------------------------------------------------------

882179de09f9bd466b0e7ca83522aee0d3d7144a
 includes/Stg.h | 76 ++++++++++++++++++++++++++++++----------------------------
 1 file changed, 39 insertions(+), 37 deletions(-)

diff --git a/includes/Stg.h b/includes/Stg.h
index a8ab5ca..a2894a5 100644
--- a/includes/Stg.h
+++ b/includes/Stg.h
@@ -129,51 +129,53 @@
  * EXTERN_INLINE is for functions that we want to inline sometimes
  * (we also compile a static version of the function; see Inlines.c)
  */
-#if defined(__GNUC__) || defined( __INTEL_COMPILER)
 
-# define INLINE_HEADER static inline
-# define INLINE_ME inline
-# define STATIC_INLINE INLINE_HEADER
-
-// The special "extern inline" behaviour is now only supported by gcc
-// when _GNUC_GNU_INLINE__ is defined, and you have to use
-// __attribute__((gnu_inline)).  So when we don't have this, we use
-// ordinary static inline.
-//
-// Apple's gcc defines __GNUC_GNU_INLINE__ without providing
-// gnu_inline, so we exclude MacOS X and fall through to the safe
-// version.
+// We generally assume C99 semantics albeit these two definitions work fine even
+// when gnu90 semantics are active (i.e. when __GNUC_GNU_INLINE__ is defined or
+// when a GCC older than 4.2 is used)
 //
-#if defined(__GNUC_GNU_INLINE__) && !defined(__APPLE__)
-#  if defined(KEEP_INLINES)
-#    define EXTERN_INLINE inline
-#  else
-#    define EXTERN_INLINE extern inline __attribute__((gnu_inline))
-#  endif
-#else
-#  if defined(KEEP_INLINES)
-#    define EXTERN_INLINE
-#  else
-#    define EXTERN_INLINE INLINE_HEADER
-#  endif
+// The problem, however, is with 'extern inline' whose semantics significantly
+// differs between gnu90 and C99
+#define INLINE_HEADER static inline
+#define INLINE_ME inline
+#define STATIC_INLINE static inline
+
+// Figure out whether `__attributes__((gnu_inline))` is needed
+// to force gnu90-style 'external inline' semantics.
+#if defined(FORCE_GNU_INLINE)
+// disable auto-detection since HAVE_GNU_INLINE has been defined externally
+#elif __GNUC_GNU_INLINE__ && __GNUC__ == 4 && __GNUC_MINOR__ == 2
+// GCC 4.2.x didn't properly support C99 inline semantics (GCC 4.3 was the first
+// release to properly support C99 inline semantics), and therefore warned when
+// using 'extern inline' while in C99 mode unless `__attributes__((gnu_inline))`
+// was explicitly set.
+# define FORCE_GNU_INLINE 1
 #endif
 
-#elif defined(_MSC_VER)
-
-# define INLINE_HEADER __inline static
-# define INLINE_ME __inline
-# define STATIC_INLINE INLINE_HEADER
-
+#if FORCE_GNU_INLINE
+// Force compiler into gnu90 semantics
 # if defined(KEEP_INLINES)
-#  define EXTERN_INLINE __inline
+#  define EXTERN_INLINE inline __attribute__((gnu_inline))
 # else
-#  define EXTERN_INLINE __inline extern
+#  define EXTERN_INLINE extern inline __attribute__((gnu_inline))
+# endif
+#elif __GNUC_GNU_INLINE__
+// we're currently in gnu90 inline mode by default and
+// __attribute__((gnu_inline)) may not be supported, so better leave it off
+# if defined(KEEP_INLINES)
+#  define EXTERN_INLINE inline
+# else
+#  define EXTERN_INLINE extern inline
 # endif
-
 #else
-
-# error "Don't know how to inline functions with your C compiler."
-
+// Assume C99 semantics (yes, this curiously results in swapped definitions!)
+// This is the preferred branch, and at some point we may drop support for
+// compilers not supporting C99 semantics altogether.
+# if defined(KEEP_INLINES)
+#  define EXTERN_INLINE extern inline
+# else
+#  define EXTERN_INLINE inline
+# endif
 #endif
 
 



More information about the ghc-commits mailing list