feat(mir/llvm): Phase 273 P0-P1 DomainPlan→CorePlan + LLVM arg fix
Phase 273 P0-P1: Two-layer plan architecture - DomainPlan: Pattern-specific knowledge (ScanWithInit) - CorePlan: Fixed vocabulary (Seq, Loop, If, Effect, Exit) - ValueId references only (String expressions forbidden) - Pipeline: Extractor→Normalizer→Verifier→Lowerer New plan/ module: - mod.rs: Type definitions, SSOT spec - normalizer.rs: DomainPlan→CorePlan + ID allocation - verifier.rs: V1-V6 invariant checks (fail-fast) - lowerer.rs: CorePlan→MIR (pattern-agnostic) LLVM fix (ChatGPT): - function_lower.py: Fix argument reference bug - Phase 258 index_of_string now PASS on LLVM backend 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
97
docs/development/current/main/phases/phase-273/P0-CLAUDE.md
Normal file
97
docs/development/current/main/phases/phase-273/P0-CLAUDE.md
Normal file
@ -0,0 +1,97 @@
|
||||
# Phase 273 P0: Plan Extractor(pure)導入の最小収束(Claude Code 指示書)
|
||||
|
||||
Status: instructions / design-first
|
||||
|
||||
目的:
|
||||
- pattern を “分岐ロジック” ではなく “Plan抽出プラグイン” に降格する。
|
||||
- block/value/phi の生成責務を **PlanLowerer に集約**し、裾広がりを止める。
|
||||
|
||||
制約:
|
||||
- Extractor は **builder を触らない**(`next_block_id/next_value_id/insert_phi/...` 禁止)
|
||||
- 新しい env var 禁止
|
||||
- by-name hardcode 禁止(Box名/Pattern名の文字列分岐を増やさない)
|
||||
- terminator SSOT は維持(`Frag → emit_frag()`)
|
||||
|
||||
参照:
|
||||
- SSOT設計: `docs/development/current/main/design/edgecfg-fragments.md`
|
||||
- 参照実装(既存): Phase 272/269 の Frag 経路
|
||||
- `docs/development/current/main/phases/phase-272/README.md`
|
||||
- `docs/development/current/main/phases/phase-269/README.md`
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Plan の固定語彙を作る(増殖しない型)
|
||||
|
||||
新規モジュール(例):
|
||||
- `src/mir/builder/control_flow/plan/`(または `src/mir/control_plan/`)
|
||||
|
||||
最低限の語彙(案):
|
||||
- `Plan::Seq(Vec<Plan>)`
|
||||
- `Plan::Loop { params, body }`
|
||||
- `Plan::If { cond, then_, else_ }`
|
||||
- `Plan::Effect { ... }`(副作用の順序だけ表す)
|
||||
- `Plan::Exit { kind, values }`
|
||||
|
||||
重要:
|
||||
- Plan は AST/expr を “参照” するだけ(必要なら node id / span を持つ)
|
||||
- Plan は “CFGを作らない”
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Extractor を pure にする(pattern の責務縮退)
|
||||
|
||||
対象:
|
||||
- `src/mir/builder/control_flow/joinir/patterns/*`
|
||||
|
||||
方針:
|
||||
- 既存の `extract_*_parts(...)` のような抽出関数を “Plan を返す” 形に寄せる
|
||||
- `Ok(None)` / `Ok(Some(plan))` / `Err(...)` を明確に使い分ける
|
||||
|
||||
Fail-fast:
|
||||
- “一致した” のに必要条件が満たせない場合は `Err`(close-but-unsupported を黙って通さない)
|
||||
|
||||
---
|
||||
|
||||
## Step 3: PlanLowerer を作る(唯一の builder 触り役)
|
||||
|
||||
新規モジュール(例):
|
||||
- `src/mir/builder/control_flow/plan/lowerer.rs`
|
||||
|
||||
責務:
|
||||
- block/value/phi を作るのはここだけ
|
||||
- Frag を組み立てて `emit_frag()` に渡す
|
||||
- 既存の emission(Phase 272 の `loop_scan_with_init` / `loop_split_scan` など)を呼ぶのは Lowerer 側に寄せる
|
||||
|
||||
---
|
||||
|
||||
## Step 4: まず1つのパターンで PoC(最小差分)
|
||||
|
||||
推奨:
|
||||
- Pattern6 または Pattern8 を 1つ選び、以下の順で移行:
|
||||
1) extractor は plan を返すだけにする
|
||||
2) lowerer が既存 emission を呼ぶ
|
||||
3) router は “plan を得たら lowerer へ” にする
|
||||
|
||||
Acceptance:
|
||||
- 既存の fixture/smoke が変わらず PASS(既定挙動不変)
|
||||
- Extractor が builder を触っていないこと(grep で確認)
|
||||
|
||||
---
|
||||
|
||||
## Step 5: docs(SSOT)更新
|
||||
|
||||
更新対象:
|
||||
- `docs/development/current/main/phases/phase-273/README.md`
|
||||
|
||||
最低限:
|
||||
- “Extractorはpure / Lowererだけが作る” を SSOT として明文化
|
||||
- Plan語彙が固定であること(増殖しない理由)を短く書く
|
||||
|
||||
---
|
||||
|
||||
## 完了条件(P0)
|
||||
|
||||
- Plan の語彙が導入され、Extractor が pure になっている(最低1パターンでPoC)
|
||||
- Lowerer が block/value/phi 生成の唯一の場所になっている
|
||||
- terminator SSOT(emit_frag)が維持されている
|
||||
- 既存スモークに退行がない
|
||||
@ -0,0 +1,34 @@
|
||||
# Phase 273 P0: Plan Extractor (pure) + PlanLowerer SSOT — completion
|
||||
|
||||
Status: ✅ completed (2025-12-22)
|
||||
|
||||
Goal:
|
||||
- Pattern を “Plan抽出プラグイン” に降格し、CFG/PHI/block/value 生成の責務を PlanLowerer に集約して、裾広がりを止める。
|
||||
|
||||
What changed (P0):
|
||||
- Plan 語彙を最小導入(P0 は PoC として pattern-specific を 1 個だけ許容)
|
||||
- Extractor は pure(builder を触らない)
|
||||
- Lowerer が block/value/phi を作る唯一の場所
|
||||
- terminator SSOT(`Frag → emit_frag()`)は維持
|
||||
|
||||
PoC target:
|
||||
- Pattern6(scan with init)
|
||||
|
||||
Behavior / limits:
|
||||
- `dynamic_needle=true` は当時 `Ok(None)` で fallthrough(P1+)
|
||||
- `step_lit != 1`(reverse scan)も `Ok(None)` で fallthrough(P1+)
|
||||
|
||||
Regression:
|
||||
- `tools/smokes/v2/profiles/integration/apps/phase254_p0_index_of_vm.sh` PASS
|
||||
|
||||
Files:
|
||||
- `src/mir/builder/control_flow/plan/mod.rs`
|
||||
- `src/mir/builder/control_flow/plan/lowerer.rs`
|
||||
- `src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs`
|
||||
- `src/mir/builder/control_flow/joinir/patterns/router.rs`
|
||||
|
||||
Next (P1+):
|
||||
- Plan語彙を固定(`Seq/Loop/If/Effect/Exit`)へ畳み、pattern-specific Plan の増殖を止める。
|
||||
|
||||
Note (follow-up):
|
||||
- その後の修正で `dynamic_needle`(Phase 258 の string index_of 系)も PlanLowerer 側で handling され、JoinIR freeze 下でも fallthrough しない経路に寄せている(詳細は Phase 273 README を参照)。
|
||||
117
docs/development/current/main/phases/phase-273/P1-CLAUDE.md
Normal file
117
docs/development/current/main/phases/phase-273/P1-CLAUDE.md
Normal file
@ -0,0 +1,117 @@
|
||||
# Phase 273 P1: Plan語彙固定 + PlanVerifier(fail-fast)(Claude Code 指示書)
|
||||
|
||||
Status: instructions / design-first
|
||||
|
||||
目的:
|
||||
- P0 の pattern-specific Plan(`Plan::ScanWithInit`)を、増殖しない固定語彙へ畳む。
|
||||
- Extractor は pure を維持しつつ、Plan の整合性は Verifier で fail-fast に固定する。
|
||||
|
||||
スコープ:
|
||||
- Plan 型の再設計(固定語彙への移行)
|
||||
- PlanNormalizer(DomainPlan → CorePlan)の追加(SSOT)
|
||||
- PlanVerifier の追加(境界で fail-fast)
|
||||
- Pattern6 を “固定語彙 CorePlan” で表現し直す(PoC 維持)
|
||||
|
||||
Non-goals:
|
||||
- 全 pattern の移行(P2+)
|
||||
- 新しい言語機能
|
||||
- env var 追加
|
||||
|
||||
参照:
|
||||
- Phase 273 README: `docs/development/current/main/phases/phase-273/README.md`
|
||||
- Phase 273 P0 completion: `docs/development/current/main/phases/phase-273/P0-COMPLETION.md`
|
||||
- Frag SSOT: `docs/development/current/main/design/edgecfg-fragments.md`
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Plan の固定語彙を導入する
|
||||
|
||||
方針:
|
||||
- `Plan` の variant を “構造語彙” に固定する(増殖しない)。
|
||||
- pattern-specific variant は廃止方向(P1では Pattern6 から移行)。
|
||||
|
||||
最低限(P1):
|
||||
- `Plan::Seq(Vec<Plan>)`
|
||||
- `Plan::Loop(LoopPlan)`
|
||||
- `Plan::If(IfPlan)`
|
||||
- `Plan::Effect(EffectPlan)`(副作用の順序だけ)
|
||||
- `Plan::Exit(ExitPlan)`(Return/Break/Continue…)
|
||||
|
||||
注意:
|
||||
- P1では “式の意味” を Plan に入れすぎない(expr は参照/ID/ASTNode を持つだけにする)。
|
||||
- **式を `String` にしない**(Lowerer 側に「文字列式の解釈器」を生やさない)。
|
||||
|
||||
---
|
||||
|
||||
## Step 1.5: DomainPlan → CorePlan の 2層 + PlanNormalizer(SSOT)
|
||||
|
||||
狙い:
|
||||
- “固定語彙にしたいが、scan固有データも欲しい” の葛藤を構造で解消する。
|
||||
- Lowerer を **CorePlan-only** にして、pattern固有知識の混入を防ぐ。
|
||||
|
||||
方針:
|
||||
- `DomainPlan`: pattern 固有の最小表現(短命・増殖は許容するが「削る側」)
|
||||
- `CorePlan`: 固定語彙のみ(増殖禁止)
|
||||
- `PlanNormalizer` が **唯一** `DomainPlan → CorePlan` を行う(SSOT)
|
||||
|
||||
重要:
|
||||
- `EffectPlan::ScanInit` のような **scan専用 variant** は禁止
|
||||
- 「あとで MethodCall に統一する」前提の例外は作らない(裾広がりの入口になる)
|
||||
|
||||
---
|
||||
|
||||
## Step 2: PlanVerifier を追加する(fail-fast)
|
||||
|
||||
新規モジュール案:
|
||||
- `src/mir/builder/control_flow/plan/verifier.rs`
|
||||
|
||||
役割:
|
||||
- Extractor が返した Plan が “Lowerer が扱える契約” を満たすかを検証する
|
||||
- close-but-unsupported を `Err` にして誤コンパイル余地を潰す
|
||||
|
||||
P1で入れる最小の不変条件(例):
|
||||
- Loop の header params / carriers が揃っている
|
||||
- Exit が Loop 外へ飛ぶ場合の kind が妥当
|
||||
- Effect が順序上の制約を破っていない(最低限:Effect がブロック境界で落ちない)
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Pattern6 を固定語彙 Plan で表現し直す
|
||||
|
||||
方針:
|
||||
- Extractor は `DomainPlan` を返す(pure)。
|
||||
- `PlanNormalizer` が `DomainPlan → CorePlan` を行い、固定語彙 `CorePlan::{Seq,Loop,If,Exit,Effect}` の組み合わせに落とす。
|
||||
- Lowerer は `CorePlan` のみを処理する(pattern固有知識を持たない)。
|
||||
|
||||
禁止(P1):
|
||||
- scan固有情報を `EffectPlan` の payload/variant として持つこと(固定語彙の侵食)
|
||||
- 式を `String` として Plan に埋め込むこと(第二の処理系が生える)
|
||||
|
||||
---
|
||||
|
||||
## Step 4: Router の責務を整理する
|
||||
|
||||
方針:
|
||||
- router は `extract_*` を呼び、`PlanVerifier` を通し、`PlanLowerer` に渡すだけ。
|
||||
- router が builder を触らない(制御の入口は薄く保つ)。
|
||||
|
||||
推奨の順序(P1):
|
||||
1. `extract_*`(pure, DomainPlan)→ `Ok(None)` / `Ok(Some(domain))` / `Err`
|
||||
2. `PlanNormalizer::normalize(domain) -> CorePlan`(SSOT)
|
||||
3. `PlanVerifier::verify(&core)`(fail-fast)
|
||||
4. `PlanLowerer::lower(core)`(CorePlan-only)
|
||||
|
||||
---
|
||||
|
||||
## Step 5: 回帰確認(P0 と同等)
|
||||
|
||||
最低限:
|
||||
- `tools/smokes/v2/profiles/integration/apps/phase254_p0_index_of_vm.sh` PASS
|
||||
|
||||
---
|
||||
|
||||
## 完了条件(P1)
|
||||
|
||||
- Plan enum の variant が固定語彙に収束している(増殖しない)
|
||||
- PlanVerifier が境界で fail-fast を提供している
|
||||
- Pattern6 が固定語彙 Plan で表現され、P0のPoCが維持されている
|
||||
119
docs/development/current/main/phases/phase-273/README.md
Normal file
119
docs/development/current/main/phases/phase-273/README.md
Normal file
@ -0,0 +1,119 @@
|
||||
# Phase 273: Plan Extractor (Pure) + PlanLowerer SSOT
|
||||
|
||||
Status: ✅ P0/P1 completed (2025-12-22)
|
||||
|
||||
Goal:
|
||||
- pattern 列挙の裾広がりを止める。
|
||||
- pattern は "検出して Plan を返すだけ" に降格し、CFG/PHI/block/value の生成責務を 1 箇所に閉じ込める。
|
||||
- P1: DomainPlan → CorePlan の 2層構造で "収束" を強める
|
||||
|
||||
---
|
||||
|
||||
## P1 完了 (2025-12-22)
|
||||
|
||||
### アーキテクチャ
|
||||
|
||||
```
|
||||
DomainPlan (Pattern固有)
|
||||
↓ PlanNormalizer (SSOT)
|
||||
CorePlan (固定語彙 - 構造ノードのみ)
|
||||
↓ PlanVerifier (fail-fast)
|
||||
↓ PlanLowerer
|
||||
MIR (block/value/phi)
|
||||
```
|
||||
|
||||
### SSOT Entry Point
|
||||
|
||||
**Files**:
|
||||
- `src/mir/builder/control_flow/plan/mod.rs` - DomainPlan/CorePlan 型定義
|
||||
- `src/mir/builder/control_flow/plan/normalizer.rs` - PlanNormalizer(DomainPlan → CorePlan)
|
||||
- `src/mir/builder/control_flow/plan/verifier.rs` - PlanVerifier(fail-fast 検証)
|
||||
- `src/mir/builder/control_flow/plan/lowerer.rs` - PlanLowerer(CorePlan → MIR)
|
||||
|
||||
### 原則
|
||||
|
||||
- Extractor は **pure**(builder 触り厳禁、DomainPlan を返すのみ)
|
||||
- Normalizer は **SSOT**(pattern 固有知識はここに集約)
|
||||
- CorePlan の式は **ValueId 参照のみ**(String 禁止 → 第2の言語処理系を作らない)
|
||||
- Lowerer は **pattern-agnostic**(CorePlan のみを処理)
|
||||
- terminator SSOT: Frag → emit_frag()
|
||||
|
||||
---
|
||||
|
||||
## CorePlan 固定語彙
|
||||
|
||||
```rust
|
||||
pub enum CorePlan {
|
||||
Seq(Vec<CorePlan>),
|
||||
Loop(CoreLoopPlan),
|
||||
If(CoreIfPlan),
|
||||
Effect(CoreEffectPlan),
|
||||
Exit(CoreExitPlan),
|
||||
}
|
||||
|
||||
pub enum CoreEffectPlan {
|
||||
MethodCall { dst, object, method, args },
|
||||
BinOp { dst, lhs, op, rhs },
|
||||
Compare { dst, lhs, op, rhs },
|
||||
Const { dst, value },
|
||||
}
|
||||
```
|
||||
|
||||
**増殖禁止ルール**:
|
||||
- ノード種別(variant)の追加は禁止
|
||||
- `EffectPlan::ScanInit` のような scan専用 variant は禁止
|
||||
- データ(フィールド、パラメータ)の追加は許容
|
||||
|
||||
---
|
||||
|
||||
## P1 Implementation Summary
|
||||
|
||||
**Files changed** (7 total):
|
||||
- Modified: `src/mir/builder/control_flow/plan/mod.rs` - DomainPlan/CorePlan 型定義 (~220 lines)
|
||||
- New: `src/mir/builder/control_flow/plan/normalizer.rs` - PlanNormalizer (~290 lines)
|
||||
- New: `src/mir/builder/control_flow/plan/verifier.rs` - PlanVerifier (~180 lines)
|
||||
- Modified: `src/mir/builder/control_flow/plan/lowerer.rs` - CorePlan 対応 (~250 lines)
|
||||
- Modified: `src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs` - DomainPlan 返却
|
||||
- Modified: `src/mir/builder/control_flow/joinir/patterns/router.rs` - Normalizer + Verifier 経由
|
||||
|
||||
**Regression test**:
|
||||
- ✅ phase254_p0_index_of_vm.sh (fixed needle, forward scan)
|
||||
- ✅ phase258_p0_index_of_string_vm.sh (dynamic needle)
|
||||
|
||||
---
|
||||
|
||||
## LLVM harness の落とし穴(Phase 258 で露出)
|
||||
|
||||
Phase 258 の `index_of_string`(dynamic needle)で、VM では正しいのに LLVM で `Result: 0` になるケースが露出した。
|
||||
原因は Phase 273 P1 の本線(DomainPlan→CorePlan→emit_frag)ではなく、LLVM harness / AOT ランタイム側の “契約” だった。
|
||||
|
||||
### 1) `params` を使わないと引数が silently に潰れる
|
||||
|
||||
MIR JSON の `params`(ValueId の引数順)を使わず、heuristic で「未定義の use」を拾うと、
|
||||
`box` フィールド等を見落とした場合に **v1 が arg0 に誤マップ**され、needle が haystack と同一扱いになる。
|
||||
|
||||
- Fix: `src/llvm_py/builders/function_lower.py` で `func_data["params"]` を SSOT として優先する
|
||||
|
||||
### 2) “raw integer vs handle” 衝突で `Result` が 0 になる
|
||||
|
||||
AOT ランタイム(nyrt)は `ny_main()` の返り値が **raw i64** か **handle(i64)** かを区別できない。
|
||||
正しい raw 返り値(例: `6`)が、たまたま生成済みの handle id と衝突すると、IntegerBox ではないため `Result: 0` になりうる。
|
||||
|
||||
- Fix: `crates/nyash_kernel/src/lib.rs` の exit_code 抽出で、handle が IntegerBox 以外なら raw i64 として扱う
|
||||
|
||||
## References
|
||||
|
||||
- JoinIR SSOT overview: `docs/development/current/main/joinir-architecture-overview.md`
|
||||
- Frag SSOT: `docs/development/current/main/design/edgecfg-fragments.md`
|
||||
- Phase 272(Pattern6/7, Frag適用): `docs/development/current/main/phases/phase-272/README.md`
|
||||
|
||||
## Instructions
|
||||
|
||||
- P0 Claude Code: `docs/development/current/main/phases/phase-273/P0-CLAUDE.md`
|
||||
- P1 Claude Code: `docs/development/current/main/phases/phase-273/P1-CLAUDE.md`
|
||||
|
||||
## Future Work (P2+)
|
||||
|
||||
1. **Pattern7/8/9 DomainPlan 追加**: Split, BoolPredicate 等を DomainPlan に追加
|
||||
2. **Normalizer 拡張**: 各 DomainPlan → CorePlan 変換
|
||||
3. **全 Pattern の Plan 化**: Pattern1-5 を段階的に Plan 化
|
||||
@ -0,0 +1,34 @@
|
||||
# Phase 278 P0: Deprecated PHI env vars removal — completion
|
||||
|
||||
Status: ✅ completed (2025-12-22)
|
||||
|
||||
Goal:
|
||||
- Remove legacy PHI debug environment variables (previously consolidated in Phase 277 P2).
|
||||
- Enforce a single SSOT set of PHI debug knobs (fail-fast on deprecated inputs).
|
||||
|
||||
SSOT (kept):
|
||||
- `NYASH_LLVM_DEBUG_PHI=1`
|
||||
- `NYASH_LLVM_DEBUG_PHI_TRACE=1`
|
||||
- `NYASH_LLVM_PHI_STRICT=1`
|
||||
|
||||
Removed inputs (deprecated variables):
|
||||
- `NYASH_LLVM_PHI_DEBUG`
|
||||
- `NYASH_PHI_TYPE_DEBUG`
|
||||
- `NYASH_PHI_ORDERING_DEBUG`
|
||||
- `NYASH_LLVM_TRACE_PHI`
|
||||
- `NYASH_LLVM_VMAP_TRACE`
|
||||
|
||||
Behavior:
|
||||
- If any removed variable is set, the harness errors with a replacement hint and exits non-zero.
|
||||
- No new environment variables introduced.
|
||||
|
||||
Docs:
|
||||
- `docs/reference/environment-variables.md` updated with:
|
||||
- removed variable list
|
||||
- migration table (old → new)
|
||||
- example error message
|
||||
|
||||
Tests:
|
||||
- Added a dedicated smoke verifying:
|
||||
- deprecated vars fail
|
||||
- SSOT vars still work
|
||||
@ -1,6 +1,6 @@
|
||||
# Phase 278 (planned): Remove deprecated PHI debug env vars
|
||||
# Phase 278 P0: Remove deprecated PHI debug env vars
|
||||
|
||||
Status: planned / cleanup
|
||||
Status: ✅ completed (2025-12-22)
|
||||
|
||||
Goal: remove legacy PHI debug environment variables that were consolidated in Phase 277 P2, so the ecosystem converges to a single, memorable set.
|
||||
|
||||
@ -16,3 +16,5 @@ Target SSOT (post-Phase 278):
|
||||
Implementation guide:
|
||||
- `docs/development/current/main/phases/phase-278/P0-INSTRUCTIONS.md`
|
||||
|
||||
Completion:
|
||||
- `docs/development/current/main/phases/phase-278/P0-COMPLETION.md`
|
||||
|
||||
113
docs/development/current/main/phases/phase-279/P0-CLAUDE.md
Normal file
113
docs/development/current/main/phases/phase-279/P0-CLAUDE.md
Normal file
@ -0,0 +1,113 @@
|
||||
# Phase 279 P0: Type propagation pipeline SSOT unification(Claude Code 指示書)
|
||||
|
||||
Status: instructions / implementation
|
||||
|
||||
目的(根治):
|
||||
- “2本のコンパイラ” を潰す。
|
||||
- 例: ルートAは BinOp 型伝播→PHI 型解決、ルートBは PHI 型解決→BinOp 型伝播、のような **順序ドリフト**で同一fixtureが壊れる。
|
||||
- 型伝播(Copy/BinOp/PHI…)の入口と順序を **1本のSSOT**に固定し、どのルートでも同じ結果になることを保証する。
|
||||
|
||||
スコープ(P0):
|
||||
- Rust側の “型伝播パイプライン” を SSOT 1箇所に集約し、主要ルートから必ず呼ぶ
|
||||
- fail-fast ガードで “PHI-before-BinOp” を禁止する
|
||||
- 代表fixtureで “ルート差が消えた” を確認する
|
||||
|
||||
Non-goals:
|
||||
- coercion / language semantics の変更
|
||||
- 新しい env var 追加
|
||||
- LLVM harness 側の場当たり的推論追加(best-effort禁止)
|
||||
|
||||
参照:
|
||||
- Phase 279 SSOT: `docs/development/current/main/phases/phase-279/P0-INSTRUCTIONS.md`
|
||||
- 現状の2ルート(要確認):
|
||||
- builder lifecycle: `src/mir/builder/lifecycle.rs`
|
||||
- JoinIR bridge: `src/mir/join_ir_vm_bridge/joinir_function_converter.rs`
|
||||
- PHI推論箱: `src/mir/phi_core/phi_type_resolver.rs`
|
||||
|
||||
---
|
||||
|
||||
## Step 0: “入口SSOT” の置き場所を決める
|
||||
|
||||
新規モジュールを作って、全ルートがそこを呼ぶ形にする。
|
||||
|
||||
推奨パス(例):
|
||||
- `src/mir/type_propagation/pipeline.rs`
|
||||
|
||||
中身(最小):
|
||||
- `pub(crate) fn run_type_propagation_pipeline(func: &mut MirFunction, value_types: &mut ValueTypes, mode: ...) -> Result<(), String>`
|
||||
- Copy type propagation
|
||||
- BinOp re-propagation
|
||||
- PHI type inference(PhiTypeResolver)
|
||||
- (必要最小の後続だけ)
|
||||
|
||||
注意:
|
||||
- “既にあるロジックを移動して呼び出し一本化” が目的。新しい推論ルールを増やさない。
|
||||
|
||||
---
|
||||
|
||||
## Step 1: lifecycle.rs から SSOT pipeline を呼ぶ
|
||||
|
||||
対象:
|
||||
- `src/mir/builder/lifecycle.rs`
|
||||
|
||||
要件:
|
||||
- lifecycle 内の “Copy/BinOp/PHI 推論の順序” を削って、SSOT pipeline 呼び出しに置き換える。
|
||||
- PHI推論は **必ず BinOp re-propagation の後**(順序固定)。
|
||||
|
||||
受け入れ:
|
||||
- lifecycle 側に “局所の順序実装” が残っていない。
|
||||
|
||||
---
|
||||
|
||||
## Step 2: joinir_function_converter.rs から SSOT pipeline を呼ぶ
|
||||
|
||||
対象:
|
||||
- `src/mir/join_ir_vm_bridge/joinir_function_converter.rs`
|
||||
|
||||
要件:
|
||||
- joinir_function_converter 内の “Copy/BinOp/PHI 推論の順序” を削って、同じ SSOT pipeline 呼び出しに置き換える。
|
||||
|
||||
受け入れ:
|
||||
- JoinIR bridge ルートでも “PHI-before-BinOp” が起きない構造になる。
|
||||
|
||||
---
|
||||
|
||||
## Step 3: fail-fast ガード(順序ドリフト禁止)
|
||||
|
||||
方針:
|
||||
- “PHI type inference が走る時点で BinOp re-propagation が未実行” を Err にするガードを SSOT pipeline 内に入れる。
|
||||
|
||||
目的:
|
||||
- 将来の改修で順序が崩れたときに、静かに壊れず “原因で止まる” ようにする。
|
||||
|
||||
---
|
||||
|
||||
## Step 4: 代表fixtureでルート差が消えたことを確認
|
||||
|
||||
最低条件:
|
||||
- “Copy chain + Int+Float promotion + PHI” を含む fixture を使う(Phase 275 系など)。
|
||||
- その fixture を “両ルート” で通して、`value_types` / PHI `dst_type` が一致することを確認する。
|
||||
|
||||
注意:
|
||||
- 新しいCIは増やさない。ローカルの代表スモークで十分。
|
||||
|
||||
---
|
||||
|
||||
## Step 5: docs 更新(SSOTの参照先を固定)
|
||||
|
||||
更新対象:
|
||||
- `docs/development/current/main/phases/phase-279/README.md`
|
||||
|
||||
必須:
|
||||
- “このファイルが pipeline unification の入口SSOT” と明記
|
||||
- 主要呼び出し元(lifecycle / joinir_function_converter)を列挙
|
||||
- “LLVM harness は consumer(best-effort禁止)” を明記
|
||||
|
||||
---
|
||||
|
||||
## 完了条件(P0)
|
||||
|
||||
- SSOT pipeline の入口が 1 箇所
|
||||
- lifecycle / JoinIR bridge がその入口を必ず呼ぶ
|
||||
- “PHI-before-BinOp” を fail-fast で禁止できる
|
||||
- 代表fixtureで “ルート差による二重バグ” が再現しない
|
||||
Reference in New Issue
Block a user