feat(edgecfg): Phase 281 P3 - cleanup Normal wiring + docs

This commit is contained in:
2025-12-23 04:11:02 +09:00
parent 2d5607930c
commit a744be929a
9 changed files with 675 additions and 111 deletions

View File

@ -2,20 +2,23 @@
## Current Focus (next)
- Phase 273design-first: `docs/development/current/main/phases/phase-273/README.md`
- P3 proposal: generalized CoreLoopPlan を SSOT 化して legacy fallback を撤去(収束の完成
- 指示書: `docs/development/current/main/phases/phase-273/P3-CLAUDE.md`
- Phase 281design-first: `docs/development/current/main/phases/phase-281/README.md`
- P1 planned: Pattern6early-exitを compose に寄せる(挙動不変で段階移行
- SSOT: `docs/development/current/main/design/edgecfg-fragments.md`, `src/mir/builder/control_flow/edgecfg/api/compose.rs`
- Phase 282planned, design-first: Router shrinkage
- pattern番号を “症状ラベル(テスト名)” に降格し、合成SSOTへ寄せた後に router を縮退させる
## Recently Completed (2025-12-22)
## Recently Completed (2025-12-23)
- Phase 280Frag composition SSOT positioning: `docs/development/current/main/phases/phase-280/README.md`
- Phase 281 P0Pattern7 → compose::if_: `docs/development/current/main/phases/phase-281/README.md`
- Phase 273Plan line SSOT: `docs/development/current/main/phases/phase-273/README.md`
- Phase 275 P0A1/B2/C2 coercion SSOT: `docs/development/current/main/phases/phase-275/README.md`
- Phase 276 P0quick wins / type_helper SSOT: `docs/development/current/main/phases/phase-276/README.md`
- Phase 277 P1PHI strict fail-fast: `docs/development/current/main/phases/phase-277/README.md`
- Phase 277 P2PHI env var 統合): `docs/development/current/main/phases/phase-277/README.md`
- Phase 278 P0deprecated PHI env vars removal: `docs/development/current/main/phases/phase-278/README.md`
- Phase 279 P0type propagation pipeline SSOT unification: `docs/development/current/main/phases/phase-279/README.md`
- Phase 273 P0Plan Extractor PoC: `docs/development/current/main/phases/phase-273/README.md`
- Phase 273 P1/P2Domain→Core→Lowerer + Pattern7移行: `docs/development/current/main/phases/phase-273/README.md`
---

View File

@ -8,16 +8,12 @@ Related:
## 直近JoinIR/selfhost
- **Phase 277 P0/P1planned, docs+validation: PHI型推論ドキュメント整備 + PHI順序検証強化**
- 入口: `docs/development/current/main/phases/phase-277/README.md`
- 目的:
- Phase 275/276 で入った PHI 型推論の “導線/責務/SSOT” を docs に固定する
- PHI 配置順序PHI → non-PHI → terminator違反を fail-fast で検出しやすくする
- **Phase 281planned: Pattern6 を compose へ段階吸収**
- 入口: `docs/development/current/main/phases/phase-281/README.md`
- P0Pattern7✅ 完了、次は P1Pattern6 early-exit
- **Phase 278planned, cleanup: PHI旧環境変数の後方互換性削除**
- 目的: Phase 277 P2 で deprecated 扱いにした旧 env var を削除し、1セットに収束させる
- 入口: `docs/development/current/main/phases/phase-278/README.md`
- 実装ガイド: `docs/development/current/main/phases/phase-278/P0-INSTRUCTIONS.md`
- **Phase 282planned: Router shrinkage**
- 目的: pattern番号を “症状ラベル” に縮退させ、合成SSOTへ寄せた後に router の分岐を減らす
(✅ done**Phase 279 P0**: Type propagation pipeline SSOT 統一lifecycle / JoinIR / LLVM の二重化解消)
- 完了: `docs/development/current/main/phases/phase-279/README.md`
@ -28,16 +24,12 @@ Related:
- 入口: fixture/smoke を SSOT として固定Pattern6→Pattern7 の順で段階適用)
- 詳細: `phases/phase-272/README.md`
- **Phase 273active, design-first: Pattern → Plan Extractorpure→ PlanLowerer で収束**
- 目的: pattern の裾広がりを止め、`Plan → Frag → emit_frag()` の本線へ一本化するterminator SSOT は維持)
- 相談メモ: `docs/development/current/main/investigations/phase-272-frag-plan-architecture-consult.md`
- 状況:
- ✅ P0PoC完了: `docs/development/current/main/phases/phase-273/README.md`
- 次: P1DomainPlan→CorePlan + PlanNormalizerSSOT+ PlanVerifier
- 受け入れ(最小):
- extractor が builder を触らないID採番/PHI挿入禁止
- CorePlan 語彙を固定(`seq/if/loop/exit/effect` など。scan専用 Effect/variant 禁止、式を String にしない
- PlanLowerer が block/value/phi を作る唯一の箱になる
- (✅ done**Phase 273**: Plan line SSOTPattern6/7
- 完了: `docs/development/current/main/phases/phase-273/README.md`
- (✅ done**Phase 277/278**: PHI strict + env var 収束
- 完了: `docs/development/current/main/phases/phase-277/README.md`
- 完了: `docs/development/current/main/phases/phase-278/README.md`
- **Phase 274active, design-first: Type SSOT Alignmentlocal + dynamic runtime**

View File

@ -1,6 +1,6 @@
# Phase 273: Plan Extractor (Pure) + PlanLowerer SSOT
Status: ✅ P0/P1/P2 completed (2025-12-22)
Status: ✅ P0/P1/P2/P3/P4 completed (2025-12-22, updated 2025-12-23)
Goal:
- pattern 列挙の裾広がりを止める。
@ -18,6 +18,11 @@ P2 では Pattern7split scanを Plan ラインへ移行し、P1 の CorePl
- ✅ CoreEffectPlan: `dst: Option<ValueId>` + `effects: EffectMask` で副作用(例: `push`)を表現可能にした
- ✅ Lowerer: “split” の知識を持たず、CorePlan のみを処理pattern-agnostic 維持)
## P3/P42025-12-22〜2025-12-23
- P3: legacy fallback を撤去し、generalized CoreLoopPlan を SSOT 化(構造で揺れを消す)
- P4: Plan line を current operational SSOT として文書化(導線固定)
## P1 完了 (2025-12-22)
### アーキテクチャ

View File

@ -1,6 +1,6 @@
# Phase 280: ExitKind+Frag Composition SSOT (A→B→C)
**Status**: In Progress (Started 2025-12-23)
**Status**: ✅ Complete (2025-12-23)
**Phase Number**: 280
**Type**: Design-First (Documentation → Minimal Code)
@ -10,8 +10,8 @@
**Strategy**: Three-phase approach (A→B→C):
- **Phase A**: Document SSOT positioning (docs-only, no code) ✅ **Complete**
- **Phase B**: Solidify composition API contract (minimal test-based verification)
- **Phase C**: Prepare Pattern6/7 for composition API (documentation-only, defer migration to Phase 281)
- **Phase B**: Solidify composition API contract (minimal test-based verification)**Complete**
- **Phase C**: Prepare Pattern6/7 for composition API (documentation-only, defer migration to Phase 281)**Complete**
**Key Insight**: Pattern numbers (1-9+) are **symptom labels** for regression tests, NOT architectural concepts. The architectural SSOT is **Frag composition rules** (`seq`/`if`/`loop`/`cleanup`).

View File

@ -0,0 +1,22 @@
# Phase 281 P0 Completion (2025-12-23)
Target:
- Pattern7SplitScanの hand-rolled Frag を、body 分岐cond_matchについて `compose::if_()` に置換する。
## Change Summary
- Modified: `src/mir/builder/control_flow/plan/normalizer.rs`
- body_bb の `cond_match` 分岐then/else→step join`compose::if_()` に置換
- header_bb の `cond_loop` 分岐、および step_bb の back-edgestep→headerは手組みのまま維持
- `EdgeArgs``empty_args` を明示的に維持implicit 省略をしない)
## Verification
- VM smoke: `tools/smokes/v2/profiles/integration/apps/phase256_p0_split_vm.sh` PASSexit=3
- LLVM smoke: `tools/smokes/v2/profiles/integration/apps/phase256_p0_split_llvm_exe.sh` PASSexit=3
## Notes
- Phase 280 の “行動は最小” 方針に従い、差分は Pattern7 の body 分岐に限定した。
- Pattern6early exitは Phase 281 P1 以降で段階移行する。

View File

@ -0,0 +1,173 @@
# Phase 281: Composition Adoption (Pattern6/7)
Status: **P0-P3 ✅ complete (2025-12-23)**
Goal:
- Phase 280 で SSOT 化した `compose::*`Frag 合成)を、実際の patternPlan lineへ段階的に適用する。
- “手組み Frag” を減らし、CFG 構築を **Frag 合成 SSOT**へ収束させる。
## SSOT References
- Frag/emit SSOT: `docs/development/current/main/design/edgecfg-fragments.md`
- Composition SSOT: `src/mir/builder/control_flow/edgecfg/api/compose.rs`
- Plan line SSOTPattern6/7: `docs/development/current/main/phases/phase-273/README.md`
- Phase 280positioning: `docs/development/current/main/phases/phase-280/README.md`
## P0 完了Pattern7
P0 では、Pattern7SplitScanの “body の cond_match 分岐” を `compose::if_()` に置換した。
- 対象: `src/mir/builder/control_flow/plan/normalizer.rs`
- 方針: 最小差分header/step は手組みのまま、body だけ compose へ)
- 受け入れ: VM/LLVM smoke が同じ exit code で PASS
完了メモ: `docs/development/current/main/phases/phase-281/P0-COMPLETION.md`
## P1: Pattern6正規形 + cleanup()設計
Status: **✅ Complete (2025-12-23)**
Pattern6 は early returnfound_bb→Returnが絡むため、P1 では "どの合成語彙に落とすか" を設計で固定し、**実装は P2 に defer** した。
### Pattern6 CFG構造
**Blocks (6 total)**:
- preheader_bb: ループ入口
- header_bb: PHI (i_current)、ループ条件 (i <= bound)
- body_bb: マッチ条件 (window == needle)
- found_bb: 早期脱出 (Return i_current)
- step_bb: インクリメント (i_next = i + 1)
- after_bb: ループ出口 (not found)
**CFG Diagram**:
```
preheader_bb
↓ Jump
header_bb [phi: i_current ← preheader:i_init, step:i_next]
├─ Branch(cond_loop: i <= bound)
├─→ body_bb (continue)
│ ├─ Branch(cond_match: window == needle)
│ │
│ ├─→ found_bb (match found)
│ │ └─ Return(i_current) ──> EXIT FUNCTION
│ │
│ └─→ step_bb (no match)
│ ├─ i_next = i + 1
│ └─ Jump → header_bb (back-edge)
└─→ after_bb (exhausted)
```
**Current Structure** (手組みFrag、P1維持):
```rust
// normalize_scan_with_init() lines 298-338
let branches = vec![
BranchStub { from: header_bb, cond: cond_loop, then: body_bb, else: after_bb },
BranchStub { from: body_bb, cond: cond_match, then: found_bb, else: step_bb },
];
let wires = vec![
EdgeStub { from: step_bb, kind: Normal, target: Some(header_bb) }, // back-edge
EdgeStub { from: found_bb, kind: Return, target: None, args: ret_found_args },
];
```
### compose::if_()が使えない理由(技術的ブロッカー)
**Pattern7 (P0 Success)**:
```
body_bb → then_bb (Normal) ┐
→ else_bb (Normal) ┘ → step_bb (両方が join に収束)
```
**Symmetric exits** → compose::if_()が完璧にフィット
**Pattern6 (P1 Challenge)**:
```
body_bb → found_bb (Return) → EXIT FUNCTION (関数脱出)
→ step_bb (Normal) → header_bb (ループ継続)
```
**Asymmetric exits** → compose::if_()の契約外Normal合流前提が壊れる
**compose::if_()の主契約**:
- Input: then_frag/else_frag 両方が Normal exits を持つ
- Output: 両方を join_frag.entry に wire
- Pattern6: found_frag が Return exit → join に収束しない
**結論**: 無理に compose::if_() を使うと:
1. body_bb から重複 terminatorBranchStub 2個
2. 1 block = 1 terminator 不変条件違反
3. Return exit の伝播経路が未定義
### 正規形P2以降の目標
**cleanup()を使った合成**:
```rust
// 将来の P2 実装イメージ
let main_loop = /* body→step normal flow */;
let early_exit = /* body→found Return */;
let combined = compose::cleanup(main_loop, early_exit);
```
**cleanup()の役割**:
- 非対称 exitNormal + Returnを統一的に扱う
- early exit を上位 Frag の exits に伝播
- main と cleanup の境界を明示的に管理
### P1決定: cleanup()契約のみ設計実装defer
**Rationale**:
1. compose::if_()は Normal 合流専用early exit 非対応)
2. cleanup()契約が SSOT 化されてないP0では不要だった
3. Pattern6 実装前に契約を固定する必要
**P1 Actions**:
- ✅ cleanup()の契約定義(シグネチャ、入力条件、出力保証)
- ✅ 最小実装Fail-Fast stub
- ✅ unit test 追加(契約確認)
- ❌ Pattern6の実コード置換P2に defer
**P2でやること**:
1. cleanup()本体実装P1契約を満たす
2. normalize_scan_with_init()をcleanup()ベースに置換
3. Pattern6 smokes維持挙動不変
## P2: cleanup(Return) 実装 + Pattern6 移行
Status: **✅ Complete (2025-12-23)**
cleanup(Return)の本体実装を完了し、Pattern6normalize_scan_with_init`compose::cleanup()` ベースに置換した。
**実装内容**:
- `compose::cleanup()` に Return exit 伝播ロジック追加
- Pattern6 の found_bbearly returnを cleanup() で統合
- 手組み BranchStub/EdgeStub を compose API に置換
**検証結果**:
- VM smoke: `phase258_p0_index_of_string_vm.sh` ✅ PASS (exit 0)
- LLVM smoke: `phase258_p0_index_of_string_llvm_exe.sh` ✅ PASS (exit 0)
- 挙動不変Pattern6 の early return が正常動作)
## P3: cleanup(Normal) 追加 + hand-roll ゼロ化
Status: **✅ Complete (2025-12-23)**
cleanup(Normal) を追加し、normalize_scan_with_init() の step back-edge を compose::cleanup() に統合した。これにより Pattern6 の**手組み Frag が完全にゼロ化**された。
**実装内容**:
- `compose::cleanup()` に Normal exit wiring 追加Return と統一的に扱う)
- Pattern6 の step_bb→header_bb back-edge を cleanup() で配線
- EdgeStub 直接生成コードを全削除
**検証結果**:
- VM smoke: `phase258_p0_index_of_string_vm.sh` ✅ PASS (exit 0)
- LLVM smoke: `phase258_p0_index_of_string_llvm_exe.sh` ✅ PASS (exit 0)
- Pattern6/7 両方が compose API 100%(手組みゼロ)
**Phase 281 完全達成**: すべての Plan line パターンが Frag 合成 SSOT に収束 🎉
## Non-Goals
- 新しい env var の追加はしない
- by-name hardcode での一時しのぎはしない
- `emit_frag()` 以外で terminator を生成しない