mesa: Replace a priori knowledge of gcc builtins with configure tests.
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. Reviewed-by: Jason Ekstrand <jason.ekstrand@intel.com> [C bits] Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
This commit is contained in:
@@ -130,6 +130,15 @@ fi
|
|||||||
dnl Check for compiler builtins
|
dnl Check for compiler builtins
|
||||||
AX_GCC_BUILTIN([__builtin_bswap32])
|
AX_GCC_BUILTIN([__builtin_bswap32])
|
||||||
AX_GCC_BUILTIN([__builtin_bswap64])
|
AX_GCC_BUILTIN([__builtin_bswap64])
|
||||||
|
AX_GCC_BUILTIN([__builtin_clz])
|
||||||
|
AX_GCC_BUILTIN([__builtin_clzll])
|
||||||
|
AX_GCC_BUILTIN([__builtin_ctz])
|
||||||
|
AX_GCC_BUILTIN([__builtin_expect])
|
||||||
|
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)
|
AM_CONDITIONAL([GEN_ASM_OFFSETS], test "x$GEN_ASM_OFFSETS" = xyes)
|
||||||
|
|
||||||
|
@@ -583,6 +583,24 @@ def generate(env):
|
|||||||
env.Append(CCFLAGS = ['-fopenmp'])
|
env.Append(CCFLAGS = ['-fopenmp'])
|
||||||
env.Append(LIBS = ['gomp'])
|
env.Append(LIBS = ['gomp'])
|
||||||
|
|
||||||
|
if gcc_compat:
|
||||||
|
ccversion = env['CCVERSION']
|
||||||
|
cppdefines += [
|
||||||
|
'HAVE___BUILTIN_EXPECT',
|
||||||
|
'HAVE___BUILTIN_FFS',
|
||||||
|
'HAVE___BUILTIN_FFSLL',
|
||||||
|
]
|
||||||
|
if distutils.version.LooseVersion(ccversion) >= distutils.version.LooseVersion('3.4'):
|
||||||
|
cppdefines += [
|
||||||
|
'HAVE___BUILTIN_CTZ',
|
||||||
|
'HAVE___BUILTIN_POPCOUNT',
|
||||||
|
'HAVE___BUILTIN_POPCOUNTLL',
|
||||||
|
'HAVE___BUILTIN_CLZ',
|
||||||
|
'HAVE___BUILTIN_CLZLL',
|
||||||
|
]
|
||||||
|
if distutils.version.LooseVersion(ccversion) >= distutils.version.LooseVersion('4.5'):
|
||||||
|
cppdefines += ['HAVE___BUILTIN_UNREACHABLE']
|
||||||
|
|
||||||
# Load tools
|
# Load tools
|
||||||
env.Tool('lex')
|
env.Tool('lex')
|
||||||
env.Tool('yacc')
|
env.Tool('yacc')
|
||||||
|
@@ -1343,7 +1343,7 @@ brw_blorp_blit_program::single_to_blend()
|
|||||||
*/
|
*/
|
||||||
inline int count_trailing_one_bits(unsigned value)
|
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);
|
return __builtin_ctz(~value);
|
||||||
#else
|
#else
|
||||||
return _mesa_bitcount(value & ~(value + 1));
|
return _mesa_bitcount(value & ~(value + 1));
|
||||||
|
@@ -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.
|
* Find the first bit set in a word.
|
||||||
*/
|
*/
|
||||||
@@ -246,8 +246,9 @@ ffs(int i)
|
|||||||
}
|
}
|
||||||
return bit;
|
return bit;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE___BUILTIN_FFSLL
|
||||||
/**
|
/**
|
||||||
* Find position of first bit set in given value.
|
* Find position of first bit set in given value.
|
||||||
* XXX Warning: this function can only be used on 64-bit systems!
|
* XXX Warning: this function can only be used on 64-bit systems!
|
||||||
@@ -271,11 +272,10 @@ ffsll(long long int val)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* __GNUC__ */
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if !defined(__GNUC__) ||\
|
#ifndef HAVE___BUILTIN_POPCOUNT
|
||||||
((__GNUC__ * 100 + __GNUC_MINOR__) < 304) /* Not gcc 3.4 or later */
|
|
||||||
/**
|
/**
|
||||||
* Return number of bits set in given GLuint.
|
* Return number of bits set in given GLuint.
|
||||||
*/
|
*/
|
||||||
@@ -288,7 +288,9 @@ _mesa_bitcount(unsigned int n)
|
|||||||
}
|
}
|
||||||
return bits;
|
return bits;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE___BUILTIN_POPCOUNTLL
|
||||||
/**
|
/**
|
||||||
* Return number of bits set in given 64-bit uint.
|
* Return number of bits set in given 64-bit uint.
|
||||||
*/
|
*/
|
||||||
|
@@ -377,8 +377,7 @@ _mesa_is_pow_two(int x)
|
|||||||
static inline int32_t
|
static inline int32_t
|
||||||
_mesa_next_pow_two_32(uint32_t x)
|
_mesa_next_pow_two_32(uint32_t x)
|
||||||
{
|
{
|
||||||
#if defined(__GNUC__) && \
|
#ifdef HAVE___BUILTIN_CLZ
|
||||||
((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
|
|
||||||
uint32_t y = (x != 1);
|
uint32_t y = (x != 1);
|
||||||
return (1 + y) << ((__builtin_clz(x - y) ^ 31) );
|
return (1 + y) << ((__builtin_clz(x - y) ^ 31) );
|
||||||
#else
|
#else
|
||||||
@@ -396,13 +395,10 @@ _mesa_next_pow_two_32(uint32_t x)
|
|||||||
static inline int64_t
|
static inline int64_t
|
||||||
_mesa_next_pow_two_64(uint64_t x)
|
_mesa_next_pow_two_64(uint64_t x)
|
||||||
{
|
{
|
||||||
#if defined(__GNUC__) && \
|
#ifdef HAVE___BUILTIN_CLZLL
|
||||||
((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
|
|
||||||
uint64_t y = (x != 1);
|
uint64_t y = (x != 1);
|
||||||
if (sizeof(x) == sizeof(long))
|
STATIC_ASSERT(sizeof(x) == sizeof(long long));
|
||||||
return (1 + y) << ((__builtin_clzl(x - y) ^ 63));
|
return (1 + y) << ((__builtin_clzll(x - y) ^ 63));
|
||||||
else
|
|
||||||
return (1 + y) << ((__builtin_clzll(x - y) ^ 63));
|
|
||||||
#else
|
#else
|
||||||
x--;
|
x--;
|
||||||
x |= x >> 1;
|
x |= x >> 1;
|
||||||
@@ -423,8 +419,7 @@ _mesa_next_pow_two_64(uint64_t x)
|
|||||||
static inline GLuint
|
static inline GLuint
|
||||||
_mesa_logbase2(GLuint n)
|
_mesa_logbase2(GLuint n)
|
||||||
{
|
{
|
||||||
#if defined(__GNUC__) && \
|
#ifdef HAVE___BUILTIN_CLZ
|
||||||
((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
|
|
||||||
return (31 - __builtin_clz(n | 1));
|
return (31 - __builtin_clz(n | 1));
|
||||||
#else
|
#else
|
||||||
GLuint pos = 0;
|
GLuint pos = 0;
|
||||||
@@ -476,22 +471,30 @@ _mesa_exec_free( void *addr );
|
|||||||
|
|
||||||
#ifndef FFS_DEFINED
|
#ifndef FFS_DEFINED
|
||||||
#define FFS_DEFINED 1
|
#define FFS_DEFINED 1
|
||||||
#ifdef __GNUC__
|
#ifdef HAVE___BUILTIN_FFS
|
||||||
#define ffs __builtin_ffs
|
#define ffs __builtin_ffs
|
||||||
#define ffsll __builtin_ffsll
|
|
||||||
#else
|
#else
|
||||||
extern int ffs(int i);
|
extern int ffs(int i);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE___BUILTIN_FFSLL
|
||||||
|
#define ffsll __builtin_ffsll
|
||||||
|
#else
|
||||||
extern int ffsll(long long int i);
|
extern int ffsll(long long int i);
|
||||||
#endif /*__ GNUC__ */
|
#endif
|
||||||
#endif /* FFS_DEFINED */
|
#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(i) __builtin_popcount(i)
|
||||||
#define _mesa_bitcount_64(i) __builtin_popcountll(i)
|
|
||||||
#else
|
#else
|
||||||
extern unsigned int
|
extern unsigned int
|
||||||
_mesa_bitcount(unsigned int n);
|
_mesa_bitcount(unsigned int n);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE___BUILTIN_POPCOUNTLL
|
||||||
|
#define _mesa_bitcount_64(i) __builtin_popcountll(i)
|
||||||
|
#else
|
||||||
extern unsigned int
|
extern unsigned int
|
||||||
_mesa_bitcount_64(uint64_t n);
|
_mesa_bitcount_64(uint64_t n);
|
||||||
#endif
|
#endif
|
||||||
@@ -504,7 +507,7 @@ _mesa_bitcount_64(uint64_t n);
|
|||||||
static inline unsigned int
|
static inline unsigned int
|
||||||
_mesa_fls(unsigned int n)
|
_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);
|
return n == 0 ? 0 : 32 - __builtin_clz(n);
|
||||||
#else
|
#else
|
||||||
unsigned int v = 1;
|
unsigned int v = 1;
|
||||||
|
@@ -33,12 +33,12 @@
|
|||||||
/**
|
/**
|
||||||
* __builtin_expect macros
|
* __builtin_expect macros
|
||||||
*/
|
*/
|
||||||
#if !defined(__GNUC__)
|
#if !defined(HAVE___BUILTIN_EXPECT)
|
||||||
# define __builtin_expect(x, y) (x)
|
# define __builtin_expect(x, y) (x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef likely
|
#ifndef likely
|
||||||
# ifdef __GNUC__
|
# ifdef HAVE___BUILTIN_EXPECT
|
||||||
# define likely(x) __builtin_expect(!!(x), 1)
|
# define likely(x) __builtin_expect(!!(x), 1)
|
||||||
# define unlikely(x) __builtin_expect(!!(x), 0)
|
# define unlikely(x) __builtin_expect(!!(x), 0)
|
||||||
# else
|
# else
|
||||||
@@ -63,20 +63,12 @@
|
|||||||
* Unreachable macro. Useful for suppressing "control reaches end of non-void
|
* Unreachable macro. Useful for suppressing "control reaches end of non-void
|
||||||
* function" warnings.
|
* function" warnings.
|
||||||
*/
|
*/
|
||||||
#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 5
|
#ifdef HAVE___BUILTIN_UNREACHABLE
|
||||||
#define unreachable(str) \
|
#define unreachable(str) \
|
||||||
do { \
|
do { \
|
||||||
assert(!str); \
|
assert(!str); \
|
||||||
__builtin_unreachable(); \
|
__builtin_unreachable(); \
|
||||||
} while (0)
|
} 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
|
#endif
|
||||||
|
|
||||||
#ifndef unreachable
|
#ifndef unreachable
|
||||||
|
Reference in New Issue
Block a user