Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.10] bpo-45116: Fix inlining regressions on Windows Release build #31459

Closed
wants to merge 3 commits into from
Closed

[3.10] bpo-45116: Fix inlining regressions on Windows Release build #31459

wants to merge 3 commits into from

Conversation

neonene
Copy link
Contributor

@neonene neonene commented Feb 21, 2022

The main interpreter loop needs to shrink a bit to keep small functions there inlined consistently.


3.10.2+ (f1916cd)

Benchmark x64 1.03x recovery

Slower (5):
- unpack_sequence: 80.3 ns +- 0.1 ns -> 85.5 ns +- 5.0 ns: 1.06x slower
- scimark_monte_carlo: 145 ms +- 3 ms -> 151 ms +- 4 ms: 1.04x slower
- tornado_http: 411 ms +- 14 ms -> 425 ms +- 52 ms: 1.04x slower
- nbody: 199 ms +- 4 ms -> 205 ms +- 5 ms: 1.03x slower
- telco: 12.8 ms +- 0.1 ms -> 13.1 ms +- 0.2 ms: 1.02x slower
Faster (34):
- scimark_lu: 233 ms +- 2 ms -> 202 ms +- 8 ms: 1.15x faster
- xml_etree_parse: 246 ms +- 9 ms -> 220 ms +- 4 ms: 1.12x faster
- unpickle_pure_python: 482 us +- 13 us -> 436 us +- 9 us: 1.11x faster
- logging_format: 25.7 us +- 1.6 us -> 23.8 us +- 0.5 us: 1.08x faster
- hexiom: 14.0 ms +- 0.3 ms -> 13.0 ms +- 0.1 ms: 1.08x faster
- xml_etree_generate: 159 ms +- 5 ms -> 148 ms +- 2 ms: 1.08x faster
- django_template: 104 ms +- 4 ms -> 96.6 ms +- 2.6 ms: 1.07x faster
- meteor_contest: 141 ms +- 2 ms -> 132 ms +- 4 ms: 1.07x faster
- logging_silent: 260 ns +- 8 ns -> 243 ns +- 13 ns: 1.07x faster
- go: 381 ms +- 4 ms -> 357 ms +- 4 ms: 1.07x faster
- sympy_integrate: 39.9 ms +- 1.1 ms -> 37.4 ms +- 0.6 ms: 1.07x faster
- sympy_expand: 940 ms +- 20 ms -> 882 ms +- 13 ms: 1.07x faster
- regex_compile: 276 ms +- 4 ms -> 260 ms +- 5 ms: 1.06x faster
- logging_simple: 23.2 us +- 1.2 us -> 21.8 us +- 0.8 us: 1.06x faster
- sympy_sum: 333 ms +- 20 ms -> 314 ms +- 8 ms: 1.06x faster
- pathlib: 172 ms +- 10 ms -> 162 ms +- 15 ms: 1.06x faster
- chameleon: 19.2 ms +- 0.5 ms -> 18.1 ms +- 0.2 ms: 1.06x faster
- pickle_pure_python: 799 us +- 7 us -> 757 us +- 14 us: 1.05x faster
- scimark_sor: 282 ms +- 3 ms -> 268 ms +- 2 ms: 1.05x faster
- nqueens: 171 ms +- 3 ms -> 163 ms +- 3 ms: 1.05x faster
- dulwich_log: 214 ms +- 14 ms -> 204 ms +- 6 ms: 1.05x faster
- float: 170 ms +- 4 ms -> 162 ms +- 2 ms: 1.05x faster
- chaos: 182 ms +- 4 ms -> 173 ms +- 7 ms: 1.05x faster
- raytrace: 810 ms +- 7 ms -> 776 ms +- 8 ms: 1.04x faster
- xml_etree_iterparse: 177 ms +- 2 ms -> 170 ms +- 10 ms: 1.04x faster
- sympy_str: 575 ms +- 13 ms -> 553 ms +- 12 ms: 1.04x faster
- fannkuch: 657 ms +- 18 ms -> 632 ms +- 7 ms: 1.04x faster
- deltablue: 11.1 ms +- 0.4 ms -> 10.7 ms +- 0.3 ms: 1.04x faster
- json_dumps: 21.8 ms +- 0.5 ms -> 21.1 ms +- 0.2 ms: 1.04x faster
- crypto_pyaes: 169 ms +- 3 ms -> 163 ms +- 4 ms: 1.03x faster
- python_startup: 14.4 ms +- 1.8 ms -> 14.0 ms +- 1.0 ms: 1.03x faster
- pyflate: 1.04 sec +- 0.01 sec -> 1.00 sec +- 0.01 sec: 1.03x faster
- xml_etree_process: 133 ms +- 2 ms -> 129 ms +- 3 ms: 1.03x faster
- unpickle: 22.9 us +- 0.3 us -> 22.4 us +- 0.3 us: 1.02x faster
Benchmark hidden because not significant (19): 2to3, json_loads, mako, pickle, pickle_dict, pickle_l
ist, pidigits, python_startup_no_site, regex_dna, regex_effbot, regex_v8, richards, scimark_fft, sci
mark_sparse_mat_mult, spectral_norm, sqlalchemy_declarative, sqlalchemy_imperative, sqlite_synth, un
pickle_list

Geometric mean: 1.03x faster

Benchmark x86 1.04x recovery

Slower (6):
- scimark_sparse_mat_mult: 8.52 ms +- 0.22 ms -> 8.97 ms +- 0.18 ms: 1.05x slower
- json_dumps: 21.6 ms +- 0.1 ms -> 22.6 ms +- 0.9 ms: 1.05x slower
- regex_effbot: 3.41 ms +- 0.04 ms -> 3.56 ms +- 0.05 ms: 1.04x slower
- logging_format: 24.4 us +- 0.3 us -> 25.4 us +- 1.0 us: 1.04x slower
- logging_simple: 22.4 us +- 0.5 us -> 22.9 us +- 0.9 us: 1.02x slower
- pathlib: 167 ms +- 8 ms -> 170 ms +- 6 ms: 1.02x slower
Faster (39):
- sqlalchemy_imperative: 53.1 ms +- 3.3 ms -> 43.1 ms +- 5.1 ms: 1.23x faster
- logging_silent: 318 ns +- 16 ns -> 275 ns +- 13 ns: 1.15x faster
- richards: 143 ms +- 4 ms -> 126 ms +- 3 ms: 1.14x faster
- scimark_monte_carlo: 179 ms +- 3 ms -> 162 ms +- 3 ms: 1.10x faster
- hexiom: 16.6 ms +- 0.2 ms -> 15.1 ms +- 0.1 ms: 1.10x faster
- unpickle_pure_python: 564 us +- 7 us -> 513 us +- 4 us: 1.10x faster
- deltablue: 13.0 ms +- 0.4 ms -> 11.9 ms +- 0.3 ms: 1.09x faster
- scimark_sor: 366 ms +- 5 ms -> 336 ms +- 5 ms: 1.09x faster
- sqlalchemy_declarative: 293 ms +- 22 ms -> 270 ms +- 8 ms: 1.09x faster
- django_template: 104 ms +- 3 ms -> 97.2 ms +- 0.9 ms: 1.07x faster
- sympy_integrate: 39.3 ms +- 3.0 ms -> 36.7 ms +- 0.9 ms: 1.07x faster
- chaos: 207 ms +- 5 ms -> 193 ms +- 5 ms: 1.07x faster
- scimark_lu: 332 ms +- 6 ms -> 310 ms +- 4 ms: 1.07x faster
- regex_compile: 303 ms +- 5 ms -> 283 ms +- 6 ms: 1.07x faster
- pyflate: 1.22 sec +- 0.01 sec -> 1.14 sec +- 0.01 sec: 1.07x faster
- float: 196 ms +- 1 ms -> 184 ms +- 2 ms: 1.07x faster
- pickle_pure_python: 868 us +- 7 us -> 814 us +- 5 us: 1.07x faster
- go: 413 ms +- 5 ms -> 387 ms +- 12 ms: 1.07x faster
- raytrace: 916 ms +- 23 ms -> 868 ms +- 9 ms: 1.06x faster
- unpack_sequence: 87.2 ns +- 1.0 ns -> 83.3 ns +- 1.6 ns: 1.05x faster
- nqueens: 188 ms +- 2 ms -> 179 ms +- 1 ms: 1.05x faster
- telco: 12.5 ms +- 0.1 ms -> 11.9 ms +- 0.0 ms: 1.04x faster
- tornado_http: 379 ms +- 9 ms -> 364 ms +- 5 ms: 1.04x faster
- spectral_norm: 285 ms +- 9 ms -> 273 ms +- 4 ms: 1.04x faster
- xml_etree_parse: 253 ms +- 5 ms -> 243 ms +- 4 ms: 1.04x faster
- sympy_str: 558 ms +- 19 ms -> 538 ms +- 5 ms: 1.04x faster
- mako: 25.8 ms +- 0.5 ms -> 24.8 ms +- 0.6 ms: 1.04x faster
- fannkuch: 844 ms +- 5 ms -> 814 ms +- 5 ms: 1.04x faster
- xml_etree_generate: 164 ms +- 2 ms -> 159 ms +- 2 ms: 1.04x faster
- meteor_contest: 147 ms +- 1 ms -> 142 ms +- 1 ms: 1.04x faster
- xml_etree_process: 136 ms +- 1 ms -> 132 ms +- 1 ms: 1.03x faster
- unpickle_list: 6.00 us +- 0.15 us -> 5.81 us +- 0.20 us: 1.03x faster
- crypto_pyaes: 204 ms +- 3 ms -> 198 ms +- 1 ms: 1.03x faster
- chameleon: 19.5 ms +- 0.3 ms -> 18.9 ms +- 0.5 ms: 1.03x faster
- sympy_sum: 302 ms +- 12 ms -> 294 ms +- 13 ms: 1.03x faster
- dulwich_log: 196 ms +- 15 ms -> 191 ms +- 2 ms: 1.03x faster
- pickle_list: 6.35 us +- 0.03 us -> 6.18 us +- 0.04 us: 1.03x faster
- xml_etree_iterparse: 169 ms +- 2 ms -> 165 ms +- 2 ms: 1.02x faster
- sympy_expand: 939 ms +- 47 ms -> 918 ms +- 30 ms: 1.02x faster

Benchmark hidden because not significant (13): 2to3, json_loads, nbody, pickle, pickle_dict, pidigit
s, python_startup, python_startup_no_site, regex_dna, regex_v8, scimark_fft, sqlite_synth, unpickle

Geometric mean: 1.04x faster

PGO builds don't change performance with this.

https://bugs.python.org/issue45116

_Py_NO_INLINE:
MSVC inlines unknown_opcode_error() with no performance down, which is too uncommon to be inlined.
@neonene neonene requested a review from markshannon as a code owner February 21, 2022 05:00
@neonene
Copy link
Contributor Author

neonene commented Feb 21, 2022

The build machines have the same log as mine:

Inlining decisions before the fix (x64)

Inlinee for function _PyEval_EvalFrameDefault
  _Py_EnsureFuncTstateNotNULL (small function)
    -_Py_FatalError_TstateNULL (initial scan: postdominated by noreturn call)
  _Py_EnterRecursiveCall (simple decision)
    _Py_MakeRecCheck (simple decision)
    -_Py_CheckRecursiveCall (rejected)
  -call_trace_protected (after recursive inlining: late size check)
  -call_trace_protected (after recursive inlining: late size check)
  PyDTrace_FUNCTION_ENTRY_ENABLED (small function)
  -dtrace_function_entry (after recursive inlining: late size check)
  -_PyCode_InitOpcache (after recursive inlining: late size check)
  -_Py_atomic_load_32bit_impl (after recursive inlining: late size check)
  -eval_frame_handle_pending (after recursive inlining: late size check)
  PyDTrace_LINE_ENABLED (small function)
  -maybe_dtrace_line (after recursive inlining: late size check)
  -maybe_call_line_trace (after recursive inlining: late size check)
  -PyTuple_GetItem (after recursive inlining: late size check)
  -format_exc_check_arg (after recursive inlining: late size check)
  _Py_INCREF (small function)
  _Py_INCREF (small function)
  _Py_XDECREF (small function)
    _Py_DECREF (simple decision)
      _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_INCREF (small function)
  _Py_INCREF (small function)
  _Py_INCREF (small function)
  -PyNumber_Positive (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  -PyNumber_Negative (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  -PyObject_IsTrue (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_INCREF (small function)
  _Py_INCREF (small function)
  -PyNumber_Invert (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  PyNumber_Power (simple decision)
    -ternary_op (rejected)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  -PyNumber_Multiply (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  PyNumber_MatrixMultiply (simple decision)
    -binary_op (rejected)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  PyNumber_TrueDivide (simple decision)
    -binary_op (rejected)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  PyNumber_FloorDivide (simple decision)
    -binary_op (rejected)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_IS_TYPE (small function)
  PyType_HasFeature (simple decision)
  _Py_IS_TYPE (small function)
  -PyUnicode_Format (after recursive inlining: late size check)
  PyNumber_Remainder (simple decision)
    -binary_op (rejected)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_IS_TYPE (small function)
  _Py_IS_TYPE (small function)
  -unicode_concatenate (after recursive inlining: late size check)
  -PyNumber_Add (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  PyNumber_Subtract (simple decision)
    -binary_op (rejected)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  -PyObject_GetItem (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  PyNumber_Lshift (simple decision)
    -binary_op (rejected)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  PyNumber_Rshift (simple decision)
    -binary_op (rejected)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  PyNumber_And (simple decision)
    -binary_op (rejected)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  PyNumber_Xor (simple decision)
    -binary_op (rejected)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  PyNumber_Or (simple decision)
    -binary_op (rejected)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  -PyList_Append (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  -PySet_Add (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  PyNumber_InPlacePower (simple decision)
    -ternary_iop (rejected)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  -PyNumber_InPlaceMultiply (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  PyNumber_InPlaceMatrixMultiply (simple decision)
    -binary_iop (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  PyNumber_InPlaceTrueDivide (simple decision)
    -binary_iop (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  PyNumber_InPlaceFloorDivide (simple decision)
    -binary_iop (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  PyNumber_InPlaceRemainder (simple decision)
    -binary_iop (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_IS_TYPE (small function)
  _Py_IS_TYPE (small function)
  -unicode_concatenate (after recursive inlining: late size check)
  -PyNumber_InPlaceAdd (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  PyNumber_InPlaceSubtract (simple decision)
    -binary_iop (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  PyNumber_InPlaceLshift (simple decision)
    -binary_iop (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  PyNumber_InPlaceRshift (simple decision)
    -binary_iop (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  PyNumber_InPlaceAnd (simple decision)
    -binary_iop (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  PyNumber_InPlaceXor (simple decision)
    -binary_iop (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  PyNumber_InPlaceOr (simple decision)
    -binary_iop (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  -PyObject_SetItem (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  -PyObject_DelItem (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _PySys_GetObjectId (simple decision)
    _PyThreadState_GET (small function)
      _PyRuntimeState_GetThreadState (small function)
        -_Py_atomic_load_64bit_impl (rejected)
    -sys_get_object_id (rejected)
  -_PyErr_SetString (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  -PyObject_CallOneArg (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  -do_raise (after recursive inlining: late size check)
  -_PyErr_SetString (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  -_PyErr_Format (initial scan: varargs, not eligible)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  -_PyErr_Format (initial scan: varargs, not eligible)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_IS_TYPE (small function)
  -_PyErr_Format (initial scan: varargs, not eligible)
  -_PyCoro_GetAwaitableIter (after recursive inlining: late size check)
  -_PyErr_FormatFromCause (initial scan: varargs, not eligible)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  -_PyCoro_GetAwaitableIter (after recursive inlining: late size check)
  -format_awaitable_error (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_IS_TYPE (small function)
  -_PyGen_yf (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  -_PyErr_SetString (after recursive inlining: late size check)
  -PyIter_Send (after recursive inlining: late size check)
  PyIter_Check (simple decision)
  _PyObject_CallMethodIdOneArg (simple decision)
    _PyObject_VectorcallMethodId (simple decision)
      -_PyUnicode_FromId (rejected)
      -PyObject_VectorcallMethod (rejected)
  _PyErr_ExceptionMatches (simple decision)
    _PyErr_Occurred (small function)
    -PyErr_GivenExceptionMatches (rejected)
  -call_exc_trace (after recursive inlining: late size check)
  -_PyGen_FetchStopIterationValue (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  -_PyAsyncGenValueWrapperNew (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  -PyFrame_BlockPop (after recursive inlining: late size check)
  -_PyErr_SetString (after recursive inlining: late size check)
  _Py_XDECREF (small function)
    _Py_DECREF (simple decision)
      _Py_Dealloc (simple decision)
  _Py_XDECREF (small function)
    _Py_DECREF (simple decision)
      _Py_Dealloc (simple decision)
  _Py_XDECREF (small function)
    _Py_DECREF (simple decision)
      _Py_Dealloc (simple decision)
  -PyFrame_BlockPop (after recursive inlining: late size check)
  -_PyErr_Restore (after recursive inlining: late size check)
  -PyErr_GivenExceptionMatches (after recursive inlining: late size check)
  -PyFrame_BlockPop (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_XDECREF (small function)
    _Py_DECREF (simple decision)
      _Py_Dealloc (simple decision)
  _Py_XDECREF (small function)
    _Py_DECREF (simple decision)
      _Py_Dealloc (simple decision)
  _Py_XDECREF (small function)
    _Py_DECREF (simple decision)
      _Py_Dealloc (simple decision)
  _Py_XDECREF (small function)
    _Py_DECREF (simple decision)
      _Py_Dealloc (simple decision)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  -_PyErr_Restore (after recursive inlining: late size check)
  _Py_INCREF (small function)
  _Py_IS_TYPE (small function)
  _PyDict_GetItemIdWithError (simple decision)
    -_PyUnicode_FromId (rejected)
    -_PyDict_GetItem_KnownHash (rejected)
  _PyErr_Occurred (small function)
  -_PyErr_SetString (after recursive inlining: late size check)
  _Py_INCREF (small function)
  -_PyUnicode_FromId (after recursive inlining: late size check)
  -PyObject_GetItem (after recursive inlining: late size check)
  _PyErr_ExceptionMatches (simple decision)
    _PyErr_Occurred (small function)
    -PyErr_GivenExceptionMatches (rejected)
  -_PyErr_SetString (after recursive inlining: late size check)
  -_PyErr_Format (initial scan: varargs, not eligible)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  _Py_IS_TYPE (small function)
  -PyDict_SetItem (after recursive inlining: late size check)
  -PyObject_SetItem (after recursive inlining: late size check)
  _Py_DECREF (simple decision)
    _Py_Dealloc (simple decision)
  -_PyErr_Format (initial scan: varargs, not eligible)
  -PyObject_DelItem (after recursive inlining: late size check)
  -format_exc_check_arg (after recursive inlining: late size check)
  _Py_IS_TYPE (small function)
  _Py_INCREF (small function)
  _Py_IS_TYPE (small function)
  _Py_INCREF (small function)
  -unpack_iterable (after recursive inlining: late size check)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -unpack_iterable (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -PyObject_SetAttr (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -PyObject_SetAttr (rejected)
  -_Py_DECREF (rejected)
  -PyDict_SetItem (rejected)
  -_Py_DECREF (rejected)
  -PyDict_DelItem (rejected)
  -_PyErr_ExceptionMatches (rejected)
  -format_exc_check_arg (rejected)
  -_PyErr_Format (initial scan: varargs, not eligible)
  -_Py_IS_TYPE (rejected)
  -PyDict_GetItemWithError (rejected)
  -_Py_INCREF (rejected)
  -_PyErr_Occurred (rejected)
  -PyObject_GetItem (rejected)
  -_PyErr_ExceptionMatches (rejected)
  -_PyErr_Clear (rejected)
  -PyDict_GetItemWithError (rejected)
  -_Py_INCREF (rejected)
  -_PyErr_Occurred (rejected)
  -_Py_IS_TYPE (rejected)
  -PyDict_GetItemWithError (rejected)
  -_PyErr_Occurred (rejected)
  -format_exc_check_arg (rejected)
  -_Py_INCREF (rejected)
  -PyObject_GetItem (rejected)
  -_PyErr_ExceptionMatches (rejected)
  -format_exc_check_arg (rejected)
  -_Py_IS_TYPE (rejected)
  -_Py_IS_TYPE (rejected)
  -_Py_INCREF (rejected)
  -_PyDict_LoadGlobal (rejected)
  -_PyErr_Occurred (rejected)
  -format_exc_check_arg (rejected)
  -_Py_INCREF (rejected)
  -PyObject_GetItem (rejected)
  -_PyErr_ExceptionMatches (rejected)
  -_PyErr_Clear (rejected)
  -PyObject_GetItem (rejected)
  -_PyErr_ExceptionMatches (rejected)
  -format_exc_check_arg (rejected)
  -_Py_XDECREF (rejected)
  -PyTuple_GetItem (rejected)
  -format_exc_check_arg (rejected)
  -_Py_DECREF (rejected)
  -format_exc_unbound (rejected)
  -_Py_INCREF (rejected)
  -_Py_IS_TYPE (rejected)
  -PyDict_GetItemWithError (rejected)
  -_Py_INCREF (rejected)
  -_PyErr_Occurred (rejected)
  -PyObject_GetItem (rejected)
  -_PyErr_ExceptionMatches (rejected)
  -_PyErr_Clear (rejected)
  -format_exc_unbound (rejected)
  -_Py_INCREF (rejected)
  -format_exc_unbound (rejected)
  -_Py_INCREF (rejected)
  -_Py_XDECREF (rejected)
  -PyUnicode_New (rejected)
  -_PyUnicode_JoinArray (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -PyTuple_New (rejected)
  -PyList_New (rejected)
  -PyList_AsTuple (rejected)
  -_Py_DECREF (rejected)
  -_PyList_Extend (rejected)
  -_PyErr_ExceptionMatches (rejected)
  -PySequence_Check (rejected)
  -_PyErr_Clear (rejected)
  -_PyErr_Format (initial scan: varargs, not eligible)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -_PySet_Update (rejected)
  -_Py_DECREF (rejected)
  -PySet_New (rejected)
  -PySet_Add (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -_PyDict_NewPresized (rejected)
  -PyDict_SetItem (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -_PyErr_Format (initial scan: parameter mismatch, varargs, not eligible)
  -_Py_IS_TYPE (rejected)
  -_PyDict_GetItemIdWithError (rejected)
  -_PyErr_Occurred (rejected)
  -PyDict_New (rejected)
  -_PyDict_SetItemId (rejected)
  -_Py_DECREF (rejected)
  -_PyUnicode_FromId (rejected)
  -PyObject_GetItem (rejected)
  -_PyErr_ExceptionMatches (rejected)
  -_PyErr_Clear (rejected)
  -PyDict_New (rejected)
  -PyObject_SetItem (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -_Py_IS_TYPE (rejected)
  -_PyErr_SetString (rejected)
  -_PyDict_NewPresized (rejected)
  -PyDict_SetItem (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -PyDict_Update (rejected)
  -_PyErr_ExceptionMatches (rejected)
  -_PyErr_Format (initial scan: varargs, not eligible)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -_PyDict_MergeEx (rejected)
  -format_kwargs_error (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -PyDict_SetItem (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -PyType_HasFeature (rejected)
  -_Py_INCREF (rejected)
  -_Py_DECREF (rejected)
  -_Py_IS_TYPE (rejected)
  -_Py_INCREF (rejected)
  -_PyDict_GetItemHint (rejected)
  -_Py_INCREF (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -_PyErr_Clear (rejected)
  -_Py_DECREF (rejected)
  -PyType_Ready (rejected)
  -_Py_DECREF (rejected)
  -_PyType_Lookup (rejected)
  -_Py_INCREF (rejected)
  -_Py_DECREF (rejected)
  -_Py_IS_TYPE (rejected)
  -_Py_INCREF (rejected)
  -_PyDict_GetItemHint (rejected)
  -_Py_INCREF (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -_PyErr_Clear (rejected)
  -_Py_DECREF (rejected)
  -PyObject_GetAttr (rejected)
  -_Py_DECREF (rejected)
  -PyObject_RichCompare (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -_Py_INCREF (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -PySequence_Contains (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -_Py_INCREF (rejected)
  -PyType_HasFeature (rejected)
  -_PyType_Check (rejected)
  -PyType_HasFeature (rejected)
  -_PyErr_SetString (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -_PyType_Check (rejected)
  -PyType_HasFeature (rejected)
  -_PyErr_SetString (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -PyErr_GivenExceptionMatches (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -import_name (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -PyFrame_FastToLocalsWithError (rejected)
  -_Py_DECREF (rejected)
  -_PyErr_SetString (rejected)
  -_Py_DECREF (rejected)
  -import_all_from (rejected)
  -PyFrame_LocalsToFast (rejected)
  -_Py_DECREF (rejected)
  -import_from (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -_Py_atomic_load_32bit_impl (rejected)
  -PyObject_IsTrue (rejected)
  -_Py_DECREF (rejected)
  -_Py_atomic_load_32bit_impl (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -_Py_atomic_load_32bit_impl (rejected)
  -PyObject_IsTrue (rejected)
  -_Py_DECREF (rejected)
  -_Py_atomic_load_32bit_impl (rejected)
  -_Py_DECREF (rejected)
  -PyObject_IsTrue (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -PyObject_IsTrue (rejected)
  -_Py_DECREF (rejected)
  -_Py_atomic_load_32bit_impl (rejected)
  -PyObject_Size (rejected)
  -PyLong_FromSsize_t (rejected)
  -match_class (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -_PyErr_Occurred (rejected)
  -_Py_DECREF (rejected)
  -PyBool_FromLong (rejected)
  -_Py_INCREF (rejected)
  -_Py_INCREF (rejected)
  -match_keys (rejected)
  -_Py_INCREF (rejected)
  -_Py_INCREF (rejected)
  -PyDict_New (rejected)
  -PyDict_Update (rejected)
  -_Py_XDECREF (rejected)
  -PyDict_DelItem (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -PyObject_GetIter (rejected)
  -_Py_DECREF (rejected)
  -_Py_IS_TYPE (rejected)
  -_Py_DECREF (rejected)
  -_PyErr_SetString (rejected)
  -_Py_IS_TYPE (rejected)
  -PyObject_GetIter (rejected)
  -_Py_DECREF (rejected)
  -_PyErr_Occurred (rejected)
  -_PyErr_ExceptionMatches (rejected)
  -call_exc_trace (rejected)
  -_PyErr_Clear (rejected)
  -_Py_DECREF (rejected)
  -PyFrame_BlockSetup (rejected)
  -special_lookup (rejected)
  -special_lookup (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -_PyObject_CallNoArg (rejected)
  -_Py_DECREF (rejected)
  -PyFrame_BlockSetup (rejected)
  -special_lookup (rejected)
  -special_lookup (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -_PyObject_CallNoArg (rejected)
  -_Py_DECREF (rejected)
  -PyFrame_BlockSetup (rejected)
  -PyObject_Vectorcall (rejected)
  -_PyObject_GetMethod (rejected)
  -_Py_DECREF (rejected)
  -call_function (rejected)
  -call_function (rejected)
  -_Py_atomic_load_32bit_impl (rejected)
  -call_function (rejected)
  -_Py_atomic_load_32bit_impl (rejected)
  -call_function (rejected)
  -_Py_DECREF (rejected)
  -_Py_atomic_load_32bit_impl (rejected)
  -_Py_IS_TYPE (rejected)
  -PyDict_New (rejected)
  -_PyDict_MergeEx (rejected)
  -_Py_DECREF (rejected)
  -format_kwargs_error (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -_Py_IS_TYPE (rejected)
  -check_args_iterable (rejected)
  -_Py_DECREF (rejected)
  -PySequence_Tuple (rejected)
  -_Py_DECREF (rejected)
  -do_call_core (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -_Py_XDECREF (rejected)
  -_Py_atomic_load_32bit_impl (rejected)
  -PyFunction_NewWithQualName (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -PySlice_New (rejected)
  -_Py_DECREF (rejected)
  -_Py_DECREF (rejected)
  -_Py_XDECREF (rejected)
  -_PyErr_Format (initial scan: varargs, not eligible)
  -_Py_DECREF (rejected)
  -_Py_XDECREF (rejected)
  -_Py_IS_TYPE (rejected)
  -PyObject_Format (rejected)
  -_Py_DECREF (rejected)
  -_Py_XDECREF (rejected)
  -PyFrame_GetLineNumber (rejected)
  -fprintf (initial scan: parameter mismatch, varargs, not eligible)
  -_PyErr_SetString (rejected)
  -_PyErr_Occurred (rejected)
  -_PyErr_SetString (rejected)
  -PyTraceBack_Here (rejected)
  -call_exc_trace (rejected)
  -_Py_XDECREF (rejected)
  -_Py_XDECREF (rejected)
  -_Py_XDECREF (rejected)
  -_Py_XDECREF (rejected)
  -_Py_XDECREF (rejected)
  -PyFrame_BlockSetup (rejected)
  -_Py_INCREF (rejected)
  -_PyErr_Fetch (rejected)
  -_PyErr_NormalizeException (rejected)
  -PyException_SetTraceback (rejected)
  -PyException_SetTraceback (rejected)
  -_Py_INCREF (rejected)
  -_Py_INCREF (rejected)
  -_Py_INCREF (rejected)
  -_Py_XDECREF (rejected)
  -call_trace_protected (rejected)
  -_Py_DECREF (rejected)
  -call_trace_protected (rejected)
  -_Py_DECREF (rejected)
  PyDTrace_FUNCTION_RETURN_ENABLED (small function)
  -dtrace_function_return (rejected)
  -_Py_LeaveRecursiveCall (rejected)
  -_Py_CheckFunctionResult (rejected)


Although they are inlined sequentially, sorting case branches by frequency has a little effect (1%).

@neonene
Copy link
Contributor Author

neonene commented Feb 21, 2022

Inlining decisions after the fix (x64)

Inlinee for function _PyEval_EvalFrameDefault
  _Py_EnsureFuncTstateNotNULL (small function)
    -_Py_FatalError_TstateNULL (initial scan: postdominated by noreturn call)
  _Py_EnterRecursiveCall (callgraph decision)
    _Py_MakeRecCheck (callgraph decision)
    _Py_CheckRecursiveCall (callgraph decision)
      -_Py_FatalErrorFunc (initial scan: postdominated by noreturn call)
      -_PyErr_Format (initial scan: varargs, not eligible)
  -call_trace_protected (rejected)
  -call_trace_protected (rejected)
  PyDTrace_FUNCTION_ENTRY_ENABLED (optimized to trivial routine)
  dtrace_function_entry (callgraph decision)
    -PyUnicode_AsUTF8 (rejected)
    -PyUnicode_AsUTF8 (rejected)
    PyFrame_GetLineNumber (callgraph decision)
      -PyCode_Addr2Line (rejected)
    PyDTrace_FUNCTION_ENTRY (optimized to trivial routine)
  _PyCode_InitOpcache (callgraph decision)
    PyBytes_Size (callgraph decision)
      PyType_HasFeature (small function)
      -PyErr_Format (initial scan: varargs, not eligible)
    PyMem_Calloc (callgraph decision)
    PyMem_Calloc (callgraph decision)
    PyMem_Free (small function)
    PyMem_Free (small function)
  _Py_atomic_load_32bit_impl (callgraph decision)
  -eval_frame_handle_pending (rejected)
  PyDTrace_LINE_ENABLED (optimized to trivial routine)
  maybe_dtrace_line (callgraph decision)
    initialize_trace_info (callgraph decision)
      _PyCode_InitAddressRange (callgraph decision)
        PyLineTable_InitAddressRange (callgraph decision)
    -_PyCode_CheckLineNumber (rejected)
    -PyUnicode_AsUTF8 (rejected)
    -PyUnicode_AsUTF8 (rejected)
    PyDTrace_LINE (optimized to trivial routine)
  maybe_call_line_trace (callgraph decision)
    initialize_trace_info (callgraph decision)
      _PyCode_InitAddressRange (callgraph decision)
        PyLineTable_InitAddressRange (callgraph decision)
    -_PyCode_CheckLineNumber (rejected)
    -_PyCode_CheckLineNumber (rejected)
    call_trace (callgraph decision)
      initialize_trace_info (callgraph decision)
        _PyCode_InitAddressRange (callgraph decision)
          PyLineTable_InitAddressRange (callgraph decision)
      -_PyCode_CheckLineNumber (rejected)
    call_trace (callgraph decision)
      initialize_trace_info (callgraph decision)
        _PyCode_InitAddressRange (callgraph decision)
          PyLineTable_InitAddressRange (callgraph decision)
      -_PyCode_CheckLineNumber (rejected)
  -PyTuple_GetItem (rejected)
  -format_exc_check_arg (rejected)
  _Py_INCREF (small function)
  _Py_INCREF (small function)
  _Py_XDECREF (callgraph decision)
    _Py_DECREF (callgraph decision)
      _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_INCREF (small function)
  _Py_INCREF (small function)
  _Py_INCREF (small function)
  PyNumber_Positive (callgraph decision)
    null_error (callgraph decision)
      _PyThreadState_GET (small function)
        _PyRuntimeState_GetThreadState (small function)
          _Py_atomic_load_64bit_impl (callgraph decision)
      _PyErr_Occurred (optimized to trivial routine)
      _PyErr_SetString (callgraph decision)
        PyUnicode_FromString (callgraph decision)
          PyErr_SetString (callgraph decision)
            _PyThreadState_GET (small function)
              _PyRuntimeState_GetThreadState (small function)
                _Py_atomic_load_64bit_impl (callgraph decision)
            -_PyErr_SetString (initial scan: recursive expansion)
          PyUnicode_DecodeUTF8Stateful (callgraph decision)
            -unicode_decode_utf8 (rejected)
        -_PyErr_SetObject (rejected)
        _Py_XDECREF (callgraph decision)
          _Py_DECREF (callgraph decision)
            _Py_Dealloc (small function)
    type_error (callgraph decision)
      -PyErr_Format (initial scan: varargs, not eligible)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  PyNumber_Negative (callgraph decision)
    null_error (callgraph decision)
      _PyThreadState_GET (small function)
        _PyRuntimeState_GetThreadState (small function)
          _Py_atomic_load_64bit_impl (callgraph decision)
      _PyErr_Occurred (optimized to trivial routine)
      _PyErr_SetString (callgraph decision)
        PyUnicode_FromString (callgraph decision)
          PyErr_SetString (callgraph decision)
            _PyThreadState_GET (small function)
              _PyRuntimeState_GetThreadState (small function)
                _Py_atomic_load_64bit_impl (callgraph decision)
            -_PyErr_SetString (initial scan: recursive expansion)
          PyUnicode_DecodeUTF8Stateful (callgraph decision)
            -unicode_decode_utf8 (rejected)
        -_PyErr_SetObject (rejected)
        _Py_XDECREF (callgraph decision)
          _Py_DECREF (callgraph decision)
            _Py_Dealloc (small function)
    type_error (callgraph decision)
      -PyErr_Format (initial scan: varargs, not eligible)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyObject_IsTrue (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_INCREF (small function)
  _Py_INCREF (small function)
  PyNumber_Invert (callgraph decision)
    null_error (callgraph decision)
      _PyThreadState_GET (small function)
        _PyRuntimeState_GetThreadState (small function)
          _Py_atomic_load_64bit_impl (callgraph decision)
      _PyErr_Occurred (optimized to trivial routine)
      _PyErr_SetString (callgraph decision)
        PyUnicode_FromString (callgraph decision)
          PyErr_SetString (callgraph decision)
            _PyThreadState_GET (small function)
              _PyRuntimeState_GetThreadState (small function)
                _Py_atomic_load_64bit_impl (callgraph decision)
            -_PyErr_SetString (initial scan: recursive expansion)
          PyUnicode_DecodeUTF8Stateful (callgraph decision)
            -unicode_decode_utf8 (rejected)
        -_PyErr_SetObject (rejected)
        _Py_XDECREF (callgraph decision)
          _Py_DECREF (callgraph decision)
            _Py_Dealloc (small function)
    type_error (callgraph decision)
      -PyErr_Format (initial scan: varargs, not eligible)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  PyNumber_Power (callgraph decision)
    -ternary_op (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyNumber_Multiply (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyNumber_MatrixMultiply (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyNumber_TrueDivide (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyNumber_FloorDivide (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_IS_TYPE (small function)
  PyType_HasFeature (small function)
  _Py_IS_TYPE (small function)
  -PyUnicode_Format (rejected)
  -PyNumber_Remainder (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_IS_TYPE (small function)
  _Py_IS_TYPE (small function)
  -unicode_concatenate (rejected)
  -PyNumber_Add (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyNumber_Subtract (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyObject_GetItem (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyNumber_Lshift (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  PyNumber_Rshift (callgraph decision)
    -binary_op (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyNumber_And (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyNumber_Xor (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyNumber_Or (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  PyList_Append (callgraph decision)
    PyType_HasFeature (small function)
    -app1 (rejected)
    _PyErr_BadInternalCall (callgraph decision)
      _PyThreadState_GET (small function)
        _PyRuntimeState_GetThreadState (small function)
          _Py_atomic_load_64bit_impl (callgraph decision)
      -_PyErr_Format (initial scan: parameter mismatch, varargs, not eligible)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PySet_Add (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyNumber_InPlacePower (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyNumber_InPlaceMultiply (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyNumber_InPlaceMatrixMultiply (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyNumber_InPlaceTrueDivide (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyNumber_InPlaceFloorDivide (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyNumber_InPlaceRemainder (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_IS_TYPE (small function)
  _Py_IS_TYPE (small function)
  -unicode_concatenate (rejected)
  -PyNumber_InPlaceAdd (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyNumber_InPlaceSubtract (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyNumber_InPlaceLshift (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyNumber_InPlaceRshift (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyNumber_InPlaceAnd (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyNumber_InPlaceXor (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyNumber_InPlaceOr (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyObject_SetItem (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyObject_DelItem (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _PySys_GetObjectId (small function)
    _PyThreadState_GET (small function)
      _PyRuntimeState_GetThreadState (small function)
        _Py_atomic_load_64bit_impl (callgraph decision)
    -sys_get_object_id (rejected)
  _PyErr_SetString (callgraph decision)
    PyUnicode_FromString (callgraph decision)
      -PyErr_SetString (rejected)
      PyUnicode_DecodeUTF8Stateful (callgraph decision)
        -unicode_decode_utf8 (rejected)
    -_PyErr_SetObject (rejected)
    _Py_XDECREF (callgraph decision)
      _Py_DECREF (callgraph decision)
        _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  PyObject_CallOneArg (callgraph decision)
    PyThreadState_Get (callgraph decision)
      _PyThreadState_GET (small function)
        _PyRuntimeState_GetThreadState (small function)
          _Py_atomic_load_64bit_impl (callgraph decision)
      _Py_EnsureFuncTstateNotNULL (small function)
        -_Py_FatalError_TstateNULL (initial scan: postdominated by noreturn call)
    -_PyObject_VectorcallTstate (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -do_raise (rejected)
  _PyErr_SetString (callgraph decision)
    PyUnicode_FromString (callgraph decision)
      PyErr_SetString (callgraph decision)
        _PyThreadState_GET (small function)
          _PyRuntimeState_GetThreadState (small function)
            _Py_atomic_load_64bit_impl (callgraph decision)
        -_PyErr_SetString (initial scan: recursive expansion)
      PyUnicode_DecodeUTF8Stateful (callgraph decision)
        -unicode_decode_utf8 (rejected)
    -_PyErr_SetObject (rejected)
    _Py_XDECREF (callgraph decision)
      _Py_DECREF (callgraph decision)
        _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -_PyErr_Format (initial scan: varargs, not eligible)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -_PyErr_Format (initial scan: varargs, not eligible)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_IS_TYPE (small function)
  -_PyErr_Format (initial scan: varargs, not eligible)
  -_PyCoro_GetAwaitableIter (rejected)
  -_PyErr_FormatFromCause (initial scan: varargs, not eligible)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -_PyCoro_GetAwaitableIter (rejected)
  format_awaitable_error (callgraph decision)
    -_PyErr_Format (initial scan: varargs, not eligible)
    -_PyErr_Format (initial scan: varargs, not eligible)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_IS_TYPE (small function)
  _PyGen_yf (callgraph decision)
    _Py_INCREF (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -_PyErr_SetString (rejected)
  -PyIter_Send (rejected)
  PyIter_Check (callgraph decision)
  _PyObject_CallMethodIdOneArg (callgraph decision)
    _PyObject_VectorcallMethodId (callgraph decision)
      -_PyUnicode_FromId (rejected)
      -PyObject_VectorcallMethod (rejected)
  _PyErr_ExceptionMatches (small function)
    _PyErr_Occurred (optimized to trivial routine)
    -PyErr_GivenExceptionMatches (rejected)
  -call_exc_trace (rejected)
  -_PyGen_FetchStopIterationValue (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _PyAsyncGenValueWrapperNew (callgraph decision)
    get_async_gen_state (small function)
      _PyInterpreterState_GET (small function)
        _PyThreadState_GET (small function)
          _PyRuntimeState_GetThreadState (small function)
            _Py_atomic_load_64bit_impl (callgraph decision)
    -_Py_NewReference (rejected)
    _PyObject_GC_New (callgraph decision)
      _PyObject_GC_Malloc (small function)
        -_PyObject_GC_Alloc (rejected)
      _PyObject_Init (callgraph decision)
        _Py_SET_TYPE (optimized to trivial routine)
        _PyType_HasFeature (small function)
        _Py_INCREF (small function)
        -_Py_NewReference (rejected)
    _Py_INCREF (small function)
    _PyObject_GC_TRACK (callgraph decision)
      _PyInterpreterState_GET (small function)
        _PyThreadState_GET (small function)
          _PyRuntimeState_GetThreadState (small function)
            _Py_atomic_load_64bit_impl (callgraph decision)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  PyFrame_BlockPop (callgraph decision)
    -_Py_FatalErrorFunc (initial scan: postdominated by noreturn call)
  -_PyErr_SetString (rejected)
  _Py_XDECREF (callgraph decision)
    _Py_DECREF (callgraph decision)
      _Py_Dealloc (small function)
  _Py_XDECREF (callgraph decision)
    _Py_DECREF (callgraph decision)
      _Py_Dealloc (small function)
  _Py_XDECREF (callgraph decision)
    _Py_DECREF (callgraph decision)
      _Py_Dealloc (small function)
  PyFrame_BlockPop (callgraph decision)
    -_Py_FatalErrorFunc (initial scan: postdominated by noreturn call)
  -_PyErr_Restore (rejected)
  -PyErr_GivenExceptionMatches (rejected)
  PyFrame_BlockPop (callgraph decision)
    -_Py_FatalErrorFunc (initial scan: postdominated by noreturn call)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_XDECREF (callgraph decision)
    _Py_DECREF (callgraph decision)
      _Py_Dealloc (small function)
  _Py_XDECREF (callgraph decision)
    _Py_DECREF (callgraph decision)
      _Py_Dealloc (small function)
  _Py_XDECREF (callgraph decision)
    _Py_DECREF (callgraph decision)
      _Py_Dealloc (small function)
  _Py_XDECREF (callgraph decision)
    _Py_DECREF (callgraph decision)
      _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -_PyErr_Restore (rejected)
  _Py_INCREF (small function)
  _Py_IS_TYPE (small function)
  _PyDict_GetItemIdWithError (callgraph decision)
    -_PyUnicode_FromId (rejected)
    -_PyDict_GetItem_KnownHash (rejected)
  _PyErr_Occurred (optimized to trivial routine)
  -_PyErr_SetString (rejected)
  _Py_INCREF (small function)
  -_PyUnicode_FromId (rejected)
  -PyObject_GetItem (rejected)
  _PyErr_ExceptionMatches (small function)
    _PyErr_Occurred (optimized to trivial routine)
    -PyErr_GivenExceptionMatches (rejected)
  -_PyErr_SetString (rejected)
  -_PyErr_Format (initial scan: varargs, not eligible)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_IS_TYPE (small function)
  -PyDict_SetItem (rejected)
  -PyObject_SetItem (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -_PyErr_Format (initial scan: varargs, not eligible)
  -PyObject_DelItem (rejected)
  -format_exc_check_arg (rejected)
  _Py_IS_TYPE (small function)
  _Py_INCREF (small function)
  _Py_IS_TYPE (small function)
  _Py_INCREF (small function)
  -unpack_iterable (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -unpack_iterable (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyObject_SetAttr (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyObject_SetAttr (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyDict_SetItem (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyDict_DelItem (rejected)
  _PyErr_ExceptionMatches (small function)
    _PyErr_Occurred (optimized to trivial routine)
    -PyErr_GivenExceptionMatches (rejected)
  -format_exc_check_arg (rejected)
  -_PyErr_Format (initial scan: varargs, not eligible)
  _Py_IS_TYPE (small function)
  -PyDict_GetItemWithError (rejected)
  _Py_INCREF (small function)
  _PyErr_Occurred (optimized to trivial routine)
  -PyObject_GetItem (rejected)
  _PyErr_ExceptionMatches (small function)
    _PyErr_Occurred (optimized to trivial routine)
    -PyErr_GivenExceptionMatches (rejected)
  -_PyErr_Clear (rejected)
  -PyDict_GetItemWithError (rejected)
  _Py_INCREF (small function)
  _PyErr_Occurred (optimized to trivial routine)
  _Py_IS_TYPE (small function)
  -PyDict_GetItemWithError (rejected)
  _PyErr_Occurred (optimized to trivial routine)
  -format_exc_check_arg (rejected)
  _Py_INCREF (small function)
  -PyObject_GetItem (rejected)
  _PyErr_ExceptionMatches (small function)
    _PyErr_Occurred (optimized to trivial routine)
    -PyErr_GivenExceptionMatches (rejected)
  -format_exc_check_arg (rejected)
  _Py_IS_TYPE (small function)
  _Py_IS_TYPE (small function)
  _Py_INCREF (small function)
  _PyDict_LoadGlobal (callgraph decision)
    _Py_IS_TYPE (small function)
    -PyObject_Hash (rejected)
  _PyErr_Occurred (optimized to trivial routine)
  -format_exc_check_arg (rejected)
  _Py_INCREF (small function)
  -PyObject_GetItem (rejected)
  _PyErr_ExceptionMatches (small function)
    _PyErr_Occurred (optimized to trivial routine)
    -PyErr_GivenExceptionMatches (rejected)
  -_PyErr_Clear (rejected)
  -PyObject_GetItem (rejected)
  _PyErr_ExceptionMatches (small function)
    _PyErr_Occurred (optimized to trivial routine)
    -PyErr_GivenExceptionMatches (rejected)
  -format_exc_check_arg (rejected)
  _Py_XDECREF (callgraph decision)
    _Py_DECREF (callgraph decision)
      _Py_Dealloc (small function)
  -PyTuple_GetItem (rejected)
  -format_exc_check_arg (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -format_exc_unbound (rejected)
  _Py_INCREF (small function)
  _Py_IS_TYPE (small function)
  -PyDict_GetItemWithError (rejected)
  _Py_INCREF (small function)
  _PyErr_Occurred (optimized to trivial routine)
  -PyObject_GetItem (rejected)
  _PyErr_ExceptionMatches (small function)
    _PyErr_Occurred (optimized to trivial routine)
    -PyErr_GivenExceptionMatches (rejected)
  -_PyErr_Clear (rejected)
  -format_exc_unbound (rejected)
  _Py_INCREF (small function)
  -format_exc_unbound (rejected)
  _Py_INCREF (small function)
  _Py_XDECREF (callgraph decision)
    _Py_DECREF (callgraph decision)
      _Py_Dealloc (small function)
  -PyUnicode_New (rejected)
  -_PyUnicode_JoinArray (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyTuple_New (rejected)
  -PyList_New (rejected)
  -PyList_AsTuple (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _PyList_Extend (small function)
    -list_extend (rejected)
  _PyErr_ExceptionMatches (small function)
    _PyErr_Occurred (optimized to trivial routine)
    -PyErr_GivenExceptionMatches (rejected)
  PySequence_Check (callgraph decision)
    PyType_HasFeature (small function)
  -_PyErr_Clear (rejected)
  -_PyErr_Format (initial scan: varargs, not eligible)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -_PySet_Update (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PySet_New (rejected)
  -PySet_Add (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -_PyDict_NewPresized (rejected)
  -PyDict_SetItem (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -_PyErr_Format (initial scan: parameter mismatch, varargs, not eligible)
  _Py_IS_TYPE (small function)
  _PyDict_GetItemIdWithError (callgraph decision)
    -_PyUnicode_FromId (rejected)
    -_PyDict_GetItem_KnownHash (rejected)
  _PyErr_Occurred (optimized to trivial routine)
  PyDict_New (small function)
    dictkeys_incref (small function)
    -new_dict (rejected)
  _PyDict_SetItemId (callgraph decision)
    -_PyUnicode_FromId (rejected)
    -PyDict_SetItem (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -_PyUnicode_FromId (rejected)
  -PyObject_GetItem (rejected)
  _PyErr_ExceptionMatches (small function)
    _PyErr_Occurred (optimized to trivial routine)
    -PyErr_GivenExceptionMatches (rejected)
  -_PyErr_Clear (rejected)
  PyDict_New (small function)
    dictkeys_incref (small function)
    -new_dict (rejected)
  -PyObject_SetItem (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_IS_TYPE (small function)
  -_PyErr_SetString (rejected)
  -_PyDict_NewPresized (rejected)
  -PyDict_SetItem (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  PyDict_Update (small function)
    -dict_merge (rejected)
  _PyErr_ExceptionMatches (small function)
    _PyErr_Occurred (optimized to trivial routine)
    -PyErr_GivenExceptionMatches (rejected)
  -_PyErr_Format (initial scan: varargs, not eligible)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _PyDict_MergeEx (small function)
    -dict_merge (rejected)
  -format_kwargs_error (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyDict_SetItem (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  PyType_HasFeature (small function)
  _Py_INCREF (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_IS_TYPE (small function)
  _Py_INCREF (small function)
  -_PyDict_GetItemHint (rejected)
  _Py_INCREF (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -_PyErr_Clear (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyType_Ready (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -_PyType_Lookup (rejected)
  _Py_INCREF (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_IS_TYPE (small function)
  _Py_INCREF (small function)
  -_PyDict_GetItemHint (rejected)
  _Py_INCREF (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -_PyErr_Clear (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyObject_GetAttr (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyObject_RichCompare (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_INCREF (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  PySequence_Contains (callgraph decision)
    -_PySequence_IterSearch (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_INCREF (small function)
  PyType_HasFeature (small function)
  _PyType_Check (small function)
    PyType_HasFeature (small function)
  PyType_HasFeature (small function)
  _PyErr_SetString (callgraph decision)
    PyUnicode_FromString (callgraph decision)
      -PyErr_SetString (rejected)
      PyUnicode_DecodeUTF8Stateful (callgraph decision)
        -unicode_decode_utf8 (rejected)
    -_PyErr_SetObject (rejected)
    _Py_XDECREF (callgraph decision)
      _Py_DECREF (callgraph decision)
        _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _PyType_Check (small function)
    PyType_HasFeature (small function)
  PyType_HasFeature (small function)
  -_PyErr_SetString (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyErr_GivenExceptionMatches (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  import_name (callgraph decision)
    _PyDict_GetItemIdWithError (callgraph decision)
      -_PyUnicode_FromId (rejected)
      -_PyDict_GetItem_KnownHash (rejected)
    _PyErr_Occurred (optimized to trivial routine)
    -_PyErr_SetString (rejected)
    -_PyLong_AsInt (rejected)
    _PyErr_Occurred (optimized to trivial routine)
    -PyImport_ImportModuleLevelObject (rejected)
    _Py_INCREF (small function)
    _PyObject_FastCall (callgraph decision)
      PyThreadState_Get (callgraph decision)
        _PyThreadState_GET (small function)
          _PyRuntimeState_GetThreadState (small function)
            _Py_atomic_load_64bit_impl (callgraph decision)
        _Py_EnsureFuncTstateNotNULL (small function)
          -_Py_FatalError_TstateNULL (initial scan: postdominated by noreturn call)
      _PyObject_FastCallTstate (callgraph decision)
        -_PyObject_VectorcallTstate (rejected)
    _Py_DECREF (callgraph decision)
      _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyFrame_FastToLocalsWithError (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -_PyErr_SetString (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -import_all_from (rejected)
  -PyFrame_LocalsToFast (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -import_from (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_atomic_load_32bit_impl (callgraph decision)
  -PyObject_IsTrue (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_atomic_load_32bit_impl (callgraph decision)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_atomic_load_32bit_impl (callgraph decision)
  -PyObject_IsTrue (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_atomic_load_32bit_impl (callgraph decision)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyObject_IsTrue (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyObject_IsTrue (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_atomic_load_32bit_impl (callgraph decision)
  -PyObject_Size (rejected)
  -PyLong_FromSsize_t (rejected)
  -match_class (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _PyErr_Occurred (optimized to trivial routine)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  PyBool_FromLong (callgraph decision)
    _Py_INCREF (small function)
  _Py_INCREF (small function)
  _Py_INCREF (small function)
  -match_keys (rejected)
  _Py_INCREF (small function)
  _Py_INCREF (small function)
  PyDict_New (small function)
    dictkeys_incref (small function)
    -new_dict (rejected)
  PyDict_Update (small function)
    -dict_merge (rejected)
  _Py_XDECREF (callgraph decision)
    _Py_DECREF (callgraph decision)
      _Py_Dealloc (small function)
  -PyDict_DelItem (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyObject_GetIter (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_IS_TYPE (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -_PyErr_SetString (rejected)
  _Py_IS_TYPE (small function)
  -PyObject_GetIter (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _PyErr_Occurred (optimized to trivial routine)
  _PyErr_ExceptionMatches (small function)
    _PyErr_Occurred (optimized to trivial routine)
    -PyErr_GivenExceptionMatches (rejected)
  -call_exc_trace (rejected)
  -_PyErr_Clear (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  PyFrame_BlockSetup (callgraph decision)
    -_Py_FatalErrorFunc (initial scan: postdominated by noreturn call)
  special_lookup (callgraph decision)
    -_PyObject_LookupSpecial (rejected)
    _PyErr_Occurred (optimized to trivial routine)
    -_PyUnicode_FromId (rejected)
    -_PyErr_SetObject (rejected)
  special_lookup (callgraph decision)
    -_PyObject_LookupSpecial (rejected)
    _PyErr_Occurred (optimized to trivial routine)
    -_PyUnicode_FromId (rejected)
    -_PyErr_SetObject (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -_PyObject_CallNoArg (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  PyFrame_BlockSetup (callgraph decision)
    -_Py_FatalErrorFunc (initial scan: postdominated by noreturn call)
  special_lookup (callgraph decision)
    -_PyObject_LookupSpecial (rejected)
    _PyErr_Occurred (optimized to trivial routine)
    -_PyUnicode_FromId (rejected)
    -_PyErr_SetObject (rejected)
  special_lookup (callgraph decision)
    -_PyObject_LookupSpecial (rejected)
    _PyErr_Occurred (optimized to trivial routine)
    -_PyUnicode_FromId (rejected)
    -_PyErr_SetObject (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -_PyObject_CallNoArg (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PyFrame_BlockSetup (rejected)
  PyObject_Vectorcall (callgraph decision)
    PyThreadState_Get (callgraph decision)
      _PyThreadState_GET (small function)
        _PyRuntimeState_GetThreadState (small function)
          _Py_atomic_load_64bit_impl (callgraph decision)
      _Py_EnsureFuncTstateNotNULL (small function)
        -_Py_FatalError_TstateNULL (initial scan: postdominated by noreturn call)
    -_PyObject_VectorcallTstate (rejected)
  -_PyObject_GetMethod (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -call_function (rejected)
  -call_function (rejected)
  _Py_atomic_load_32bit_impl (callgraph decision)
  call_function (callgraph decision)
    -trace_call_function (rejected)
    PyObject_Vectorcall (callgraph decision)
      PyThreadState_Get (callgraph decision)
        _PyThreadState_GET (small function)
          _PyRuntimeState_GetThreadState (small function)
            _Py_atomic_load_64bit_impl (callgraph decision)
        _Py_EnsureFuncTstateNotNULL (small function)
          -_Py_FatalError_TstateNULL (initial scan: postdominated by noreturn call)
      -_PyObject_VectorcallTstate (rejected)
    _Py_DECREF (callgraph decision)
      _Py_Dealloc (small function)
  _Py_atomic_load_32bit_impl (callgraph decision)
  call_function (callgraph decision)
    -trace_call_function (rejected)
    PyObject_Vectorcall (callgraph decision)
      PyThreadState_Get (callgraph decision)
        _PyThreadState_GET (small function)
          _PyRuntimeState_GetThreadState (small function)
            _Py_atomic_load_64bit_impl (callgraph decision)
        _Py_EnsureFuncTstateNotNULL (small function)
          -_Py_FatalError_TstateNULL (initial scan: postdominated by noreturn call)
      -_PyObject_VectorcallTstate (rejected)
    _Py_DECREF (callgraph decision)
      _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_atomic_load_32bit_impl (callgraph decision)
  _Py_IS_TYPE (small function)
  PyDict_New (small function)
    dictkeys_incref (small function)
    -new_dict (rejected)
  _PyDict_MergeEx (small function)
    -dict_merge (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -format_kwargs_error (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_IS_TYPE (small function)
  check_args_iterable (callgraph decision)
    PySequence_Check (callgraph decision)
      PyType_HasFeature (small function)
    -_PyErr_Clear (rejected)
    -_PyObject_FunctionStr (rejected)
    -_PyErr_Format (initial scan: parameter mismatch, varargs, not eligible)
    _Py_DECREF (callgraph decision)
      _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PySequence_Tuple (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -do_call_core (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_XDECREF (callgraph decision)
    _Py_DECREF (callgraph decision)
      _Py_Dealloc (small function)
  _Py_atomic_load_32bit_impl (callgraph decision)
  -PyFunction_NewWithQualName (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -PySlice_New (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_XDECREF (callgraph decision)
    _Py_DECREF (callgraph decision)
      _Py_Dealloc (small function)
  -_PyErr_Format (initial scan: varargs, not eligible)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_XDECREF (callgraph decision)
    _Py_DECREF (callgraph decision)
      _Py_Dealloc (small function)
  _Py_IS_TYPE (small function)
  -PyObject_Format (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  _Py_XDECREF (callgraph decision)
    _Py_DECREF (callgraph decision)
      _Py_Dealloc (small function)
  -unknown_opcode_error (initial scan: not eligible)
  _PyErr_Occurred (optimized to trivial routine)
  _PyErr_SetString (callgraph decision)
    PyUnicode_FromString (callgraph decision)
      PyErr_SetString (callgraph decision)
        _PyThreadState_GET (small function)
          _PyRuntimeState_GetThreadState (small function)
            _Py_atomic_load_64bit_impl (callgraph decision)
        -_PyErr_SetString (initial scan: recursive expansion)
      PyUnicode_DecodeUTF8Stateful (callgraph decision)
        -unicode_decode_utf8 (rejected)
    -_PyErr_SetObject (rejected)
    _Py_XDECREF (callgraph decision)
      _Py_DECREF (callgraph decision)
        _Py_Dealloc (small function)
  -PyTraceBack_Here (rejected)
  -call_exc_trace (rejected)
  _Py_XDECREF (callgraph decision)
    _Py_DECREF (callgraph decision)
      _Py_Dealloc (small function)
  _Py_XDECREF (callgraph decision)
    _Py_DECREF (callgraph decision)
      _Py_Dealloc (small function)
  _Py_XDECREF (callgraph decision)
    _Py_DECREF (callgraph decision)
      _Py_Dealloc (small function)
  _Py_XDECREF (callgraph decision)
    _Py_DECREF (callgraph decision)
      _Py_Dealloc (small function)
  _Py_XDECREF (callgraph decision)
    _Py_DECREF (callgraph decision)
      _Py_Dealloc (small function)
  -PyFrame_BlockSetup (rejected)
  _Py_INCREF (small function)
  _PyErr_Fetch (callgraph decision)
  -_PyErr_NormalizeException (rejected)
  -PyException_SetTraceback (rejected)
  -PyException_SetTraceback (rejected)
  _Py_INCREF (small function)
  _Py_INCREF (small function)
  _Py_INCREF (small function)
  _Py_XDECREF (callgraph decision)
    _Py_DECREF (callgraph decision)
      _Py_Dealloc (small function)
  -call_trace_protected (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  -call_trace_protected (rejected)
  _Py_DECREF (callgraph decision)
    _Py_Dealloc (small function)
  PyDTrace_FUNCTION_RETURN_ENABLED (optimized to trivial routine)
  dtrace_function_return (callgraph decision)
    -PyUnicode_AsUTF8 (rejected)
    -PyUnicode_AsUTF8 (rejected)
    PyFrame_GetLineNumber (callgraph decision)
      -PyCode_Addr2Line (rejected)
    PyDTrace_FUNCTION_RETURN (optimized to trivial routine)
  _Py_LeaveRecursiveCall (small function)
  -_Py_CheckFunctionResult (rejected)

@AlexWaygood AlexWaygood added the performance Performance or resource usage label Feb 21, 2022
Copy link
Member

@gvanrossum gvanrossum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you serious that replacing just those five lines (two calls) with one is enough to make the compiler inline everything again?

@neonene
Copy link
Contributor Author

neonene commented Feb 24, 2022

Are you serious that replacing just those five lines (two calls) with one is enough to make the compiler inline everything again?

The inliner should work again on 3.10.2+ Release as 2d3cb28 shows in the build logs. Other code blocks may need to be replaced in the future.

Using cl.exe with /Ob3 option (eager inlining) can also be the fix on VS2019 and 2022.

@neonene neonene changed the title [3.10] bpo-45116: Fix performance regressions on Windows Release build [3.10] bpo-45116: Fix inlining regressions on Windows Release build Feb 24, 2022
@gvanrossum
Copy link
Member

Oh I see, this is for 3.10 only. For 3.11 we'll have to do something else -- probably we'll first have to instrument things using #31436 .

@zooba What do you think of merging this into 3.10? The evidence seems reasonable, although it's one of those rare PRs that should only be merged for a version branch.

@neonene
Copy link
Contributor Author

neonene commented Apr 23, 2022

3.11 should be focused on now.

@neonene neonene closed this Apr 23, 2022
@neonene neonene deleted the bpo-45116-310 branch April 23, 2022 05:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting review performance Performance or resource usage
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants