Skip to content

Feat: Fast entry without per-call depth counting for bounded compiled functions (#147) - #210

Merged
b-re-w merged 4 commits into
developfrom
feat/tp-fast-entry
Oct 17, 2026
Merged

b-re-w merged 4 commits into
developfrom
feat/tp-fast-entry

Conversation

@b-re-w

@b-re-w b-re-w commented Oct 17, 2026

Copy link
Copy Markdown
Member

Closes #147

Feature added:

  • A compiled function is bounded when it is outside every call cycle, all its callees are bounded, and it runs no Python code. redo calls to bounded callees and Box of scalars are allowed.
  • A bounded function gets a static inline fast twin tp_fimpl_f(..., int tp_fd). The twin has no tp_enter_call/tp_leave_call and no entry poll, and it calls the callees' twins, so the C compiler can inline small leaves.
  • The normal impl takes the fast path only when tp_depth_room(k) holds (k = the static depth of the tree). If the precheck fails, the call runs the counted path, so RecursionError is raised at exactly the call where CPython raises it.
  • Wherever a fast tree can run Python code (a redo, a loop poll), the frame count is set to its exact value for that span (tp_depth_py_begin/end(tp_fd)).

Tests added: test_fast_entry.py, 11 tests.

  • What they cover:
    • a differential at every depth around the recursion limit;
    • a redo running a deep compiled call at every depth;
    • a signal handler measuring the recursion depth during a fast tree's poll;
    • the generated-C shape;
    • unbounded functions keep the old path.
  • Red before the change: 6 failed. The 3 tests that passed assert absences.
  • Mutations:
    • a precheck that is always true makes the depth differential fail;
    • dropping the count at redo makes the redo-depth test fail (off by one depth);
    • dropping the count at polls makes the handler test fail (off by tp_fd).

Measured (quiet window, interleaved against develop, 11 pairs; data in benchmarks/typedpython/results/2026-10-17-fast-entry-ab.json):

after / before, median speedup vs CPython
spectral-norm 0.094 (0.093 to 0.717; one outlier pair) 5.6x → 59.4x
fannkuch-redux 1.006 (0.893 to 1.045) 21.8x → 21.7x

spectral-norm now passes the M2 10x criterion (#41). nbody is not measured because it does not compile on develop since #209 (more than two list parameters); that regression is reported separately.

Verification (local):

  • Full TypedPython suite on CPython 3.15.0rc1 free-threaded, with RuntimeWarning as error: 1000 passed, 3 skipped.
  • The benchmarks compile the same function sets as develop.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant