summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bignum.c14
-rw-r--r--configure.ac1
-rw-r--r--st.c10
-rw-r--r--string.c11
4 files changed, 29 insertions, 7 deletions
diff --git a/bignum.c b/bignum.c
index 6656d28ea4..40d5d0e224 100644
--- a/bignum.c
+++ b/bignum.c
@@ -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)])
diff --git a/st.c b/st.c
index 5ca6263db0..2e7fc6bfde 100644
--- a/st.c
+++ b/st.c
@@ -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);
}
diff --git a/string.c b/string.c
index 63b4d57f82..9902b0feb3 100644
--- a/string.c
+++ b/string.c
@@ -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