From 7974c30b9fd84fa56ea1515ed2c08b38edf1a383 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 3 Sep 2021 16:44:02 +0200 Subject: [PATCH] bpo-45094: Add Py_NO_INLINE macro (GH-28140) * Rename _Py_NO_INLINE macro to Py_NO_INLINE: make it public and document it. * Sort macros in the C API documentation. --- Doc/c-api/intro.rst | 119 ++++++++++-------- Include/pymath.h | 7 +- Include/pyport.h | 25 ++-- .../2021-09-03-15-53-43.bpo-45094.tinXwL.rst | 2 + Modules/_functoolsmodule.c | 2 +- Modules/_io/bytesio.c | 2 +- Modules/_posixsubprocess.c | 4 +- Python/marshal.c | 2 +- 8 files changed, 87 insertions(+), 76 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2021-09-03-15-53-43.bpo-45094.tinXwL.rst diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst index 2d85d30702d..83824bb474f 100644 --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -105,6 +105,71 @@ defined closer to where they are useful (e.g. :c:macro:`Py_RETURN_NONE`). Others of a more general utility are defined here. This is not necessarily a complete listing. +.. c:macro:: Py_ABS(x) + + Return the absolute value of ``x``. + + .. versionadded:: 3.3 + +.. c:macro:: Py_CHARMASK(c) + + Argument must be a character or an integer in the range [-128, 127] or [0, + 255]. This macro returns ``c`` cast to an ``unsigned char``. + +.. c:macro:: Py_DEPRECATED(version) + + Use this for deprecated declarations. The macro must be placed before the + symbol name. + + Example:: + + Py_DEPRECATED(3.8) PyAPI_FUNC(int) Py_OldFunction(void); + + .. versionchanged:: 3.8 + MSVC support was added. + +.. c:macro:: Py_GETENV(s) + + Like ``getenv(s)``, but returns ``NULL`` if :option:`-E` was passed on the + command line (i.e. if ``Py_IgnoreEnvironmentFlag`` is set). + +.. c:macro:: Py_MAX(x, y) + + Return the maximum value between ``x`` and ``y``. + + .. versionadded:: 3.3 + +.. c:macro:: Py_MEMBER_SIZE(type, member) + + Return the size of a structure (``type``) ``member`` in bytes. + + .. versionadded:: 3.6 + +.. c:macro:: Py_MIN(x, y) + + Return the minimum value between ``x`` and ``y``. + + .. versionadded:: 3.3 + +.. c:macro:: Py_NO_INLINE + + Disable inlining on a function. For example, it reduces the C stack + consumption: useful on LTO+PGO builds which heavily inline code (see + :issue:`33720`). + + Usage:: + + Py_NO_INLINE static int random(void) { return 4; } + + .. versionadded:: 3.11 + +.. c:macro:: Py_STRINGIFY(x) + + Convert ``x`` to a C string. E.g. ``Py_STRINGIFY(123)`` returns + ``"123"``. + + .. versionadded:: 3.4 + .. c:macro:: Py_UNREACHABLE() Use this when you have a code path that cannot be reached by design. @@ -127,47 +192,6 @@ complete listing. .. versionadded:: 3.7 -.. c:macro:: Py_ABS(x) - - Return the absolute value of ``x``. - - .. versionadded:: 3.3 - -.. c:macro:: Py_MIN(x, y) - - Return the minimum value between ``x`` and ``y``. - - .. versionadded:: 3.3 - -.. c:macro:: Py_MAX(x, y) - - Return the maximum value between ``x`` and ``y``. - - .. versionadded:: 3.3 - -.. c:macro:: Py_STRINGIFY(x) - - Convert ``x`` to a C string. E.g. ``Py_STRINGIFY(123)`` returns - ``"123"``. - - .. versionadded:: 3.4 - -.. c:macro:: Py_MEMBER_SIZE(type, member) - - Return the size of a structure (``type``) ``member`` in bytes. - - .. versionadded:: 3.6 - -.. c:macro:: Py_CHARMASK(c) - - Argument must be a character or an integer in the range [-128, 127] or [0, - 255]. This macro returns ``c`` cast to an ``unsigned char``. - -.. c:macro:: Py_GETENV(s) - - Like ``getenv(s)``, but returns ``NULL`` if :option:`-E` was passed on the - command line (i.e. if ``Py_IgnoreEnvironmentFlag`` is set). - .. c:macro:: Py_UNUSED(arg) Use this for unused arguments in a function definition to silence compiler @@ -175,18 +199,6 @@ complete listing. .. versionadded:: 3.4 -.. c:macro:: Py_DEPRECATED(version) - - Use this for deprecated declarations. The macro must be placed before the - symbol name. - - Example:: - - Py_DEPRECATED(3.8) PyAPI_FUNC(int) Py_OldFunction(void); - - .. versionchanged:: 3.8 - MSVC support was added. - .. c:macro:: PyDoc_STRVAR(name, str) Creates a variable with name ``name`` that can be used in docstrings. @@ -221,6 +233,7 @@ complete listing. {NULL, NULL} }; + .. _api-objects: Objects, Types and Reference Counts diff --git a/Include/pymath.h b/Include/pymath.h index f869724334a..ebb3b05f1b5 100644 --- a/Include/pymath.h +++ b/Include/pymath.h @@ -163,12 +163,7 @@ PyAPI_FUNC(void) _Py_set_387controlword(unsigned short); #pragma float_control(push) #pragma float_control(precise, on) #pragma float_control(except, on) - #if defined(_MSC_VER) - __declspec(noinline) - #else /* Linux */ - __attribute__((noinline)) - #endif /* _MSC_VER */ - static double __icc_nan() + Py_NO_INLINE static double __icc_nan() { return sqrt(-1.0); } diff --git a/Include/pyport.h b/Include/pyport.h index b2b53dd2f77..0aaa4eedd31 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -557,19 +557,20 @@ extern "C" { #define _Py_HOT_FUNCTION #endif -/* _Py_NO_INLINE - * Disable inlining on a function. For example, it helps to reduce the C stack - * consumption. - * - * Usage: - * int _Py_NO_INLINE x(void) { return 3; } - */ -#if defined(_MSC_VER) -# define _Py_NO_INLINE __declspec(noinline) -#elif defined(__GNUC__) || defined(__clang__) -# define _Py_NO_INLINE __attribute__ ((noinline)) +// Py_NO_INLINE +// Disable inlining on a function. For example, it reduces the C stack +// consumption: useful on LTO+PGO builds which heavily inline code (see +// bpo-33720). +// +// Usage: +// +// Py_NO_INLINE static int random(void) { return 4; } +#if defined(__GNUC__) || defined(__clang__) || defined(__INTEL_COMPILER) +# define Py_NO_INLINE __attribute__ ((noinline)) +#elif defined(_MSC_VER) +# define Py_NO_INLINE __declspec(noinline) #else -# define _Py_NO_INLINE +# define Py_NO_INLINE #endif /************************************************************************** diff --git a/Misc/NEWS.d/next/C API/2021-09-03-15-53-43.bpo-45094.tinXwL.rst b/Misc/NEWS.d/next/C API/2021-09-03-15-53-43.bpo-45094.tinXwL.rst new file mode 100644 index 00000000000..84b01b23b43 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2021-09-03-15-53-43.bpo-45094.tinXwL.rst @@ -0,0 +1,2 @@ +Add the :c:macro:`Py_NO_INLINE` macro to disable inlining on a function. +Patch by Victor Stinner. diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index fa145216809..a93c0be6a14 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -186,7 +186,7 @@ partial_dealloc(partialobject *pto) /* Merging keyword arguments using the vectorcall convention is messy, so * if we would need to do that, we stop using vectorcall and fall back * to using partial_call() instead. */ -_Py_NO_INLINE static PyObject * +Py_NO_INLINE static PyObject * partial_vectorcall_fallback(PyThreadState *tstate, partialobject *pto, PyObject *const *args, size_t nargsf, PyObject *kwnames) diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index 2468f45f941..930ef7e29db 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -176,7 +176,7 @@ resize_buffer(bytesio *self, size_t size) object. Returns the number of bytes written, or -1 on error. Inlining is disabled because it's significantly decreases performance of writelines() in PGO build. */ -_Py_NO_INLINE static Py_ssize_t +Py_NO_INLINE static Py_ssize_t write_bytes(bytesio *self, PyObject *b) { if (check_closed(self)) { diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index a58159a277b..63207de8b91 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -451,7 +451,7 @@ reset_signal_handlers(const sigset_t *child_sigmask) * If vfork-unsafe functionality is desired after vfork(), consider using * syscall() to obtain it. */ -_Py_NO_INLINE static void +Py_NO_INLINE static void child_exec(char *const exec_array[], char *const argv[], char *const envp[], @@ -650,7 +650,7 @@ child_exec(char *const exec_array[], * child_exec() should not be inlined to avoid spurious -Wclobber warnings from * GCC (see bpo-35823). */ -_Py_NO_INLINE static pid_t +Py_NO_INLINE static pid_t do_fork_exec(char *const exec_array[], char *const argv[], char *const envp[], diff --git a/Python/marshal.c b/Python/marshal.c index 60b818f0dda..346384edea6 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -891,7 +891,7 @@ r_float_bin(RFILE *p) /* Issue #33720: Disable inlining for reducing the C stack consumption on PGO builds. */ -_Py_NO_INLINE static double +Py_NO_INLINE static double r_float_str(RFILE *p) { int n;