[Mesa-dev] [PATCH 02/12] mesa: Replace a priori knowledge of gcc builtins with configure tests.

Matt Turner mattst88 at gmail.com
Mon Sep 22 11:50:59 PDT 2014


Presumbly this will let clang and other compilers use the built-ins as
well.

Notice two changes specifically:
   - in _mesa_next_pow_two_64(), always use __builtin_clzll and add a
     static assertion that this is safe.
   - in macros.h, remove the clang-specific definition since it should
     be able to detect __builtin_unreachable in configure.
---
 configure.ac                                 |  8 +++++++
 src/mesa/drivers/dri/i965/brw_blorp_blit.cpp |  2 +-
 src/mesa/main/imports.c                      | 12 ++++++----
 src/mesa/main/imports.h                      | 35 +++++++++++++++-------------
 src/util/macros.h                            | 14 +++--------
 5 files changed, 38 insertions(+), 33 deletions(-)

diff --git a/configure.ac b/configure.ac
index 12f914e..6b0adbc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -132,6 +132,14 @@ fi
 dnl Check for compiler builtins
 AX_GCC_BUILTIN([__builtin_bswap32])
 AX_GCC_BUILTIN([__builtin_bswap64])
+AX_GCC_BUILTIN([__builtin_clz])
+AX_GCC_BUILTIN([__builtin_clzll])
+AX_GCC_BUILTIN([__builtin_ctz])
+AX_GCC_BUILTIN([__builtin_ffs])
+AX_GCC_BUILTIN([__builtin_ffsll])
+AX_GCC_BUILTIN([__builtin_popcount])
+AX_GCC_BUILTIN([__builtin_popcountll])
+AX_GCC_BUILTIN([__builtin_unreachable])
 
 AM_CONDITIONAL([GEN_ASM_OFFSETS], test "x$GEN_ASM_OFFSETS" = xyes)
 
diff --git a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
index 105acdd..844f5e4 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
+++ b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
@@ -1343,7 +1343,7 @@ brw_blorp_blit_program::single_to_blend()
  */
 inline int count_trailing_one_bits(unsigned value)
 {
-#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
+#ifdef HAVE___BUILTIN_CTZ
    return __builtin_ctz(~value);
 #else
    return _mesa_bitcount(value & ~(value + 1));
diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c
index c5a7d63..bbfaf54 100644
--- a/src/mesa/main/imports.c
+++ b/src/mesa/main/imports.c
@@ -217,7 +217,7 @@ _mesa_align_realloc(void *oldBuffer, size_t oldSize, size_t newSize,
 /*@{*/
 
 
-#ifndef __GNUC__
+#ifndef HAVE___BUILTIN_FFS
 /**
  * Find the first bit set in a word.
  */
@@ -246,8 +246,9 @@ ffs(int i)
    }
    return bit;
 }
+#endif
 
-
+#ifndef HAVE___BUILTIN_FFSLL
 /**
  * Find position of first bit set in given value.
  * XXX Warning: this function can only be used on 64-bit systems!
@@ -271,11 +272,10 @@ ffsll(long long int val)
 
    return 0;
 }
-#endif /* __GNUC__ */
+#endif
 
 
-#if !defined(__GNUC__) ||\
-   ((__GNUC__ * 100 + __GNUC_MINOR__) < 304) /* Not gcc 3.4 or later */
+#ifndef HAVE___BUILTIN_POPCOUNT
 /**
  * Return number of bits set in given GLuint.
  */
@@ -288,7 +288,9 @@ _mesa_bitcount(unsigned int n)
    }
    return bits;
 }
+#endif
 
+#ifndef HAVE___BUILTIN_POPCOUNTLL
 /**
  * Return number of bits set in given 64-bit uint.
  */
diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h
index 8dbcf83..967eebc 100644
--- a/src/mesa/main/imports.h
+++ b/src/mesa/main/imports.h
@@ -377,8 +377,7 @@ _mesa_is_pow_two(int x)
 static inline int32_t
 _mesa_next_pow_two_32(uint32_t x)
 {
-#if defined(__GNUC__) && \
-	((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
+#ifdef HAVE___BUILTIN_CLZ
 	uint32_t y = (x != 1);
 	return (1 + y) << ((__builtin_clz(x - y) ^ 31) );
 #else
@@ -396,13 +395,10 @@ _mesa_next_pow_two_32(uint32_t x)
 static inline int64_t
 _mesa_next_pow_two_64(uint64_t x)
 {
-#if defined(__GNUC__) && \
-	((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
+#ifdef HAVE___BUILTIN_CLZLL
 	uint64_t y = (x != 1);
-	if (sizeof(x) == sizeof(long))
-		return (1 + y) << ((__builtin_clzl(x - y) ^ 63));
-	else
-		return (1 + y) << ((__builtin_clzll(x - y) ^ 63));
+	STATIC_ASSERT(sizeof(x) == sizeof(long long));
+	return (1 + y) << ((__builtin_clzll(x - y) ^ 63));
 #else
 	x--;
 	x |= x >> 1;
@@ -423,8 +419,7 @@ _mesa_next_pow_two_64(uint64_t x)
 static inline GLuint
 _mesa_logbase2(GLuint n)
 {
-#if defined(__GNUC__) && \
-   ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
+#ifdef HAVE___BUILTIN_CLZ
    return (31 - __builtin_clz(n | 1));
 #else
    GLuint pos = 0;
@@ -476,22 +471,30 @@ _mesa_exec_free( void *addr );
 
 #ifndef FFS_DEFINED
 #define FFS_DEFINED 1
-#ifdef __GNUC__
+#ifdef HAVE___BUILTIN_FFS
 #define ffs __builtin_ffs
-#define ffsll __builtin_ffsll
 #else
 extern int ffs(int i);
+#endif
+
+#ifdef HAVE___BUILTIN_FFSLL
+#define ffsll __builtin_ffsll
+#else
 extern int ffsll(long long int i);
-#endif /*__ GNUC__ */
+#endif
 #endif /* FFS_DEFINED */
 
 
-#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
+#ifdef HAVE___BUILTIN_POPCOUNT
 #define _mesa_bitcount(i) __builtin_popcount(i)
-#define _mesa_bitcount_64(i) __builtin_popcountll(i)
 #else
 extern unsigned int
 _mesa_bitcount(unsigned int n);
+#endif
+
+#ifdef HAVE___BUILTIN_POPCOUNTLL
+#define _mesa_bitcount_64(i) __builtin_popcountll(i)
+#else
 extern unsigned int
 _mesa_bitcount_64(uint64_t n);
 #endif
@@ -504,7 +507,7 @@ _mesa_bitcount_64(uint64_t n);
 static inline unsigned int
 _mesa_fls(unsigned int n)
 {
-#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304)
+#ifdef HAVE___BUILTIN_CLZ
    return n == 0 ? 0 : 32 - __builtin_clz(n);
 #else
    unsigned int v = 1;
diff --git a/src/util/macros.h b/src/util/macros.h
index ee05e05..2e2f90f 100644
--- a/src/util/macros.h
+++ b/src/util/macros.h
@@ -33,12 +33,12 @@
 /**
  * __builtin_expect macros
  */
-#if !defined(__GNUC__)
+#if !defined(HAVE___BUILTIN_EXPECT)
 #  define __builtin_expect(x, y) (x)
 #endif
 
 #ifndef likely
-#  ifdef __GNUC__
+#  ifdef HAVE___BUILTIN_EXPECT
 #    define likely(x)   __builtin_expect(!!(x), 1)
 #    define unlikely(x) __builtin_expect(!!(x), 0)
 #  else
@@ -63,20 +63,12 @@
  * Unreachable macro. Useful for suppressing "control reaches end of non-void
  * function" warnings.
  */
-#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 5
+#ifdef HAVE___BUILTIN_UNREACHABLE
 #define unreachable(str)    \
 do {                        \
    assert(!str);            \
    __builtin_unreachable(); \
 } while (0)
-#elif (defined(__clang__) && defined(__has_builtin))
-# if __has_builtin(__builtin_unreachable)
-#  define unreachable(str)  \
-do {                        \
-   assert(!str);            \
-   __builtin_unreachable(); \
-} while (0)
-# endif
 #endif
 
 #ifndef unreachable
-- 
1.8.5.5



More information about the mesa-dev mailing list