diff options
-rw-r--r-- | bignum.c | 14 | ||||
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | st.c | 10 | ||||
-rw-r--r-- | string.c | 11 |
4 files changed, 29 insertions, 7 deletions
@@ -1079,6 +1079,13 @@ integer_unpack_single_bdigit(BDIGIT u, size_t size, int flags, BDIGIT *dp) return sign; } +#ifdef HAVE_BUILTIN___BUILTIN_ASSUME_ALIGNED +#define reinterpret_cast(type, value) (type) \ + __builtin_assume_aligned((value), sizeof(*(type)NULL)); +#else +#define reinterpret_cast(type, value) (type)value +#endif + static int bary_unpack_internal(BDIGIT *bdigits, size_t num_bdigits, const void *words, size_t numwords, size_t wordsize, size_t nails, int flags, int nlp_bits) { @@ -1100,22 +1107,23 @@ bary_unpack_internal(BDIGIT *bdigits, size_t num_bdigits, const void *words, siz } #if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT if (wordsize == 2 && (uintptr_t)words % RUBY_ALIGNOF(uint16_t) == 0) { - uint16_t u = *(uint16_t *)buf; + uint16_t u = *reinterpret_cast(const uint16_t *, buf); return integer_unpack_single_bdigit(need_swap ? swap16(u) : u, sizeof(uint16_t), flags, dp); } #endif #if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT if (wordsize == 4 && (uintptr_t)words % RUBY_ALIGNOF(uint32_t) == 0) { - uint32_t u = *(uint32_t *)buf; + uint32_t u = *reinterpret_cast(const uint32_t *, buf); return integer_unpack_single_bdigit(need_swap ? swap32(u) : u, sizeof(uint32_t), flags, dp); } #endif #if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT if (wordsize == 8 && (uintptr_t)words % RUBY_ALIGNOF(uint64_t) == 0) { - uint64_t u = *(uint64_t *)buf; + uint64_t u = *reinterpret_cast(const uint64_t *, buf); return integer_unpack_single_bdigit(need_swap ? swap64(u) : u, sizeof(uint64_t), flags, dp); } #endif +#undef reinterpret_cast } #if !defined(WORDS_BIGENDIAN) if (nails == 0 && SIZEOF_BDIGIT == sizeof(BDIGIT) && diff --git a/configure.ac b/configure.ac index 49c2b76bd3..e5be5a778e 100644 --- a/configure.ac +++ b/configure.ac @@ -2493,6 +2493,7 @@ AC_CACHE_CHECK([for $1], AS_TR_SH(rb_cv_builtin_$1), AS_IF([test "${AS_TR_SH(rb_cv_builtin_$1)}" != no], [ AC_DEFINE(AS_TR_CPP(HAVE_BUILTIN_$1)) ])]) +RUBY_CHECK_BUILTIN_FUNC(__builtin_assume_aligned, [__builtin_assume_aligned((void*)32, 32)]) RUBY_CHECK_BUILTIN_FUNC(__builtin_bswap16, [__builtin_bswap16(0)]) RUBY_CHECK_BUILTIN_FUNC(__builtin_bswap32, [__builtin_bswap32(0)]) RUBY_CHECK_BUILTIN_FUNC(__builtin_bswap64, [__builtin_bswap64(0)]) @@ -1816,9 +1816,14 @@ st_hash(const void *ptr, size_t len, st_index_t h) } else #endif +#ifdef HAVE_BUILTIN___BUILTIN_ASSUME_ALIGNED +#define aligned_data __builtin_assume_aligned(data, sizeof(st_index_t)) +#else +#define aligned_data data +#endif { do { - h = murmur_step(h, *(st_index_t *)data); + h = murmur_step(h, *(st_index_t *)aligned_data); data += sizeof(st_index_t); len -= sizeof(st_index_t); } while (len >= sizeof(st_index_t)); @@ -1834,7 +1839,7 @@ st_hash(const void *ptr, size_t len, st_index_t h) case 6: t |= data_at(5) << 40; case 5: t |= data_at(4) << 32; case 4: - t |= (st_index_t)*(uint32_t*)data; + t |= (st_index_t)*(uint32_t*)aligned_data; goto skip_tail; # define SKIP_TAIL 1 #endif @@ -1859,6 +1864,7 @@ st_hash(const void *ptr, size_t len, st_index_t h) h *= C2; } h ^= l; +#undef aligned_data return murmur_finish(h); } @@ -481,8 +481,15 @@ search_nonascii(const char *p, const char *e) } } #endif - s = (const uintptr_t *)p; - t = (const uintptr_t *)(e - (SIZEOF_VOIDP-1)); +#ifdef HAVE_BUILTIN___BUILTIN_ASSUME_ALIGNED +#define aligned_ptr(value) \ + __builtin_assume_aligned((value), sizeof(uintptr_t *)) +#else +#define aligned_ptr(value) (uintptr_t *)(value) +#endif + s = aligned_ptr(p); + t = aligned_ptr(e - (SIZEOF_VOIDP-1)); +#undef aligned_ptr for (;s < t; s++) { if (*s & NONASCII_MASK) { #ifdef WORDS_BIGENDIAN |