feat(synthesis): dead-store elimination pass (VCR-RA-001, ready-to-wire transform)#246
Merged
Conversation
…re transform) 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>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
avrabe
added a commit
that referenced
this pull request
Jun 5, 2026
…ures the residency gap (#209/#242) (#281) apply_const_cse(instrs): drop a `movw rd,#v` that re-materializes a constant already resident in `ra`, and retarget rd's in-segment reads to ra — every rewrite proven by the liveness analysis (rename_use + safe_cse_uses), and it ONLY removes materializations (pressure never rises), so unlike the mla fusion (#277) it cannot regress on-target. Plus the operand rewriter (rename_use: rewrites uses, never defs; declines on RMW/unmodeled ops) and value ranges. Wired behind SYNTH_CONST_CSE=1 (default-off). VALIDATED SOUND: all three differential fixtures RESULT-IDENTICAL with it on (control_step 0x00210A55, flight_seam 0x07FDF307, div_const 338/338). MEASURED FINDING (the point of this commit): it fires ZERO times on the real flat_flight (170→170 insns, 26→26 movw, byte-identical) — because the greedy selector already DESTROYED the residency it needs: by the second `movw #0x7e` the register that held the first was reused for another value, so there is no resident copy to fold. This is the third time measurement redirected the work (dead-store #246 no-op; mla regressed; const-CSE fires 0). The consistent lesson: const-CSE is an ALLOCATOR capability, not a post-pass — it only fires AFTER re-allocation gives each value a stable register. So the pass stays flag-gated infra (de-risked, differential-validated, ready for the post-re-allocation pipeline stage), NOT default-on (0 delta on greedy code, which the audit rule forbids shipping). Tests: fold a redundant clamp bound; decline on clobbered-resident; decline on maybe-live-out. clippy/fmt clean. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
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.
The analysis layer is complete on main (#243 + #245); this adds the first transform built on it.
What
eliminate_dead_stores()— removes the provably-dead storesanalyze_functionfinds (a write overwritten before any use within its straight-line segment, which makes it dead regardless of cross-block liveness). The generic, function-wide form of the hand-rolled #221 peephole (drop_prev_const_materialization).Branch-offset safety (by construction)
Dead instructions are interior to a straight-line segment and are never branch targets, so removing one is offset-neutral. Intended to run on
select_with_stackoutput beforeresolve_label_branches, where branches are still symbolic labels (resolved to bytes afterward) — so the rewrite cannot perturb any target.Side-by-side discipline
Pure function — not wired into codegen by this change, so emitted bytes are unchanged: control_step
0x00210A55ORACLE PASS, 279 lib tests. 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 awaitedflat_flightdelta.Tests (3)
#9, drops the dead#7).Where this sits on the track
analysis (
reg_effect→local_dead_defs/redundant_const_defs→analyze_function) is done; this is the first transform pass. Next: the gated wiring into the codegen path, then the harder const-CSE/spill transforms that need the allocator's register-keeping (the part that movesflat_flight's 315 cyc).Part of #242.
🤖 Generated with Claude Code