diff --git a/docs/development/current/main/10-Now.md b/docs/development/current/main/10-Now.md index 25b2185a..6e0b1a3e 100644 --- a/docs/development/current/main/10-Now.md +++ b/docs/development/current/main/10-Now.md @@ -3,8 +3,8 @@ ## Current Focus (next) - Phase 273(design-first): `docs/development/current/main/phases/phase-273/README.md` - - P1: DomainPlan→CorePlan(固定語彙)+ PlanNormalizer(SSOT)+ PlanVerifier(fail-fast)で “増殖” を止める - - CorePlan は `Seq/Loop/If/Effect/Exit` のみ(scan専用 Effect/variant 禁止、式を String にしない) + - P3 proposal: generalized CoreLoopPlan を SSOT 化して legacy fallback を撤去(収束の完成) + - 指示書: `docs/development/current/main/phases/phase-273/P3-CLAUDE.md` ## Recently Completed (2025-12-22) @@ -15,6 +15,7 @@ - Phase 278 P0(deprecated PHI env vars removal): `docs/development/current/main/phases/phase-278/README.md` - Phase 279 P0(type propagation pipeline SSOT unification): `docs/development/current/main/phases/phase-279/README.md` - Phase 273 P0(Plan Extractor PoC): `docs/development/current/main/phases/phase-273/README.md` +- Phase 273 P1/P2(Domain→Core→Lowerer + Pattern7移行): `docs/development/current/main/phases/phase-273/README.md` --- diff --git a/docs/development/current/main/phases/phase-273/P2-COMPLETION.md b/docs/development/current/main/phases/phase-273/P2-COMPLETION.md new file mode 100644 index 00000000..abe375bb --- /dev/null +++ b/docs/development/current/main/phases/phase-273/P2-COMPLETION.md @@ -0,0 +1,33 @@ +# Phase 273 P2 Completion (2025-12-22) + +P2 Goal: +- Pattern7(split scan)を Plan ライン(DomainPlan→CorePlan→Lowerer)へ移行し、Lowerer の “pattern知識” を増やさない。 + +## Delivered + +- CoreEffectPlan: 副作用対応 + - `MethodCall` が `dst: Option` を持てる(`push` 等の void-return 対応) + - `effects: EffectMask` を CorePlan から指定できる(PURE ではない呼び出しを明示) + +- CoreLoopPlan: 一般化(Pattern6/7 の収束点) + - `block_effects: Vec<(BasicBlockId, Vec)>` + - `phis: Vec` + - `frag: Frag`(terminator SSOT: `emit_frag()`) + - `final_values: Vec<(String, ValueId)>`(variable_map 更新の SSOT) + +- Pattern7: Plan ライン移行 + - Extractor は pure(builder を触らない) + - Normalizer が split 固有のブロック構造/PHI/Frag を決定(SSOT) + - Lowerer は CorePlan を吐くだけ(pattern-agnostic) + +## Regression / Validation + +- VM: + - `tools/smokes/v2/profiles/integration/apps/phase256_p0_split_vm.sh` PASS(Pattern7) + - `tools/smokes/v2/profiles/integration/apps/phase258_p0_index_of_string_vm.sh` PASS(Pattern6) + +## Notes + +- P2 は “generalized 経路” と “legacy fallback” を共存させた(移行中の安全策)。 +- 次の P3 で Pattern6 も generalized 経路へ移し、legacy fallback を撤去すると収束が完成する。 + diff --git a/docs/development/current/main/phases/phase-273/P3-CLAUDE.md b/docs/development/current/main/phases/phase-273/P3-CLAUDE.md new file mode 100644 index 00000000..5898e6bf --- /dev/null +++ b/docs/development/current/main/phases/phase-273/P3-CLAUDE.md @@ -0,0 +1,95 @@ +# Phase 273 P3 — “Plan Lowering SSOT Finalize” (Claude Code Instructions) + +目的: +- Phase 273 P2 で導入した generalized CoreLoopPlan を SSOT として固定し、legacy fallback を撤去して収束を完成させる。 + +前提: +- Extractor は pure(builder 触り禁止) +- Pattern知識は Normalizer に閉じる +- Lowerer は CorePlan のみを処理(pattern-agnostic) +- terminator SSOT は `Frag → emit_frag()` のみ + +## Scope + +P3 でやる: +1. Pattern6 を generalized CoreLoopPlan(`frag/block_effects/phis/final_values`)へ移行 +2. `lower_loop_legacy()` を撤去し、generalized 経路を SSOT 化(Fail-Fast) +3. CoreLoopPlan の `Option<...>` を必須化して “揺れ” を構造で消す(可能なら) + +P3 でやらない: +- Pattern8/その他 pattern の Plan 化(別フェーズ) +- CorePlan の vocabulary 増殖(variant追加禁止) + +## Tasks + +### Task 1: Pattern6 を generalized CoreLoopPlan へ移行 + +対象: +- `src/mir/builder/control_flow/plan/normalizer.rs` + +やること: +- ScanWithInit の normalize で以下を構築する: + - `block_effects`: header/body/step の効果(ValueId は normalizer で生成・型登録) + - `phis`: header の loop-carrier PHI + - `frag`: header/body の BranchStub + wires(step→header, found→Return(i), after→Return(-1) など現行仕様に合わせる) + - `final_values`: `i` の最終値(after で使うならその ValueId) +- legacy field(`header_effects/body/step_effects/carriers/cond_*` など)を空/未使用にするか、最終的に削除する。 + +注意: +- ScanWithInit は “return” を含むので、Frag wires に Return を含める(emit_frag SSOT)。 +- `ensure_block_exists` が必要なブロック(after/found 等)は Lowerer で担保する。 + +### Task 2: Lowerer の legacy fallback を撤去 + +対象: +- `src/mir/builder/control_flow/plan/lowerer.rs` + +やること: +- `lower_loop_legacy()` を削除 +- `lower_loop()` は generalized フィールドを必須として扱い、欠落時は Err(Fail-Fast) + - 例: `block_effects/phis/frag/final_values` が None なら `[lowerer] missing generalized loop fields` で Err + +狙い: +- Lowerer から `emit_scan_with_init_edgecfg()` 等の pattern 参照を完全に消す。 + +### Task 3: CoreLoopPlan の “必須化”(可能な範囲で) + +対象: +- `src/mir/builder/control_flow/plan/mod.rs` + +やること: +- `block_effects/phis/frag/final_values` を `Option` から非Optionへ変更(できるなら) +- legacy fields を削除(この時点で Pattern6/7 が generalized を使っていることが前提) + +### Task 4: Verifier の拡張(generalized 専用の不変条件) + +対象: +- `src/mir/builder/control_flow/plan/verifier.rs` + +例: +- `phis` が空でないこと(carrierがある場合) +- `frag.entry` が header_bb に一致すること(loopのentry SSOT) +- `block_effects` に header/body/step が含まれること(最低限) + +### Task 5: 回帰テスト + +VM: +- `bash tools/smokes/v2/profiles/integration/apps/phase254_p0_index_of_vm.sh` +- `bash tools/smokes/v2/profiles/integration/apps/phase256_p0_split_vm.sh` +- `bash tools/smokes/v2/profiles/integration/apps/phase258_p0_index_of_string_vm.sh` + +LLVM(必ず harness で、mock禁止): +- `cargo build --release --features llvm` +- `bash tools/smokes/v2/profiles/integration/apps/phase256_p0_split_llvm_exe.sh` +- `bash tools/smokes/v2/profiles/integration/apps/phase258_p0_index_of_string_llvm_exe.sh` + +注意: +- `NYASH_LLVM_USE_HARNESS=1` で `--features llvm` が無い場合は fail-fast する(mock禁止)。 + +## Acceptance Criteria + +- Lowerer から `emit_scan_with_init_edgecfg()` 等の pattern 固有参照が消えている +- Pattern6/7 が generalized CoreLoopPlan を使用している +- legacy fallback が撤去され、欠落時は Err(Fail-Fast) +- 上記 smokes がすべて PASS(VM/LLVM) + diff --git a/docs/development/current/main/phases/phase-273/README.md b/docs/development/current/main/phases/phase-273/README.md index 1fae2f6a..ea5fae4b 100644 --- a/docs/development/current/main/phases/phase-273/README.md +++ b/docs/development/current/main/phases/phase-273/README.md @@ -1,6 +1,6 @@ # Phase 273: Plan Extractor (Pure) + PlanLowerer SSOT -Status: ✅ P0/P1 completed (2025-12-22) +Status: ✅ P0/P1/P2 completed (2025-12-22) Goal: - pattern 列挙の裾広がりを止める。 @@ -9,6 +9,15 @@ Goal: --- +## P2 完了 (2025-12-22) + +P2 では Pattern7(split scan)を Plan ラインへ移行し、P1 の CorePlan を保ったまま “収束圧” を上げた。 + +- ✅ Pattern7: Extractor → DomainPlan → Normalizer → CorePlan → Lowerer(MIR/Frag/emit_frag)へ統一 +- ✅ CoreLoopPlan: `block_effects / phis / frag / final_values` で一般化(Pattern6/7 が同一 CorePlan に収束) +- ✅ CoreEffectPlan: `dst: Option` + `effects: EffectMask` で副作用(例: `push`)を表現可能にした +- ✅ Lowerer: “split” の知識を持たず、CorePlan のみを処理(pattern-agnostic 維持) + ## P1 完了 (2025-12-22) ### アーキテクチャ @@ -52,7 +61,7 @@ pub enum CorePlan { } pub enum CoreEffectPlan { - MethodCall { dst, object, method, args }, + MethodCall { dst, object, method, args, effects }, BinOp { dst, lhs, op, rhs }, Compare { dst, lhs, op, rhs }, Const { dst, value }, @@ -111,6 +120,16 @@ AOT ランタイム(nyrt)は `ny_main()` の返り値が **raw i64** か **h - 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` +- P2 Completion: `docs/development/current/main/phases/phase-273/P2-COMPLETION.md` + +## Next (P3 proposal) + +P2 で追加した “legacy fallback” を残したままだと、Lowerer の中に `emit_scan_with_init_edgecfg()` 等の旧経路が残り続ける。 +収束を完成させるには、次を P3 で行うのが良い: + +- Pattern6 を generalized CoreLoopPlan(`frag/block_effects/phis/final_values`)に移行 +- `lower_loop_legacy()` を撤去し、generalized 経路を SSOT 化(Fail-Fast) +- CoreLoopPlan の `Option<...>` フィールドを必須化(構造で “揺れ” を消す) ## Future Work (P2+) diff --git a/src/mir/builder/control_flow/edgecfg/api/compose.rs b/src/mir/builder/control_flow/edgecfg/api/compose.rs index 9e767386..06926782 100644 --- a/src/mir/builder/control_flow/edgecfg/api/compose.rs +++ b/src/mir/builder/control_flow/edgecfg/api/compose.rs @@ -13,7 +13,6 @@ use std::collections::BTreeMap; use crate::mir::basic_block::{BasicBlockId, EdgeArgs}; use crate::mir::control_form::LoopId; use crate::mir::value_id::ValueId; -use crate::mir::join_ir::lowering::inline_boundary::JumpArgsLayout; use super::frag::Frag; use super::exit_kind::ExitKind; use super::edge_stub::EdgeStub; // Phase 265 P2: wires/exits 分離で必要 diff --git a/src/mir/builder/control_flow/edgecfg/api/mod.rs b/src/mir/builder/control_flow/edgecfg/api/mod.rs index 748202b3..e0a1fcf6 100644 --- a/src/mir/builder/control_flow/edgecfg/api/mod.rs +++ b/src/mir/builder/control_flow/edgecfg/api/mod.rs @@ -34,7 +34,7 @@ pub(crate) use compose::{seq, if_, loop_, cleanup}; // 検証関数 pub use verify::verify_frag_invariants; -pub use verify::verify_frag_invariants_strict; // Phase 266: strict 版追加 + // Phase 266: strict 版追加 // Phase 267 P0: wires + branches → MIR terminator 変換 -pub use emit::{emit_wires, emit_frag}; +pub use emit::emit_frag; diff --git a/src/mir/builder/control_flow/edgecfg/mod.rs b/src/mir/builder/control_flow/edgecfg/mod.rs index 5a37b944..83b35bc6 100644 --- a/src/mir/builder/control_flow/edgecfg/mod.rs +++ b/src/mir/builder/control_flow/edgecfg/mod.rs @@ -6,7 +6,5 @@ pub mod api; // 公開型(安定) -pub use api::{ExitKind, EdgeStub, Frag, verify_frag_invariants}; // 合成関数(Phase 264: crate内のみ公開) -pub(crate) use api::{seq, if_, loop_, cleanup}; diff --git a/src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs b/src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs index 99443003..e03530df 100644 --- a/src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs +++ b/src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs @@ -18,8 +18,7 @@ use crate::mir::builder::joinir_id_remapper::JoinIrIdRemapper; use crate::mir::join_ir::lowering::error_tags; use crate::mir::join_ir::lowering::inline_boundary::JoinInlineBoundary; // Phase 256 P1.7: Removed join_func_name import - no longer needed -use crate::mir::types::ConstValue; -use crate::mir::{BasicBlock, BasicBlockId, MirFunction, MirInstruction, MirModule, MirType, ValueId}; +use crate::mir::{BasicBlock, BasicBlockId, MirInstruction, MirModule, ValueId}; use std::collections::BTreeMap; // Phase 222.5-E: HashMap → BTreeMap for determinism use std::collections::BTreeSet; diff --git a/src/mir/builder/control_flow/joinir/merge/rewriter/mod.rs b/src/mir/builder/control_flow/joinir/merge/rewriter/mod.rs index 6c20a96a..33034510 100644 --- a/src/mir/builder/control_flow/joinir/merge/rewriter/mod.rs +++ b/src/mir/builder/control_flow/joinir/merge/rewriter/mod.rs @@ -39,5 +39,5 @@ pub(super) mod terminator; // Phase 260 P0.1 Step 5: Terminator remapping extrac pub(super) mod type_propagation; // Phase 260 P0.1 Step 4: Type propagation extracted ✅ // Re-export public API -pub(super) use helpers::is_skippable_continuation; // Phase 260 P0.1 Step 3: From helpers ✅ + // Phase 260 P0.1 Step 3: From helpers ✅ pub(super) use super::instruction_rewriter::merge_and_rewrite; // Still in parent (TODO: extract) diff --git a/src/mir/builder/control_flow/joinir/patterns/pattern2_lowering_orchestrator.rs b/src/mir/builder/control_flow/joinir/patterns/pattern2_lowering_orchestrator.rs index bd4d24da..78f809ca 100644 --- a/src/mir/builder/control_flow/joinir/patterns/pattern2_lowering_orchestrator.rs +++ b/src/mir/builder/control_flow/joinir/patterns/pattern2_lowering_orchestrator.rs @@ -36,7 +36,6 @@ use super::pattern2_steps::gather_facts_step_box::GatherFactsStepBox; use super::pattern2_steps::merge_step_box::MergeStepBox; use super::pattern2_steps::normalize_body_step_box::NormalizeBodyStepBox; use super::pattern2_steps::post_loop_early_return_step_box::PostLoopEarlyReturnStepBox; -use super::pattern2_steps::promote_step_box::PromoteStepBox; pub(crate) struct Pattern2LoweringOrchestrator; diff --git a/src/mir/builder/control_flow/joinir/patterns/pattern2_steps/emit_joinir_step_box.rs b/src/mir/builder/control_flow/joinir/patterns/pattern2_steps/emit_joinir_step_box.rs index 64a8ad4d..ba0c0ca2 100644 --- a/src/mir/builder/control_flow/joinir/patterns/pattern2_steps/emit_joinir_step_box.rs +++ b/src/mir/builder/control_flow/joinir/patterns/pattern2_steps/emit_joinir_step_box.rs @@ -4,7 +4,6 @@ use crate::ast::ASTNode; use crate::mir::builder::MirBuilder; -use crate::mir::ValueId; use super::super::pattern2_inputs_facts_box::{Pattern2DebugLog, Pattern2Inputs}; use crate::mir::join_ir::lowering::inline_boundary::JoinInlineBoundary; diff --git a/src/mir/builder/control_flow/joinir/patterns/pattern2_steps/promote_step_box.rs b/src/mir/builder/control_flow/joinir/patterns/pattern2_steps/promote_step_box.rs index 569ad0ce..f70f532b 100644 --- a/src/mir/builder/control_flow/joinir/patterns/pattern2_steps/promote_step_box.rs +++ b/src/mir/builder/control_flow/joinir/patterns/pattern2_steps/promote_step_box.rs @@ -10,7 +10,7 @@ use crate::ast::ASTNode; use crate::mir::builder::MirBuilder; -use super::super::pattern2::api::{try_promote, PromoteDecision, PromoteStepResult}; +use super::super::pattern2::api::{try_promote, PromoteDecision}; use super::super::pattern2_inputs_facts_box::Pattern2Inputs; pub(crate) struct PromoteStepBox; diff --git a/src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs b/src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs index 7ad435e2..59c6b38d 100644 --- a/src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs +++ b/src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs @@ -33,11 +33,8 @@ //! - MethodCall allowed_in_condition() = false, but allowed_in_init() = true //! - Need to hoist MethodCall to init phase -use super::super::trace; -use super::common::var; // Phase 255 P2: Use shared var() helper -use crate::ast::{ASTNode, BinaryOperator, LiteralValue}; -use crate::mir::builder::MirBuilder; -use crate::mir::ValueId; + // Phase 255 P2: Use shared var() helper +use crate::ast::ASTNode; // Phase 273 P1: Import DomainPlan types (Plan renamed to DomainPlan) use crate::mir::builder::control_flow::plan::{DomainPlan, ScanDirection as PlanScanDirection, ScanWithInitPlan}; diff --git a/src/mir/builder/control_flow/joinir/patterns/pattern8_scan_bool_predicate.rs b/src/mir/builder/control_flow/joinir/patterns/pattern8_scan_bool_predicate.rs index d7c71d86..8a09347c 100644 --- a/src/mir/builder/control_flow/joinir/patterns/pattern8_scan_bool_predicate.rs +++ b/src/mir/builder/control_flow/joinir/patterns/pattern8_scan_bool_predicate.rs @@ -34,7 +34,6 @@ //! - Pattern 8: Returns boolean (true/false) use super::super::trace; -use super::common::var; use crate::ast::{ASTNode, BinaryOperator, LiteralValue, UnaryOperator}; use crate::mir::builder::MirBuilder; use crate::mir::ValueId; diff --git a/src/mir/builder/control_flow/plan/mod.rs b/src/mir/builder/control_flow/plan/mod.rs index c3a34a89..582f7bb7 100644 --- a/src/mir/builder/control_flow/plan/mod.rs +++ b/src/mir/builder/control_flow/plan/mod.rs @@ -192,21 +192,7 @@ pub(in crate::mir::builder) struct CoreLoopPlan { pub final_values: Vec<(String, ValueId)>, } -/// Phase 273 P1: Loop carrier (PHI variable) -#[derive(Debug, Clone)] -pub(in crate::mir::builder) struct CoreCarrierInfo { - /// Variable name (for variable_map update) - pub name: String, - - /// Initial value (from preheader) - pub init_value: ValueId, - - /// Step value (from step block, back-edge) - pub step_value: ValueId, - - /// PHI destination (loop variable inside loop) - pub phi_dst: ValueId, -} +// Phase 273 P3: CoreCarrierInfo removed (replaced by CorePhiInfo) /// Phase 273 P1: Conditional plan #[derive(Debug, Clone)] diff --git a/src/mir/builder/control_flow/plan/normalizer.rs b/src/mir/builder/control_flow/plan/normalizer.rs index 08e27edd..88fb9b9f 100644 --- a/src/mir/builder/control_flow/plan/normalizer.rs +++ b/src/mir/builder/control_flow/plan/normalizer.rs @@ -12,7 +12,7 @@ //! Lowerer processes CorePlan without any pattern knowledge. use super::{ - CoreCarrierInfo, CoreEffectPlan, CoreLoopPlan, CorePhiInfo, CorePlan, DomainPlan, + CoreEffectPlan, CoreLoopPlan, CorePhiInfo, CorePlan, DomainPlan, ScanWithInitPlan, SplitScanPlan, }; use crate::mir::builder::control_flow::joinir::patterns::router::LoopPatternContext; diff --git a/src/mir/builder/control_flow/plan/verifier.rs b/src/mir/builder/control_flow/plan/verifier.rs index e8f958a0..001eb5f6 100644 --- a/src/mir/builder/control_flow/plan/verifier.rs +++ b/src/mir/builder/control_flow/plan/verifier.rs @@ -1,4 +1,4 @@ -//! Phase 273 P1: PlanVerifier - CorePlan 不変条件検証 (fail-fast) +//! Phase 273 P3: PlanVerifier - CorePlan 不変条件検証 (fail-fast) //! //! # Responsibilities //! @@ -6,16 +6,20 @@ //! - Fail fast on close-but-unsupported patterns //! - Prevent silent miscompilation //! -//! # Invariants (V1-V6) +//! # Invariants (V2-V9) //! -//! - V1: Carrier completeness (name/init_value/step_value present) //! - V2: Condition validity (valid ValueId) //! - V3: Exit validity (Return in function, Break/Continue in loop) //! - V4: Seq non-empty //! - V5: If completeness (then_plans non-empty) //! - V6: ValueId validity (all ValueIds pre-generated) +//! - V7: PHI non-empty (loops require at least one carrier) +//! - V8: Frag entry matches header_bb +//! - V9: block_effects contains header_bb +//! +//! Phase 273 P3: V1 (Carrier completeness) removed with CoreCarrierInfo -use super::{CoreCarrierInfo, CoreEffectPlan, CoreExitPlan, CoreIfPlan, CoreLoopPlan, CorePlan}; +use super::{CoreEffectPlan, CoreExitPlan, CoreIfPlan, CoreLoopPlan, CorePlan}; use crate::mir::ValueId; /// Phase 273 P1: PlanVerifier - CorePlan 不変条件検証 (fail-fast) @@ -132,21 +136,7 @@ impl PlanVerifier { Ok(()) } - /// V1: Carrier completeness - fn verify_carrier(carrier: &CoreCarrierInfo, depth: usize, index: usize) -> Result<(), String> { - if carrier.name.is_empty() { - return Err(format!( - "[V1] Carrier[{}] at depth {} has empty name", - index, depth - )); - } - - Self::verify_value_id_basic(carrier.init_value, depth, &format!("carrier[{}].init_value", index))?; - Self::verify_value_id_basic(carrier.step_value, depth, &format!("carrier[{}].step_value", index))?; - Self::verify_value_id_basic(carrier.phi_dst, depth, &format!("carrier[{}].phi_dst", index))?; - - Ok(()) - } + // Phase 273 P3: verify_carrier() removed (CoreCarrierInfo replaced by CorePhiInfo) /// V5: If completeness fn verify_if(if_plan: &CoreIfPlan, depth: usize, in_loop: bool) -> Result<(), String> { diff --git a/src/mir/builder/emission/loop_scan_with_init.rs b/src/mir/builder/emission/loop_scan_with_init.rs deleted file mode 100644 index 8c4f3eda..00000000 --- a/src/mir/builder/emission/loop_scan_with_init.rs +++ /dev/null @@ -1,143 +0,0 @@ -//! Phase 272 P0.1: Pattern6 Scan with Init - Emission Entrypoint -//! -//! ## Purpose -//! Thin entrypoint for Pattern6 Frag construction and MIR terminator emission. -//! This module only handles terminator wiring via EdgeCFG Frag API. -//! Block allocation and value computation (len, substring, match check) are done by Pattern6. -//! -//! ## Pattern Structure -//! ```nyash -//! index_of(s, ch) { -//! local i = 0 -//! loop(i < s.length()) { -//! if s.substring(i, i + 1) == ch { -//! return i -//! } -//! i = i + 1 -//! } -//! return -1 -//! } -//! ``` -//! -//! ## P0 Scope -//! - Forward scan only (step = 1) -//! - Fixed needle (ch) -//! - No ret_not_found_bb (after_bb handles AST return -1) -//! -//! ## Critical SSOT -//! 1. Return in wires (not exits) - emit_frag() generates terminators from wires/branches only -//! 2. after_bb has no terminator - let subsequent AST lowering handle "return -1" -//! 3. Frag assembly is direct field access (no with_* API) -//! 4. BranchStub/EdgeStub field names match current implementation -//! 5. Return Void (loop as statement, not expression) - -use crate::mir::builder::MirBuilder; -use crate::mir::builder::control_flow::edgecfg::api::{ - BranchStub, EdgeStub, ExitKind, Frag, emit_frag, -}; -use crate::mir::basic_block::{BasicBlockId, EdgeArgs}; -use crate::mir::join_ir::lowering::inline_boundary::JumpArgsLayout; -use crate::mir::ValueId; - -/// Emit Scan with Init EdgeCFG Fragment -/// -/// ## Arguments -/// - `b`: MirBuilder (for emit_frag access to current_function) -/// - `header_bb`: Loop condition check block (i < s.length()) -/// - `body_bb`: Substring + match check + early return branch -/// - `step_bb`: Increment i and jump back to header -/// - `after_bb`: Normal loop exit (no terminator - subsequent AST lowering handles "return -1") -/// - `ret_found_bb`: Early exit Return(i) block -/// - `cond_loop`: ValueId for (i < s.length()) -/// - `cond_match`: ValueId for (ch == needle) -/// - `i_found`: ValueId for loop variable i (return value for found case) -/// -/// ## Frag Structure -/// - **branches**: -/// 1. header: cond_loop true→body, false→after -/// 2. body: cond_match true→ret_found, false→step -/// - **wires**: -/// - step → header (Normal Jump) -/// - ret_found_bb → Return(i) - **IN WIRES, NOT EXITS** -/// - **exits**: empty (no upward propagation in P0) -/// -/// ## Returns -/// `Ok(())` - Frag emitted successfully -/// `Err` - emit_frag failed or current_function is None -pub(in crate::mir::builder) fn emit_scan_with_init_edgecfg( - b: &mut MirBuilder, - header_bb: BasicBlockId, - body_bb: BasicBlockId, - step_bb: BasicBlockId, - after_bb: BasicBlockId, - ret_found_bb: BasicBlockId, - cond_loop: ValueId, - cond_match: ValueId, - i_found: ValueId, -) -> Result<(), String> { - // EdgeArgs::empty() helper - let empty_args = EdgeArgs { - layout: JumpArgsLayout::CarriersOnly, - values: vec![], - }; - - // Return(i) arguments (contains found index) - let ret_found_args = EdgeArgs { - layout: JumpArgsLayout::CarriersOnly, - values: vec![i_found], - }; - - // branches (BranchStub) - current field names - let branches = vec![ - BranchStub { - from: header_bb, - cond: cond_loop, - then_target: body_bb, - then_args: empty_args.clone(), - else_target: after_bb, - else_args: empty_args.clone(), - }, - BranchStub { - from: body_bb, - cond: cond_match, - then_target: ret_found_bb, - then_args: empty_args.clone(), - else_target: step_bb, - else_args: empty_args.clone(), - }, - ]; - - // wires (EdgeStub) - current field names - let wires = vec![ - // step_bb → header_bb Jump (Normal) - EdgeStub { - from: step_bb, - kind: ExitKind::Normal, - target: Some(header_bb), - args: empty_args, - }, - // ret_found_bb Return(i) - THIS GOES IN WIRES! - EdgeStub { - from: ret_found_bb, - kind: ExitKind::Return, - target: None, - args: ret_found_args, - }, - // P0: No ret_not_found wire - after_bb handles AST return -1 - ]; - - // Frag assembly (direct field access - no with_* API exists) - let mut frag = Frag::new(header_bb); - frag.branches = branches; - frag.wires = wires; - // exits is empty (no upward propagation in P0) - - // emit_frag generates MIR terminators - if let Some(ref mut func) = b.scope_ctx.current_function { - emit_frag(func, &frag)?; - } else { - return Err("[emit_scan_with_init_edgecfg] current_function is None".to_string()); - } - - Ok(()) -} diff --git a/src/mir/builder/emission/mod.rs b/src/mir/builder/emission/mod.rs index ac32426c..027ea02b 100644 --- a/src/mir/builder/emission/mod.rs +++ b/src/mir/builder/emission/mod.rs @@ -4,13 +4,13 @@ //! - branch.rs: Branch/Jump 発行の薄い関数 //! - phi.rs: PHI挿入の薄いラッパー(builder context extraction) //! - loop_predicate_scan.rs: Pattern8 bool predicate scan EdgeCFG Frag (Phase 269 P1) -//! - loop_scan_with_init.rs: Pattern6 scan with init EdgeCFG Frag (Phase 272 P0.1) //! - loop_split_scan.rs: Pattern7 split scan EdgeCFG Frag (Phase 272 P0.2) +//! +//! Phase 273 P3: loop_scan_with_init.rs removed (replaced by generalized Frag API) pub mod branch; pub mod compare; pub mod constant; pub(in crate::mir::builder) mod phi; // Phase 272 P0.2 Refactoring pub(in crate::mir::builder) mod loop_predicate_scan; // Phase 269 P1 -pub(in crate::mir::builder) mod loop_scan_with_init; // Phase 272 P0.1 pub(in crate::mir::builder) mod loop_split_scan; // Phase 272 P0.2 diff --git a/src/mir/builder/lifecycle.rs b/src/mir/builder/lifecycle.rs index 21daff7f..2b21d198 100644 --- a/src/mir/builder/lifecycle.rs +++ b/src/mir/builder/lifecycle.rs @@ -44,7 +44,6 @@ use crate::mir::join_ir::lowering::generic_type_resolver::GenericTypeResolver; // Phase 83: P3-D 既知メソッド戻り値型推論箱 use crate::mir::join_ir::lowering::method_return_hint::MethodReturnHintBox; // Phase 84-2: Copy命令型伝播箱(ChatGPT Pro設計) -use crate::mir::phi_core::copy_type_propagator::CopyTypePropagator; // Phase 84-3: PHI + Copy グラフ型推論箱(ChatGPT Pro設計) use crate::mir::phi_core::phi_type_resolver::PhiTypeResolver; diff --git a/src/mir/join_ir/lowering/carrier_info.rs b/src/mir/join_ir/lowering/carrier_info.rs index 2e327e4b..c6f2c8fb 100644 --- a/src/mir/join_ir/lowering/carrier_info.rs +++ b/src/mir/join_ir/lowering/carrier_info.rs @@ -28,7 +28,6 @@ use std::collections::BTreeSet; #[cfg(feature = "normalized_dev")] use crate::mir::BindingId; // Phase 76+78: BindingId for promoted carriers -use crate::mir::join_ir::JoinFuncId; /// Phase 227: CarrierRole - Distinguishes loop state carriers from condition-only carriers /// diff --git a/src/mir/join_ir/lowering/inline_boundary.rs b/src/mir/join_ir/lowering/inline_boundary.rs index 07812452..acbfeae0 100644 --- a/src/mir/join_ir/lowering/inline_boundary.rs +++ b/src/mir/join_ir/lowering/inline_boundary.rs @@ -44,7 +44,6 @@ //! ``` use super::carrier_info::{CarrierRole, ExitReconnectMode}; -use crate::mir::join_ir::JoinFuncId; use crate::mir::ValueId; use std::collections::BTreeSet; diff --git a/src/mir/join_ir_vm_bridge/handlers/jump.rs b/src/mir/join_ir_vm_bridge/handlers/jump.rs index 97483c87..f149d0e8 100644 --- a/src/mir/join_ir_vm_bridge/handlers/jump.rs +++ b/src/mir/join_ir_vm_bridge/handlers/jump.rs @@ -89,10 +89,9 @@ //! jump_args_layout = CarriersOnly //! ``` -use crate::ast::Span; use crate::mir::join_ir::{JoinContId, JoinFuncId}; use crate::mir::join_ir::lowering::inline_boundary::JumpArgsLayout; -use crate::mir::{BasicBlock, BasicBlockId, EffectMask, MirFunction, MirInstruction, ValueId}; +use crate::mir::{BasicBlock, BasicBlockId, MirFunction, MirInstruction, ValueId}; use std::collections::BTreeMap; use super::super::{join_func_name, JoinIrVmBridgeError}; diff --git a/src/mir/join_ir_vm_bridge/joinir_function_converter.rs b/src/mir/join_ir_vm_bridge/joinir_function_converter.rs index 3d1ba918..b1330204 100644 --- a/src/mir/join_ir_vm_bridge/joinir_function_converter.rs +++ b/src/mir/join_ir_vm_bridge/joinir_function_converter.rs @@ -6,9 +6,7 @@ //! - 関数署名の管理 use crate::mir::join_ir::{JoinFuncId, JoinFunction, JoinModule}; -use crate::mir::phi_core::copy_type_propagator::CopyTypePropagator; -use crate::mir::phi_core::phi_type_resolver::PhiTypeResolver; -use crate::mir::{BasicBlockId, EffectMask, FunctionSignature, MirFunction, MirInstruction, MirModule, MirType}; +use crate::mir::{BasicBlockId, EffectMask, FunctionSignature, MirFunction, MirModule, MirType}; use std::collections::BTreeMap; use super::join_func_name; diff --git a/src/mir/verification/cfg.rs b/src/mir/verification/cfg.rs index 90ef8b24..23ecbcce 100644 --- a/src/mir/verification/cfg.rs +++ b/src/mir/verification/cfg.rs @@ -1,7 +1,7 @@ use crate::mir::function::MirFunction; use crate::mir::verification::utils; use crate::mir::verification_types::VerificationError; -use crate::mir::{BasicBlockId, MirInstruction, ValueId}; +use crate::mir::{BasicBlockId, ValueId}; use std::collections::{HashMap, HashSet}; /// Verify CFG references and reachability