Skip to content

Emission allocates 40% less on large files: per-file literal steps, per-def probes, no memo closures (#1262) - #1617

Merged
Lorenzobattistela merged 2 commits into
mainfrom
ai/1262-lits
Oct 16, 2026
Merged

Lorenzobattistela merged 2 commits into
mainfrom
ai/1262-lits

Conversation

@nicolas-abril

Copy link
Copy Markdown
Collaborator

🤖 Written by an AI agent for @nicolas-abril; not yet reviewed by a human.

Part of #1262. This lowers how much compile_book allocates while it emits a large file. It doesn't fix the root cause: emission still re-runs the whole file about 8 times while facts settle (#1386).

Measured on Chromi's examples/eco/main.bend. On main that file fails with duplicate declaration of Text, so I renamed its Text{ to AText{ for the measurement. The emitted C is byte-identical to main's.

main 234cb9b this PR
allocated during emit (V8 sampling) 29.2 GiB 17.4 GiB
bun main.ts wall time, 3 runs 10.3–11.0 s 8.0–8.2 s
max RSS, 3 runs 3.5–5.4 GB 4.2–4.8 GB

RSS depends on when Bun's GC happens to run, and it is too noisy to call a win or a loss.

Changes (comp.ts only, +58/−47):

  • term_force memoizes literal steps per file, keyed by k + v. Before, they were memoized per def and keyed by the term object, so the same literal got stepped again in every def and in every pass (29.2 → 23.1 GiB).
  • compile_book resets PROBES before each def. Before, it only reset in file_new, so it grew from about 131k to 1M entries across the passes. Now it stays at about 430 (23.1 → 22.4 GiB). This is the part to review closely. It's only safe if no probe from an earlier def is still alive in a cache that outlives memo_gc(). The new steps and opens maps hold only probe-free results. teles predates this PR and isn't cleared per def.
  • lay_at memoizes its open-type check (ty_holds(A, Var|App)) per file, keyed by term_key(term_lower(A)) (22.4 → 18.8 GiB).
  • term_uses, term_open and term_spine pass named functions to memo and no longer allocate a closure on every call. term_uses folds with a loop (18.8 → 17.4 GiB).

What's left, from the heap profile: each of the ~8 fixpoint passes allocates about 2.2 GiB (#1386). U32 literal matching (mat_rows/mat_lits) takes about 1.5 GiB, and term_higher about 2.5 GiB.

Checks (macOS M-series, at 539c7e6): ping 59/59, test 1639/1639, perf 124/124, repo 53/54. The one repo failure is the token cap: bend2/comp.ts is 64187 > 64000 ttok. main is already over it at 64092 (repo-gate is red on main), and this PR adds 95. Not run: Linux, CUDA, Metal, hub corpus. safe.ts isn't touched.

@Lorenzobattistela Lorenzobattistela self-assigned this Oct 16, 2026
@Lorenzobattistela
Lorenzobattistela merged commit 239d53f into main Oct 16, 2026
1 of 2 checks passed
@Lorenzobattistela
Lorenzobattistela deleted the ai/1262-lits branch October 16, 2026 21:10
nicolas-abril added a commit to nicolas-abril/bend that referenced this pull request Oct 19, 2026
comp.ts keeps this branch's structure, with upstream's changes ported in:
bendlang#1615's frame-slot write-back in bind_pop; bendlang#1617's named memo functions
(open_of, spine_of, uses_of), per-file literal steps keyed by string, and
lay_at memoized per type key (FL.ty_opens, keyed by ty_key); bendlang#1625's
F32.read regex; bendlang#1628's string_contains.

bendlang#1617's per-def PROBES reset is left out: here probes and the term caches
live as long as the file and units emit again across sweeps, so a reset
would reuse probe indices still held in FL.opens and FL.uses.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
nicolas-abril added a commit to nicolas-abril/bend that referenced this pull request Oct 19, 2026
bendlang#1617 split them into named functions to save a closure per call; on
this branch that changes neither emit time nor peak memory, measured on
boss_3d, hvm5_mini and walkers_test and on a quarter of the corpus.
Output is byte-identical.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Lorenzobattistela Lorenzobattistela mentioned this pull request Oct 20, 2026
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.

2 participants