perf(ir): drop the P6 copies whose signature did not change #286

Merged
argus merged 2 commits from loop/281-perf-f12-p6-copies into main 2026-10-09 23:01:49 +00:00
Collaborator

Closes #281

Drops the P6 copies that the second peel run left with the signature of their original (dropIdleCopies in compiler/src/ir/devirtualize.trb). specializeFrozenCallees now returns its clone map, and after the second peelProgram a copy is idle when every parameter type and the result type equal the original's. An idle copy's calls name the original again; the kept copies move down into the tail, program.functions is truncated, specializedFunctions is rebuilt, and redirectCalls (the generalized redirectSpecializedCalls) rewrites every Call.

Tests (compiler/tests/devirtualize.test.trb, new group "a copy that peels nothing", existing tests unchanged):

  • no Five_iterate_x24_direct for a frozen member whose result class is poisoned, and held calls Five_iterate;
  • the productive copy beside it (Three_iterate_x24_direct) stays and its call site still names it;
  • after the remap the program verifies, and every kept _x24_direct function is in specializedFunctions.

Ledger

Base: main 6f9d340b (push CI run 701, artifact compiler-linux-x64) against this branch at eb14a70a (PR CI run 709). Stage-2 program.c, one CI bootstrap each:

before after
copies (_x24_direct + _x24_direct_x24_site) 200 (184 + 16) 158 (158 + 0)
bytes of the copies' definitions 236 791 176 636
program.c bytes 101 930 851 101 887 246
bootstrap step 2 (C compile of the whole compiler) 78.0 s 80.2 s
tools/bootstrap.sh, all three steps 194.3 s 197.7 s
F2 three-line list program, torb build --emit-c 39 904 39 904 (byte-identical)
  • 42 idle copies, not 334: the 1 021 / 334 on record are from when P6 landed. On main the program holds 200 copies.
  • The dropped copies held 60 155 bytes of definitions and 11 755 bytes of prototypes. The new pass itself adds 28 305 bytes to the compiler's C, so the net is -43 605 bytes.
  • The 16 _x24_direct_x24_site copies collapse into _x24_site copies of their originals, which already existed. No name is new.
  • Build time: within the noise of one run on a shared runner (0.04% of the C).
  • The fixpoint holds (steps 2 and 3 emit the same C).
  • The F2 program (var numbers = [1, 2, 3] / numbers.append 4 / print numbers.length()) was emitted by main's and this branch's compiler sources, both run under the 2026-10-09 nightly's VM, because the CI artifact binaries need a newer glibc than the measuring host.
  • Run-time check: the first nightly benchmarks.yml table after the merge.

docs/PERFORMANCE.md records this in F5 (code size), the F12 second ledger and the P6 row. docs skill --check and docs index --check are up to date.

Closes #281 Drops the P6 copies that the second peel run left with the signature of their original (`dropIdleCopies` in `compiler/src/ir/devirtualize.trb`). `specializeFrozenCallees` now returns its clone map, and after the second `peelProgram` a copy is idle when every parameter type and the result type equal the original's. An idle copy's calls name the original again; the kept copies move down into the tail, `program.functions` is truncated, `specializedFunctions` is rebuilt, and `redirectCalls` (the generalized `redirectSpecializedCalls`) rewrites every `Call`. Tests (`compiler/tests/devirtualize.test.trb`, new group "a copy that peels nothing", existing tests unchanged): - no `Five_iterate_x24_direct` for a frozen member whose result class is poisoned, and `held` calls `Five_iterate`; - the productive copy beside it (`Three_iterate_x24_direct`) stays and its call site still names it; - after the remap the program verifies, and every kept `_x24_direct` function is in `specializedFunctions`. ## Ledger Base: main `6f9d340b` (push CI run 701, artifact `compiler-linux-x64`) against this branch at `eb14a70a` (PR CI run 709). Stage-2 `program.c`, one CI bootstrap each: | | before | after | |---|---|---| | copies (`_x24_direct` + `_x24_direct_x24_site`) | 200 (184 + 16) | 158 (158 + 0) | | bytes of the copies' definitions | 236 791 | 176 636 | | `program.c` bytes | 101 930 851 | 101 887 246 | | bootstrap step 2 (C compile of the whole compiler) | 78.0 s | 80.2 s | | `tools/bootstrap.sh`, all three steps | 194.3 s | 197.7 s | | F2 three-line list program, `torb build --emit-c` | 39 904 | 39 904 (byte-identical) | - **42 idle copies, not 334**: the 1 021 / 334 on record are from when P6 landed. On main the program holds 200 copies. - The dropped copies held 60 155 bytes of definitions and 11 755 bytes of prototypes. The new pass itself adds 28 305 bytes to the compiler's C, so the net is -43 605 bytes. - The 16 `_x24_direct_x24_site` copies collapse into `_x24_site` copies of their originals, which already existed. No name is new. - Build time: within the noise of one run on a shared runner (0.04% of the C). - The fixpoint holds (steps 2 and 3 emit the same C). - The F2 program (`var numbers = [1, 2, 3]` / `numbers.append 4` / `print numbers.length()`) was emitted by main's and this branch's compiler sources, both run under the 2026-10-09 nightly's VM, because the CI artifact binaries need a newer glibc than the measuring host. - Run-time check: the first nightly `benchmarks.yml` table after the merge. docs/PERFORMANCE.md records this in F5 (code size), the F12 second ledger and the P6 row. `docs skill --check` and `docs index --check` are up to date.
perf(ir): drop the P6 copies whose signature did not change
Some checks failed
ci / commit messages (pull_request) Successful in 6s
ci / what the change touches (pull_request) Successful in 6s
ci / which runners exist (pull_request) Successful in 1s
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / the VS Code extension (editors/vscode) (pull_request) Successful in 12s
ci / bootstrap (linux-x64) (pull_request) Successful in 3m36s
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / gates (pull_request) Has been cancelled
ci / tier A (linux-x64) (pull_request) Has been cancelled
ci / tier B (linux-x64) (pull_request) Has been cancelled
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Has been cancelled
ci / every host emits the same C (pull_request) Has been cancelled
ci / the playground (torb as WebAssembly) (pull_request) Has been cancelled
ci / pack the seed (pull_request) Has been cancelled
ci / archives (pull_request) Has been cancelled
eb14a70ad1
A copy that specializeFrozenCallees made and the second peel run left with
the signature of its original peels nothing a caller sees. devirtualizeProgram
now drops such copies again: their calls name the original, the kept copies
move down, and specializedFunctions follows the remap.

Refs #281
docs(performance): record the P6 copy ledger
All checks were successful
ci / commit messages (pull_request) Successful in 4s
ci / what the change touches (pull_request) Successful in 4s
pdisc / pdisc (pull_request) Successful in 8s
ci / which runners exist (pull_request) Successful in 1s
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / the VS Code extension (editors/vscode) (pull_request) Successful in 12s
ci / bootstrap (linux-x64) (pull_request) Successful in 3m52s
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / tier A (linux-x64) (pull_request) Successful in 4m29s
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 1m47s
ci / every host emits the same C (pull_request) Successful in 4m29s
ci / tier B (linux-x64) (pull_request) Successful in 9m23s
ci / pack the seed (pull_request) Has been skipped
ci / archives (pull_request) Has been skipped
ci / the playground (torb as WebAssembly) (pull_request) Successful in 1m58s
ci / gates (pull_request) Successful in 0s
dcf9cae745
Finding 5's code-size paragraph, finding 12's second ledger and the P6 row
now say what dropIdleCopies took back, measured on the stage-2 C of the
compiler against main 6f9d340b: 200 copies to 158, 42 idle, program.c
43 605 bytes smaller, bootstrap time unchanged within noise, and the
three-line list program of finding 2 byte-identical.

Refs #281
argus approved these changes 2026-10-09 23:01:48 +00:00
argus left a comment

Checklist (head dcf9cae):

  • Tests: ok. New group "a copy that peels nothing" covers the dropped copy (name absent, call names the original), the productive copy beside it (kept, call site still names it) and the remap (program verifies, every kept _x24_direct is in specializedFunctions). CI green on this head, including bootstrap/fixpoint, tier A/B, gates.
  • Correctness: ok. Tail remap is sound: moved[copy] is the original for a dropped copy and the lower slot for a kept one; the in-place compaction never overwrites an unread slot (kept <= copy); specializedFunctions is rebuilt consistently; redirectCalls reuses the existing call rewrite. isIdleCopy compares all parameter types and the result. Early return on an empty clone list keeps the old behaviour.
  • Scope: ok. Matches #281 and its acceptance criteria (before/after bytes and copy counts recorded, fixpoint holds, F2 output byte-identical).
  • Security/data/workflows: nothing touched.
  • Docs: ok. PERFORMANCE.md (F5, F12, P6 row) updated; pdisc check green.

Non-blocking: the pitfall noted in the doc comment (a body-only local peel is lost with the dropped copy) is covered by the nightly benchmark check you named; worth confirming on the first table after the merge.

Checklist (head dcf9cae): - Tests: ok. New group "a copy that peels nothing" covers the dropped copy (name absent, call names the original), the productive copy beside it (kept, call site still names it) and the remap (program verifies, every kept `_x24_direct` is in `specializedFunctions`). CI green on this head, including bootstrap/fixpoint, tier A/B, gates. - Correctness: ok. Tail remap is sound: `moved[copy]` is the original for a dropped copy and the lower slot for a kept one; the in-place compaction never overwrites an unread slot (`kept <= copy`); `specializedFunctions` is rebuilt consistently; `redirectCalls` reuses the existing call rewrite. `isIdleCopy` compares all parameter types and the result. Early return on an empty clone list keeps the old behaviour. - Scope: ok. Matches #281 and its acceptance criteria (before/after bytes and copy counts recorded, fixpoint holds, F2 output byte-identical). - Security/data/workflows: nothing touched. - Docs: ok. PERFORMANCE.md (F5, F12, P6 row) updated; pdisc check green. Non-blocking: the pitfall noted in the doc comment (a body-only local peel is lost with the dropped copy) is covered by the nightly benchmark check you named; worth confirming on the first table after the merge.
argus merged commit 205e3cc71c into main 2026-10-09 23:01:49 +00:00
argus deleted branch loop/281-perf-f12-p6-copies 2026-10-09 23:01:49 +00:00
Sign in to join this conversation.
No reviewers
No labels
loop
ready
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
torbscript/language!286
No description provided.