Found in numpy in numpy/numpy#33290
Numpy uses a "hack" to do temporary elision for arithmetic expressions to avoid allocating memory for temporaries. One thing it does to enable this elision is to detect "Am I being called directly by the python interpreter?" and part of that check is the question, "Is _PyEval_EvalFrameDefault in the call stack?".
Now on my macos machine for example with clang, If I'm on an interpreter that was built with --with-tail-call-interp such as the conda-forge build of cpython, _PyEval_EvalFrameDefault is no longer in the call stack and temporary elision is disabled so users lose this nice performance boost. On that issue I was informed that _PyEval_EvalFrameDefault should still be in the call stack and in turns out that this is probably PGO inlining as marking _PyEval_EvalFrameDefault with Py_NO_INLINE brings it back in the call stack. Is there any chance cpython can do something about that? Such as making the function Py_NO_INLINE? I'd be happy to send a patch if that's a fine approach.
Here are some call stacks with lldb to showcase my point that I got with spin lldb -- $(pyenv which python) -P -c 'import numpy as np; n = 1<<16; np.ones(n) + np.ones(n) + np.ones(n)'
Without tail-call interpeter:
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
* frame #0: 0x0000000106372710 _multiarray_umath.cpython-314-darwin.so`check_callers(cannot=0x000000016fdfd020) at temp_elide.c:165:9
frame #1: 0x0000000106372460 _multiarray_umath.cpython-314-darwin.so`can_elide_temp(olhs=0x0000000105273390, orhs=0x00000001052f40f0, cannot=0x000000016fdfd020) at temp_elide.c:348:20
frame #2: 0x0000000106372018 _multiarray_umath.cpython-314-darwin.so`try_binary_elide(m1=0x0000000105273390, m2=0x00000001052f40f0, inplace_op=(_multiarray_umath.cpython-314-darwin.so`array_inplace_add at number.c:517), res=0x000000016fdfd060, commutative=1) at temp_elide.c:366:9
frame #3: 0x0000000106358e08 _multiarray_umath.cpython-314-darwin.so`array_add(m1=0x0000000105273390, m2=0x00000001052f40f0) at number.c:243:9
frame #4: 0x0000000100063fbc python`PyNumber_Add + 92
frame #5: 0x00000001001f1158 python`_PyEval_EvalFrameDefault + 528
frame #6: 0x00000001001efca4 python`_PyEval_Vector + 576
frame #7: 0x00000001001ef9c0 python`PyEval_EvalCode + 160
frame #8: 0x00000001003b3a48 python`run_mod + 232
frame #9: 0x00000001003b387c python`_PyRun_String + 192
frame #10: 0x00000001002a7c58 python`_PyRun_SimpleString + 156
frame #11: 0x00000001002d4f28 python`Py_RunMain + 416
frame #12: 0x00000001003b7ab0 python`pymain_main + 464
frame #13: 0x0000000100000954 python`main + 44
frame #14: 0x00000001838b0d7c dyld`start + 6652
And with tail-call interpeter:
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
* frame #0: 0x000000010639e710 _multiarray_umath.cpython-314-darwin.so`check_callers(cannot=0x000000016fdfd6d0) at temp_elide.c:165:9
frame #1: 0x000000010639e460 _multiarray_umath.cpython-314-darwin.so`can_elide_temp(olhs=0x000000010529f390, orhs=0x00000001053200f0, cannot=0x000000016fdfd6d0) at temp_elide.c:348:20
frame #2: 0x000000010639e018 _multiarray_umath.cpython-314-darwin.so`try_binary_elide(m1=0x000000010529f390, m2=0x00000001053200f0, inplace_op=(_multiarray_umath.cpython-314-darwin.so`array_inplace_add at number.c:517), res=0x000000016fdfd710, commutative=1) at temp_elide.c:366:9
frame #3: 0x0000000106384e08 _multiarray_umath.cpython-314-darwin.so`array_add(m1=0x000000010529f390, m2=0x00000001053200f0) at number.c:243:9
frame #4: 0x00000001000658cc python`PyNumber_Add + 92
frame #5: 0x000000010034df80 python`_TAIL_CALL_BINARY_OP + 68
frame #6: 0x00000001001ec4c4 python`_PyEval_Vector + 820
frame #7: 0x00000001001ec0ec python`PyEval_EvalCode + 160
frame #8: 0x0000000100382978 python`run_mod + 232
frame #9: 0x00000001003827ac python`_PyRun_String + 192
frame #10: 0x0000000100253544 python`_PyRun_SimpleString + 156
frame #11: 0x000000010028071c python`Py_RunMain + 416
frame #12: 0x000000010038693c python`pymain_main + 464
frame #13: 0x0000000100000954 python`main + 44
frame #14: 0x00000001838b0d7c dyld`start + 6652
cc @ngoldbaum @Fidget-Spinner
Linked PRs