Skip to content

Commit

Permalink
pyport: add new macros
Browse files Browse the repository at this point in the history
This adds _PY_LIKELY, _PY_UNLIKELY, _Py_ALWAYS_INLINE, and macros to
test for SSE2 and NEON support.
  • Loading branch information
colesbury committed Apr 16, 2023
1 parent f30d8d8 commit 385eb1d
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 34 deletions.
65 changes: 65 additions & 0 deletions Include/pyport.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,14 @@ typedef Py_ssize_t Py_ssize_clean_t;
# define PY_FORMAT_SIZE_T "z"
#endif

#if defined(__SSE2__)
#define HAVE_SSE2 1
#elif defined(_MSC_VER) && (defined(_M_X64) || (defined(_M_IX86) && _M_IX86_FP >= 2))
#define HAVE_SSE2 1
#elif defined(__ARM_NEON) || defined(__ARM_NEON__)
#define HAVE_NEON 1
#endif

/* Py_LOCAL can be used instead of static to get the fastest possible calling
* convention for functions that are local to a given module.
*
Expand Down Expand Up @@ -340,6 +348,20 @@ extern "C" {
#define _Py_COMP_DIAG_POP
#endif

/* _Py_LIKELY and _PY_UNLIKELY
* Provides the compiler with branch prediction information.
*
* Usage:
* if (_PY_UNLIKELY(x == NULL)) { ... }
*/
#if defined(__GNUC__)
# define _PY_LIKELY(x) __builtin_expect((x),1)
# define _PY_UNLIKELY(x) __builtin_expect((x),0)
#else
# define _PY_LIKELY(x) (x)
# define _PY_UNLIKELY(x) (x)
#endif

/* _Py_HOT_FUNCTION
* The hot attribute on a function is used to inform the compiler that the
* function is a hot spot of the compiled program. The function is optimized
Expand Down Expand Up @@ -409,6 +431,14 @@ extern "C" {
# define Py_NO_INLINE
#endif

#if defined(_MSC_VER)
# define _Py_ALWAYS_INLINE __forceinline
#elif defined(__GNUC__) || defined(__clang__)
# define _Py_ALWAYS_INLINE inline __attribute__ ((always_inline))
#else
# define _Py_ALWAYS_INLINE inline
#endif

/**************************************************************************
Prototypes that are missing from the standard include files on some systems
(and possibly only some versions of such systems.)
Expand Down Expand Up @@ -602,6 +632,12 @@ extern char * _getpty(int *, int, mode_t, int);
#define Py_ALIGNED(x)
#endif

#ifdef _MSC_VER
#define Py_DECL_THREAD __declspec(thread)
#else
#define Py_DECL_THREAD __thread
#endif

/* Eliminate end-of-loop code not reached warnings from SunPro C
* when using do{...}while(0) macros
*/
Expand Down Expand Up @@ -720,10 +756,39 @@ extern char * _getpty(int *, int, mode_t, int);
# define _Py_ADDRESS_SANITIZER
# endif
# endif
# if __has_feature(thread_sanitizer)
# if !defined(_Py_THREAD_SANITIZER)
# define _Py_THREAD_SANITIZER
# endif
# endif
#elif defined(__GNUC__)
# if defined(__SANITIZE_ADDRESS__)
# define _Py_ADDRESS_SANITIZER
# endif
# if defined(__SANITIZE_THREAD__)
# define _Py_THREAD_SANITIZER
# endif
#endif

#if defined(_Py_MEMORY_SANITIZER)
# define _Py_NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory))
#else
# define _Py_NO_SANITIZE_MEMORY
#endif

#if defined(_Py_ADDRESS_SANITIZER)
# define _Py_NO_SANITIZE_ADDRESS __attribute__((no_sanitize("address")))
#else
# define _Py_NO_SANITIZE_ADDRESS
#endif

// TSAN is supported since GCC 5.1, but __SANITIZE_THREAD__ macro is provided
// only since GCC 7.
#if defined(_Py_THREAD_SANITIZER) || (__GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1))
# define _Py_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread))
#else
# define _Py_NO_SANITIZE_THREAD
#endif


#endif /* Py_PYPORT_H */
34 changes: 0 additions & 34 deletions Objects/obmalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,40 +167,6 @@ _PyMem_ArenaFree(void *Py_UNUSED(ctx), void *ptr,
/*******************************************/


#if defined(__has_feature) /* Clang */
# if __has_feature(address_sanitizer) /* is ASAN enabled? */
# define _Py_NO_SANITIZE_ADDRESS \
__attribute__((no_sanitize("address")))
# endif
# if __has_feature(thread_sanitizer) /* is TSAN enabled? */
# define _Py_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread))
# endif
# if __has_feature(memory_sanitizer) /* is MSAN enabled? */
# define _Py_NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory))
# endif
#elif defined(__GNUC__)
# if defined(__SANITIZE_ADDRESS__) /* GCC 4.8+, is ASAN enabled? */
# define _Py_NO_SANITIZE_ADDRESS \
__attribute__((no_sanitize_address))
# endif
// TSAN is supported since GCC 5.1, but __SANITIZE_THREAD__ macro
// is provided only since GCC 7.
# if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1)
# define _Py_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread))
# endif
#endif

#ifndef _Py_NO_SANITIZE_ADDRESS
# define _Py_NO_SANITIZE_ADDRESS
#endif
#ifndef _Py_NO_SANITIZE_THREAD
# define _Py_NO_SANITIZE_THREAD
#endif
#ifndef _Py_NO_SANITIZE_MEMORY
# define _Py_NO_SANITIZE_MEMORY
#endif


#define _PyMem_Raw (_PyRuntime.allocators.standard.raw)
#define _PyMem (_PyRuntime.allocators.standard.mem)
#define _PyObject (_PyRuntime.allocators.standard.obj)
Expand Down

0 comments on commit 385eb1d

Please sign in to comment.