Lift ct 2 / ct 3 count-by-predicate to native VM dispatch (PR C of ILO-45)#707
Merged
Conversation
PR C of ILO-45. Adds a combined `(Builtin::Ct, 2) | (Builtin::Ct, 3)`
compiler arm that emits a per-element OP_CALL_DYN loop with a numeric
counter accumulator. No new opcode or finalizer needed — counter
increments via OP_ADDK_N on the true branch of the bool typecheck,
identical to flt's predicate shape minus the LISTAPPEND.
Argc=1 for plain `ct fn xs`, argc=2 for closure-bind `ct fn ctx xs`.
Both share the same arm; the ctx variant just allocates the extra
contiguous arg1_reg before the loop. Cranelift inherits via the
existing OP_CALL_DYN codegen.
Two entries removed from is_tree_bridge_eligible. After this PR, the
only FnRef-taking entries left on the bridge are gone — the remaining
work for the eval-loop deletion is:
- PR D: audit non-HOF bridge entries for transitive eval_body
reachability, lift any that need it
- PR E: delete eval_body / eval_stmt / eval_expr / Env / trampoline
AOT object baselines updated for the two examples that exercise `ct`
(ct-count-by-predicate, reserved-names). The remaining 134 baselines
are byte-identical to PR B's regen.
Test plan: cargo test --release --features cranelift green.
Smoke test: pos / above-threshold counts give identical output across
default / --vm / --jit. examples/ct-count-by-predicate.@ covers
both ct 2 and ct 3 (closure-bind) — now natively dispatched.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
This was referenced May 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PR C of ILO-45 — third slice of the tree-walker eval-loop deletion. Lifts
ct fn xsandct fn ctx xsoff the tree-bridge to native VM dispatch via a per-element OP_CALL_DYN loop with a numeric counter accumulator. No new opcode needed — counter increments via the existing OP_ADDK_N on the true branch of the bool typecheck.After this PR, every FnRef-taking entry on
is_tree_bridge_eligiblehas been lifted. The remaining bridge entries are all non-HOF builtins (regex, fmt, fs metadata, crypto, calendar, sleep, run, env-all, math constants, jkeys). PR D will audit those for transitiveeval_bodyreachability, and PR E will delete the eval loop itself.What's in the diff
Single commit, two files:
src/vm/mod.rs(Builtin::Ct, 2) | (Builtin::Ct, 3) =>arm incompile_call. Argc=1 (plain) vs argc=2 (closure-bind) handled by conditionally allocating arg1_reg. Same bool-typecheck error shape as flt 2/3 ("ct: predicate must return bool" via WRAPERR + PANIC_UNWRAP).is_tree_bridge_eligible.tests/aot-baselines/obj-baselines.tsvct-count-by-predicateandreserved-names(the only examples exercisingct). Other 134 baselines byte-identical to PR B's regen.Test plan
cargo test --release --features cranelift— full suite greenpos/above-thresholdcounts give identical output across default /--vm/--jitexamples/ct-count-by-predicate.@covers bothct 2andct 3closure-bind — now natively dispatchedsuperpowers:code-reviewersubagent run on the diff — no blockers (flagged a closure-with-captures coverage gap that's shared with PRs A and B's lifts, not new in C)Follow-ups
eval_bodyreachability; lift any that still call into the eval loop internallyeval_body/eval_stmt/eval_expr/Env/ trampoline /ACTIVE_AST_PROGRAM(the headline LoC win)