]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-45094: Add Py_NO_INLINE macro (GH-28140)
authorVictor Stinner <vstinner@python.org>
Fri, 3 Sep 2021 14:44:02 +0000 (16:44 +0200)
committerGitHub <noreply@github.com>
Fri, 3 Sep 2021 14:44:02 +0000 (16:44 +0200)
* 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
Include/pymath.h
Include/pyport.h
Misc/NEWS.d/next/C API/2021-09-03-15-53-43.bpo-45094.tinXwL.rst [new file with mode: 0644]
Modules/_functoolsmodule.c
Modules/_io/bytesio.c
Modules/_posixsubprocess.c
Python/marshal.c

index 2d85d30702df9c5ea133f73b321ed6e2e8da017f..83824bb474fbd89827d286f656ee59cb35aa843d 100644 (file)
@@ -105,45 +105,63 @@ 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_UNREACHABLE()
+.. c:macro:: Py_ABS(x)
 
-   Use this when you have a code path that cannot be reached by design.
-   For example, in the ``default:`` clause in a ``switch`` statement for which
-   all possible values are covered in ``case`` statements.  Use this in places
-   where you might be tempted to put an ``assert(0)`` or ``abort()`` call.
+   Return the absolute value of ``x``.
 
-   In release mode, the macro helps the compiler to optimize the code, and
-   avoids a warning about unreachable code.  For example, the macro is
-   implemented with ``__builtin_unreachable()`` on GCC in release mode.
+   .. versionadded:: 3.3
 
-   A use for ``Py_UNREACHABLE()`` is following a call a function that
-   never returns but that is not declared :c:macro:`_Py_NO_RETURN`.
+.. c:macro:: Py_CHARMASK(c)
 
-   If a code path is very unlikely code but can be reached under exceptional
-   case, this macro must not be used.  For example, under low memory condition
-   or if a system call returns a value out of the expected range.  In this
-   case, it's better to report the error to the caller.  If the error cannot
-   be reported to caller, :c:func:`Py_FatalError` can be used.
+   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``.
 
-   .. versionadded:: 3.7
+.. c:macro:: Py_DEPRECATED(version)
 
-.. c:macro:: Py_ABS(x)
+   Use this for deprecated declarations.  The macro must be placed before the
+   symbol name.
 
-   Return the absolute value of ``x``.
+   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_MAX(x, y)
+.. c:macro:: Py_NO_INLINE
 
-   Return the maximum value between ``x`` and ``y``.
+   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`).
 
-   .. versionadded:: 3.3
+   Usage::
+
+       Py_NO_INLINE static int random(void) { return 4; }
+
+   .. versionadded:: 3.11
 
 .. c:macro:: Py_STRINGIFY(x)
 
@@ -152,21 +170,27 @@ complete listing.
 
    .. versionadded:: 3.4
 
-.. c:macro:: Py_MEMBER_SIZE(type, member)
-
-   Return the size of a structure (``type``) ``member`` in bytes.
+.. c:macro:: Py_UNREACHABLE()
 
-   .. versionadded:: 3.6
+   Use this when you have a code path that cannot be reached by design.
+   For example, in the ``default:`` clause in a ``switch`` statement for which
+   all possible values are covered in ``case`` statements.  Use this in places
+   where you might be tempted to put an ``assert(0)`` or ``abort()`` call.
 
-.. c:macro:: Py_CHARMASK(c)
+   In release mode, the macro helps the compiler to optimize the code, and
+   avoids a warning about unreachable code.  For example, the macro is
+   implemented with ``__builtin_unreachable()`` on GCC in release mode.
 
-   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``.
+   A use for ``Py_UNREACHABLE()`` is following a call a function that
+   never returns but that is not declared :c:macro:`_Py_NO_RETURN`.
 
-.. c:macro:: Py_GETENV(s)
+   If a code path is very unlikely code but can be reached under exceptional
+   case, this macro must not be used.  For example, under low memory condition
+   or if a system call returns a value out of the expected range.  In this
+   case, it's better to report the error to the caller.  If the error cannot
+   be reported to caller, :c:func:`Py_FatalError` can be used.
 
-   Like ``getenv(s)``, but returns ``NULL`` if :option:`-E` was passed on the
-   command line (i.e. if ``Py_IgnoreEnvironmentFlag`` is set).
+   .. versionadded:: 3.7
 
 .. c:macro:: Py_UNUSED(arg)
 
@@ -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
index f869724334a4c4b24e7239f34430cde9e1b794f4..ebb3b05f1b53caf7b2d8957686980445be892cf1 100644 (file)
@@ -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);
         }
index b2b53dd2f771b6573b2a43072224c23e3744bf47..0aaa4eedd31a1ce16a1d90095e7f07ea71cdf044 100644 (file)
@@ -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 (file)
index 0000000..84b01b2
--- /dev/null
@@ -0,0 +1,2 @@
+Add the :c:macro:`Py_NO_INLINE` macro to disable inlining on a function.
+Patch by Victor Stinner.
index fa1452168094b92e890fe8ac4ca07957ffb8e98e..a93c0be6a149af5217ed40c9351cea48479b3f06 100644 (file)
@@ -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)
index 2468f45f941e2ec6b6e553d019501024cb6492c3..930ef7e29dbcf670c78ab4c668f177bbbd315b0e 100644 (file)
@@ -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)) {
index a58159a277bea8fb703aa6a74f1db4502b2e7c7a..63207de8b91371ffe9fab95fd023d43b6cfc703c 100644 (file)
@@ -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 @@ error:
  * 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[],
index 60b818f0dda4ac1bb3f06a26c7953ec329f7955a..346384edea6180f7aa52b09181b32c2a466b7b92 100644 (file)
@@ -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;