summaryrefslogtreecommitdiff
path: root/numpy/core
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/core')
-rw-r--r--numpy/core/include/numpy/npy_common.h18
-rw-r--r--numpy/core/setup_common.py1
-rw-r--r--numpy/core/src/multiarray/common.h12
3 files changed, 28 insertions, 3 deletions
diff --git a/numpy/core/include/numpy/npy_common.h b/numpy/core/include/numpy/npy_common.h
index ac2e631e6..e5fd09e91 100644
--- a/numpy/core/include/numpy/npy_common.h
+++ b/numpy/core/include/numpy/npy_common.h
@@ -18,6 +18,24 @@
#define NPY_GCC_UNROLL_LOOPS
#endif
+/*
+ * give a hint to the compiler which branch is more likely or unlikely
+ * to occur, e.g. rare error cases:
+ *
+ * if (NPY_UNLIKELY(failure == 0))
+ * return NULL;
+ *
+ * the double !! is to cast the expression (e.g. NULL) to a boolean required by
+ * the intrinsic
+ */
+#ifdef HAVE___BUILTIN_EXPECT
+#define NPY_LIKELY(x) __builtin_expect(!!(x), 1)
+#define NPY_UNLIKELY(x) __builtin_expect(!!(x), 0)
+#else
+#define NPY_LIKELY(x) (x)
+#define NPY_UNLIKELY(x) (x)
+#endif
+
#if defined(_MSC_VER)
#define NPY_INLINE __inline
#elif defined(__GNUC__)
diff --git a/numpy/core/setup_common.py b/numpy/core/setup_common.py
index 9f745e965..9a630225d 100644
--- a/numpy/core/setup_common.py
+++ b/numpy/core/setup_common.py
@@ -111,6 +111,7 @@ OPTIONAL_INTRINSICS = [("__builtin_isnan", '5.'),
("__builtin_isfinite", '5.'),
("__builtin_bswap32", '5u'),
("__builtin_bswap64", '5u'),
+ ("__builtin_expect", '5, 0'),
]
# gcc function attributes
diff --git a/numpy/core/src/multiarray/common.h b/numpy/core/src/multiarray/common.h
index 636d9c67d..82b66123c 100644
--- a/numpy/core/src/multiarray/common.h
+++ b/numpy/core/src/multiarray/common.h
@@ -1,5 +1,6 @@
#ifndef _NPY_PRIVATE_COMMON_H_
#define _NPY_PRIVATE_COMMON_H_
+#include <numpy/npy_common.h>
#define error_converting(x) (((x) == -1) && PyErr_Occurred())
@@ -71,11 +72,16 @@ offset_bounds_from_strides(const int itemsize, const int nd,
static NPY_INLINE int
npy_is_aligned(const void * p, const npy_uintp alignment)
{
- /* test for the and is still faster than a direct modulo */
- if ((alignment & (alignment - 1)) == 0)
+ /*
+ * alignment is usually a power of two
+ * the test is faster than a direct modulo
+ */
+ if (NPY_LIKELY((alignment & (alignment - 1)) == 0)) {
return ((npy_uintp)(p) & ((alignment) - 1)) == 0;
- else
+ }
+ else {
return ((npy_uintp)(p) % alignment) == 0;
+ }
}