2025-12-23 05:03:25 +09:00
|
|
|
|
# Phase 282: Router Shrinkage (pattern番号の症状ラベル化)
|
|
|
|
|
|
|
|
|
|
|
|
Status: Planned (design-first)
|
|
|
|
|
|
|
|
|
|
|
|
Goal:
|
|
|
|
|
|
- pattern番号(Pattern1/2/…)を “症状ラベル(テスト名)” に縮退させ、router の責務を「抽出の配線」へ収束させる。
|
|
|
|
|
|
- CFG 構築は `Frag/ExitKind` 合成 SSOT(`compose::*` + `emit_frag()`)へ一本化する。
|
|
|
|
|
|
|
|
|
|
|
|
## SSOT References
|
|
|
|
|
|
|
|
|
|
|
|
- Frag/emit SSOT: `docs/development/current/main/design/edgecfg-fragments.md`
|
|
|
|
|
|
- Composition SSOT: `src/mir/builder/control_flow/edgecfg/api/compose.rs`
|
|
|
|
|
|
- JoinIR overview: `docs/development/current/main/joinir-architecture-overview.md`
|
|
|
|
|
|
- Plan line(Pattern6/7): `docs/development/current/main/phases/phase-273/README.md`
|
|
|
|
|
|
- Composition adoption(Pattern6/7): `docs/development/current/main/phases/phase-281/README.md`
|
|
|
|
|
|
|
|
|
|
|
|
## Problem
|
|
|
|
|
|
|
|
|
|
|
|
pattern番号が router の分岐点として肥大化すると、以下が起きる:
|
|
|
|
|
|
- “認識(extract)” と “CFG構築(lower)” が混ざる
|
|
|
|
|
|
- 分岐の追加が雪だるま式に増える(実質、2つ以上のコンパイラを育てる)
|
|
|
|
|
|
- 収束先(SSOT)が曖昧になり、バグ修正の導線が折れる
|
|
|
|
|
|
|
|
|
|
|
|
## Target Shape (SSOT)
|
|
|
|
|
|
|
|
|
|
|
|
router の役割をここまで縮退させる:
|
|
|
|
|
|
- **やる**: Extractor の列挙、Ok(None)/Err の境界管理、Plan/JoinIR の入口選択
|
|
|
|
|
|
- **やらない**: CFG構築のディテール、terminator 生成、推測 fallback
|
|
|
|
|
|
|
|
|
|
|
|
CFG構築は以下に収束させる:
|
|
|
|
|
|
- Plan line: `Extractor → DomainPlan → Normalizer → CorePlan → Lowerer → emit_frag()`
|
|
|
|
|
|
- JoinIR line: `cf_loop → (必要な抽出) → Frag composition → emit_frag()`
|
|
|
|
|
|
|
|
|
|
|
|
## P0 (docs-only) — SSOT 固定
|
|
|
|
|
|
|
|
|
|
|
|
- router の責務/禁止事項を明文化(by-name hardcode禁止、silent fallback禁止)
|
|
|
|
|
|
- "pattern番号の意味" を SSOT として定義(テスト名/症状ラベル)
|
|
|
|
|
|
- 入口リンクを `10-Now.md` に固定
|
|
|
|
|
|
|
|
|
|
|
|
### Router Responsibilities SSOT
|
|
|
|
|
|
|
|
|
|
|
|
**Router がやること**:
|
|
|
|
|
|
1. Extraction 戦略の列挙(Plan-based, JoinIR table-based)
|
|
|
|
|
|
2. Extractor を優先順で呼び出し(Plan line → JoinIR table)
|
|
|
|
|
|
3. Ok(None)/Err の境界管理(Fail-Fast原則)
|
|
|
|
|
|
4. Entrypoint の選択(Plan line vs JoinIR line)
|
|
|
|
|
|
5. Routing 決定のログ出力(debug mode のみ、既存 trace 機構)
|
|
|
|
|
|
|
|
|
|
|
|
**Router がやらないこと**(禁止事項):
|
|
|
|
|
|
1. CFG 構築(block 割り当て、PHI 挿入、terminator 生成)
|
|
|
|
|
|
2. Pattern 固有の lowering ロジック(Normalizer/Lowerer に委譲)
|
|
|
|
|
|
3. Silent fallback(エラーは明示的に)
|
|
|
|
|
|
4. By-name hardcode(関数名マッチング禁止、debug 以外)
|
|
|
|
|
|
5. Mock path fallback(test 専用パターンの本番使用禁止)
|
|
|
|
|
|
|
|
|
|
|
|
**Pattern 番号 = 症状ラベル**(Phase 280 SSOT positioning):
|
|
|
|
|
|
- ✅ 正しい用途: テスト名(`loop_if_phi.hako` → Pattern3_WithIfPhi)、debug ログ
|
|
|
|
|
|
- ❌ 禁止: CFG 分岐(`if pattern == 6 then ...`)、アーキテクチャ SSOT(Frag composition が SSOT)
|
|
|
|
|
|
|
|
|
|
|
|
**Detection 戦略**(簡潔版、詳細は P2+ で補完):
|
2025-12-23 08:13:47 +09:00
|
|
|
|
- **ExtractionBased**(Pattern6/7/8/9): extract() 成功 → match(SSOT 単一)
|
|
|
|
|
|
- 注: Pattern8/9 は JoinIR table 経由でも、can_lower 内部で extract を使って判定している(pattern_kind 依存ではない)
|
|
|
|
|
|
- **StructureBased**(主に Pattern1-5): ctx.pattern_kind などの事前分類を使う(legacy、SSOT が二重になりやすい)
|
2025-12-23 05:03:25 +09:00
|
|
|
|
|
|
|
|
|
|
**SSOT 参照**:
|
|
|
|
|
|
- Frag composition: `src/mir/builder/control_flow/edgecfg/api/compose.rs`
|
|
|
|
|
|
- Plan line: `src/mir/builder/control_flow/plan/normalizer.rs`
|
|
|
|
|
|
- Terminator 生成: `emit_frag()` (Phase 267)
|
|
|
|
|
|
|
|
|
|
|
|
### Ok(None)/Err Boundary Rules
|
|
|
|
|
|
|
|
|
|
|
|
**Fail-Fast 原則**:
|
|
|
|
|
|
- `Ok(None)`: Extraction がパターンに一致しなかった(次を試す)
|
|
|
|
|
|
- `Err(String)`: Extraction が一致したが検証失敗(即座に fail)
|
|
|
|
|
|
- **禁止**: Close-but-unsupported → Ok(None)(Err で返すべき)
|
|
|
|
|
|
|
|
|
|
|
|
**例**:
|
|
|
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
|
|
// ✅ 正しい: 一致しない
|
|
|
|
|
|
extract_scan_with_init_plan() → Ok(None) // 次のパターンを試す
|
|
|
|
|
|
|
|
|
|
|
|
// ✅ 正しい: 一致したが非サポート
|
|
|
|
|
|
extract_scan_with_init_plan() → Err("P1 scope: reverse scan not supported")
|
|
|
|
|
|
|
|
|
|
|
|
// ❌ 禁止: Silent fallback
|
|
|
|
|
|
extract_scan_with_init_plan() → Ok(None) for unsupported cases
|
|
|
|
|
|
// (非サポートケースを Ok(None) で返してはいけない)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**境界の位置**(router.rs 実装):
|
|
|
|
|
|
- Plan line(lines 310-337, 341-368): extract → match → Normalize → Verify → Lower
|
|
|
|
|
|
- JoinIR table(lines 376-382): can_lower → lower
|
|
|
|
|
|
- No match(lines 384-395): Ok(None) を caller に返す(Err ではない)
|
|
|
|
|
|
|
|
|
|
|
|
### Entrypoint Table
|
|
|
|
|
|
|
|
|
|
|
|
| Entrypoint | Entry Condition | Patterns | SSOT Downstream |
|
|
|
|
|
|
|------------|----------------|----------|-----------------|
|
|
|
|
|
|
| **Plan line** | extract_*_plan() が Ok(Some) | Pattern6/7 | Normalizer → CorePlan → Lowerer → emit_frag |
|
|
|
|
|
|
| **JoinIR table** | LOOP_PATTERNS 反復 | Pattern1-5,8-9 | cf_loop 抽出 → Frag composition → emit_frag |
|
|
|
|
|
|
| **No match** | すべての extract が Ok(None) | (none) | Err を caller に返す |
|
|
|
|
|
|
|
|
|
|
|
|
**Plan line の責務**(Phase 273 SSOT):
|
|
|
|
|
|
1. **Extraction**: extract_*_plan()(pure、builder 不要)
|
|
|
|
|
|
2. **Normalization**: PlanNormalizer(pattern 知識の展開)
|
|
|
|
|
|
3. **Verification**: PlanVerifier(fail-fast 検証)
|
|
|
|
|
|
4. **Lowering**: PlanLowerer(block/value 割り当て + Frag composition)
|
|
|
|
|
|
5. **Emission**: emit_frag()(terminator SSOT)
|
|
|
|
|
|
|
|
|
|
|
|
**JoinIR table の責務**(Phase 194+ table-driven):
|
2025-12-23 08:13:47 +09:00
|
|
|
|
1. **Detection**: can_lower()(pattern により structure-based / extraction-based が混在)
|
2025-12-23 05:03:25 +09:00
|
|
|
|
2. **Extraction**: cf_loop 抽出
|
|
|
|
|
|
3. **収束先**: Frag composition → emit_frag(内部パイプライン詳細は最小化)
|
|
|
|
|
|
|
|
|
|
|
|
**収束先の統一**(Phase 282 Goal):
|
|
|
|
|
|
- すべての entrypoint が最終的に `emit_frag()` に収束(terminator 生成の SSOT)
|
|
|
|
|
|
- CFG 構築の詳細は router が持たない(抽出の配線のみ)
|
|
|
|
|
|
|
|
|
|
|
|
## P1 (code, minimal) — 配線の可視化
|
|
|
|
|
|
|
|
|
|
|
|
- router に “経路ログ” を追加(既定OFF、debugのみに限定)
|
|
|
|
|
|
- pattern番号ではなく “entrypoint(Plan/JoinIR)” をログの主語にする
|
|
|
|
|
|
|
|
|
|
|
|
## Acceptance (Phase 282)
|
|
|
|
|
|
|
|
|
|
|
|
- router の責務が docs で SSOT 化されている
|
|
|
|
|
|
- router の変更が「extractor配線」のみになっている(CFG構築の詳細を持たない)
|
|
|
|
|
|
- 既存の VM/LLVM smokes に退行がない
|