Skip to content

feat(synthesis): register def/use + liveness foundation (VCR-RA-001 step 1)#243

Merged
avrabe merged 1 commit into
mainfrom
feat/vcr-ra-001-liveness-foundation
Jun 4, 2026
Merged

feat(synthesis): register def/use + liveness foundation (VCR-RA-001 step 1)#243
avrabe merged 1 commit into
mainfrom
feat/vcr-ra-001-liveness-foundation

Conversation

@avrabe

@avrabe avrabe commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

First incremental step on the verified-codegen roadmap's allocator track — VCR-RA-001 (epic #242, artifacts/verified-codegen-roadmap.yaml).

Why

The cleanup audit keeps finding the same root cause: the cost-gated fallbacks exist because select_with_stack has no liveness reasoning — it tracks a virtual stack and hard-fails on exhaustion (instruction_selector.rs:330/356/577/4667) instead of reasoning over live ranges. A spill-capable allocator needs a def/use + liveness primitive first. This lands that primitive — the reusable foundation a real allocator, DCE, and peephole-safety checks all build on.

What (additive, pure analysis — not wired into codegen)

crates/synth-synthesis/src/liveness.rs:

  • RegEffect + reg_effect(&ArmOp) — per-instruction register def/use. Precise for the scalar integer ARM ops (ALU / mov / movw / movt / mul / umull / mls / shifts / loads / stores / cmp / push / pop). Subtleties handled: a store's source operand is a use not a def; Movt/MovtSym read+write rd (preserve the low half).
  • local_dead_defs() — sound dead-store detection within a straight-line block: the generic form of the hand-rolled dead-divisor-const peephole (cleanup(selector): dead divisor constant materialized on reciprocal-multiply path (#209 accretion) #221, drop_prev_const_materialization).

Soundness

Ops not yet modeled precisely — high-level pseudo-ops (LocalGet, Select…), the i64-pair ops, FP, calls, control flow — return None from reg_effect, and every analysis returns None for a stream it cannot fully model. A non-None result is always trustworthy; a wrong answer is never produced.

Frozen-fixture safety

Nothing here is called from codegen, so emitted bytes are unchanged: control_step 0x00210A55 ORACLE PASS (bit-identical). Full synth-synthesis lib suite: 269 passed. 7 new unit tests (three-operand ALU; store-source-is-a-use; Movt read+write; pseudo/call decline; dead-store detected; intervening-use respected; branch/unmodeled declines).

Next steps on VCR-RA-001

CFG-aware (cross-block) liveness; interference graph over virtual registers (pre-allocation, where true pressure lives); then spill-under-pressure to replace the exhaustion hard-fail — at which point the reciprocal-mult cost-gate becomes revert-able (the VCR-VER-001 gate).

Part of #242.

🤖 Generated with Claude Code

…tep 1)

First incremental step of the verified-codegen roadmap's allocator track
(VCR-RA-001, epic #242). The current codegen has NO liveness reasoning:
select_with_stack tracks a virtual stack and hard-fails on exhaustion
(instruction_selector.rs:330/356/577/4667) instead of reasoning over live
ranges — which is what forces the cost-gated fallbacks the cleanup audit keeps
flagging. This lands the reusable primitive a spill-capable allocator (and DCE,
and peephole-safety) is built on.

New module crates/synth-synthesis/src/liveness.rs (pure analysis, NOT wired into
codegen → emitted bytes unchanged, frozen fixtures bit-identical):
- RegEffect + reg_effect(&ArmOp): per-instruction register def/use. Precise for
  the scalar integer ARM ops (ALU/mov/movw/movt/mul/umull/mls/shifts/loads/
  stores/cmp/push/pop). Store source operands are USES not defs; Movt/MovtSym
  read+write rd (preserve low half).
- local_dead_defs(): sound dead-store detection within a straight-line block —
  the GENERIC form of the hand-rolled dead-divisor-const peephole (#221).

Soundness discipline: ops not yet modeled precisely (high-level pseudo-ops,
i64-pair, FP, calls, control flow) return None from reg_effect, and every
analysis returns None for a stream it cannot fully model — a non-None result is
always trustworthy.

Tests (7): three-operand ALU, store-source-is-a-use, Movt read+write,
pseudo/call ops decline, dead-store detected, intervening-use respected,
branch/unmodeled declines. Full lib suite 269 passed; control_step fixture
ORACLE PASS (bit-identical).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@codecov

codecov Bot commented Jun 4, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 78.46154% with 42 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
crates/synth-synthesis/src/liveness.rs 78.46% 42 Missing ⚠️

📢 Thoughts on this report? Let us know!

@avrabe avrabe merged commit 026d58b into main Jun 4, 2026
13 of 14 checks passed
@avrabe avrabe deleted the feat/vcr-ra-001-liveness-foundation branch June 4, 2026 18:06
avrabe added a commit that referenced this pull request Jun 4, 2026
Document the verified-codegen north star where contributors and future sessions
will see it: replace the patch-accreting single-pass selector + allocator with
foundationally-verified, allocator-robust infrastructure — correctness from
construction, not an ever-growing pile of locally-correct patches.

- README.md: new "Roadmap — North Star" section after Formal Verification — the
  thesis, the VCR-* track table (A codegen core / B authoritative semantics /
  C validation / VCR-VER-001 gate) with statuses, and gale's silicon target for
  Track A (#209: flat_flight 315 cyc vs 99 native, 61% redundant const
  materializations, 17 spills — const-CSE + liveness-based spilling).
- CLAUDE.md: a "North Star (roadmap)" pointer after Proof Status so future
  sessions carry the program context.

Refs epic #242, PR #243 (VCR-RA-001 step 1), #209 (silicon target).

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
avrabe added a commit that referenced this pull request Jun 4, 2026
…-RA-001) (#245)

* feat(synthesis): redundant-constant detection (VCR-RA-001, const-CSE analysis)

Second analysis on the verified-codegen allocator track (#242), building on the
liveness primitive from #243. Adds redundant_const_defs(): within a straight-line
block, the constant materializations that re-derive a value ALREADY resident in a
register (not clobbered since) — the forward dual of local_dead_defs (which finds
a write with no later read; this finds a write whose value was already computed).

This is the analysis behind const-CSE / rematerialization-avoidance — the
dominant hot-path waste gale measured on flat_flight (#209): the int8 saturation
clamps #0x7e / #0x7f re-materialized 6x each, 61% of all constant loads
redundant. A new test reproduces that exact pattern (6 clamp loads, first stays
live -> 5 flagged redundant).

Pure detection — reports the opportunity; the fix (keep the constant resident
across its uses) is the allocator's job. Recognizes the single-instruction const
forms (Movw 16-bit, Mov #imm); a Movw;Movt pair is correctly NOT treated as a
pure 16-bit const (Movt invalidates the tracked value). Returns None for any
stream it cannot fully model (branch / call / unmodeled op), so a result is never
wrong. Not wired into codegen -> emitted bytes unchanged.

Tests (5): rematerialization-while-resident flagged; clobber respected;
flat_flight 6x-clamp pattern -> 5 redundant; Movw;Movt pair not a pure const;
declines on branch. Full lib suite 274 passed; control_step ORACLE PASS
(bit-identical).

Part of #242.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(synthesis): apply the const-CSE/dead-store detectors function-wide

Make the analyses usable on real (branchy) functions. The per-block detectors
decline (None) on any branch; real functions like flat_flight (the br_table
clamps gale measures, #209) are a sequence of straight-line blocks separated by
control flow.

analyze_function() splits the stream into MAXIMAL straight-line, fully-modeled
segments (a branch/call/unmodeled op ends the current segment), runs both
local_dead_defs and redundant_const_defs per segment, and reports global
indices + segment/skip counts. Sound by construction: state resets at every
boundary, so cross-block redundancy is under-reported, never over-reported, and
an unmodeled instruction never lands inside a segment. Never returns None — it
analyzes whatever is analyzable.

This is what lets the const-CSE detector be pointed at flat_flight (gale's frozen
Track-A baseline 315 cyc / 34 const-loads / 13 distinct) and yield a real
function-wide redundancy count, instead of declining on the first branch.

Tests (2): redundancy found in BOTH segments across a branch (per-block detector
declines on the whole stream); no cross-boundary redundancy claimed (state reset
at the boundary). Full lib suite 276 passed; control_step ORACLE PASS
(bit-identical, still pure analysis — not wired into codegen).

Part of #242.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
avrabe added a commit that referenced this pull request Jun 4, 2026
…re transform) (#246)

The analysis layer is complete on main (#243 + #245); this adds the first
TRANSFORM built on it — eliminate_dead_stores(): removes the provably-dead
stores analyze_function finds (a write overwritten before any use within its
straight-line segment, dead regardless of cross-block liveness). The generic,
function-wide form of the hand-rolled #221 peephole.

Branch-offset safety is by construction: dead instructions are interior to a
straight-line segment and never branch targets, so the rewrite is offset-neutral
— intended to run on select_with_stack output BEFORE resolve_label_branches,
where branches are still symbolic labels.

Side-by-side discipline: this is a PURE function, NOT wired into codegen by this
change, so emitted bytes are unchanged (control_step ORACLE PASS). The wiring is
a separate, fully oracle-gated step (every differential fixture result-identical
+ a measured size/cycle delta + fuzz) — the migration that finally emits gale's
awaited flat_flight delta.

Tests (3): overwritten def removed (keeps the live one); no-op + identical stream
when nothing dead; a def at a segment boundary is never removed (could be live
past the branch). Full lib suite 279 passed.

Part of #242.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
avrabe added a commit that referenced this pull request Jun 4, 2026
…put (VCR-RA-001) (#247)

* test(synthesis): validate liveness analyses against real selector output (VCR-RA-001)

The liveness/CSE analyses (#243/#245) and the dead-store transform (#246) are
unit-tested on synthetic instruction vectors. Before wiring the transform into
the codegen path, confirm the analyses are sound on REAL select_with_stack
output: run the actual selector on a constant-reusing sequence
((p & 0x7e) + (p & 0x7e), mirroring gale's repeated-clamp shape) and assert
analyze_function / redundant_const_defs / eliminate_dead_stores are internally
consistent with the emitted instructions — every reported redundant-const index
is a materialization of the claimed value, dead-def indices are valid, and
elimination is length-consistent.

This is the precondition for the gated wiring step: the analysis correctly reads
real codegen, not just hand-built vectors. Pure test addition — no codegen
change.

Part of #242.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* style: rustfmt the VCR validation test

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
avrabe added a commit that referenced this pull request Jun 5, 2026
…rectness fixes (#260)

Promote the accumulated v0.11.30 work into the CHANGELOG before tagging:
native-pointer ABI (#237) + the VCR-* constant-immediate folding (#250/#252/#254)
+ analysis foundation (#243/#245) + three latent-miscompile encoder fixes
(#251 ORR/EOR NOP, #253 ADD/SUB large-frame, #255 CMP/ADDS/SUBS ThumbExpandImm).
Adds a falsification statement covering the encoder correctness class.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
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