diff --git a/CURRENT_TASK.md b/CURRENT_TASK.md index f19ab450..069a2d7b 100644 --- a/CURRENT_TASK.md +++ b/CURRENT_TASK.md @@ -18,8 +18,8 @@ Scope: Repo root の旧リンク互換。現行の入口は `docs/development/cu **CorePlan migration 道筋 SSOT** `docs/development/current/main/design/coreplan-migration-roadmap-ssot.md` が移行タスクの Done 判定の入口。 -**Next implementation (Phase 29ao P7)** -`docs/development/current/main/phases/phase-29ao/P7-VALUEJOIN-EDGEARGS-LAYOUT-VERIFY-INSTRUCTIONS.md` +**Next implementation (Phase 29ao P8)** +`docs/development/current/main/phases/phase-29ao/README.md` **2025-12-29: Phase 29am P0 COMPLETE (CorePlan If/Exit lowerer/verifier)** CorePlan の If/Exit を lowerer/verifier で扱えるようにして、CorePlan 移行の土台を作った。 diff --git a/docs/development/current/main/10-Now.md b/docs/development/current/main/10-Now.md index 1c662708..6e4bc7e8 100644 --- a/docs/development/current/main/10-Now.md +++ b/docs/development/current/main/10-Now.md @@ -2,7 +2,7 @@ ## Current Focus: Phase 29ao(CorePlan composition) -Next: Phase 29ao P7(ValueJoin wire → CorePlan/Frag) +Next: Phase 29ao P8(ValueJoin minimal wire) 運用ルール: integration filter で phase143_* は回さない(JoinIR 回帰は phase29ae pack のみ) 運用ルール: phase286_pattern9_* は legacy pack (SKIP) を使う 移行道筋 SSOT: `docs/development/current/main/design/coreplan-migration-roadmap-ssot.md` @@ -42,6 +42,11 @@ Next: Phase 29ao P7(ValueJoin wire → CorePlan/Frag) - 変更: `src/mir/builder/control_flow/plan/normalizer/skeleton_loop.rs` / `src/mir/builder/control_flow/plan/composer/mod.rs` / `docs/development/current/main/phases/phase-29ao/README.md` / `docs/development/current/main/10-Now.md` / `docs/development/current/main/30-Backlog.md` / `CURRENT_TASK.md` - 検証: `cargo build --release` / `./tools/smokes/v2/run.sh --profile quick` / `./tools/smokes/v2/profiles/integration/joinir/phase29ae_regression_pack_vm.sh` +**2025-12-30: Phase 29ao P7 完了** ✅ +- 目的: `ExprResultPlusCarriers` の語彙固定と最小 verify を追加(未接続) +- 変更: `src/mir/builder/control_flow/plan/normalizer/value_join_args.rs` / `src/mir/builder/control_flow/plan/normalizer/mod.rs` / `src/mir/builder/control_flow/plan/verifier.rs` / `docs/development/current/main/phases/phase-29ao/README.md` / `docs/development/current/main/10-Now.md` / `docs/development/current/main/30-Backlog.md` / `CURRENT_TASK.md` +- 検証: `cargo build --release` / `./tools/smokes/v2/run.sh --profile quick` / `./tools/smokes/v2/profiles/integration/joinir/phase29ae_regression_pack_vm.sh` + **2025-12-29: Phase 29an P15 完了** ✅ - 目的: P0–P14 の成果を closeout 形式でまとめ、次フェーズ(Phase 29ao)入口を固定 - 変更: `docs/development/current/main/phases/phase-29an/README.md` / `docs/development/current/main/10-Now.md` / `docs/development/current/main/30-Backlog.md` / `CURRENT_TASK.md` diff --git a/docs/development/current/main/30-Backlog.md b/docs/development/current/main/30-Backlog.md index f426c917..4445ee9a 100644 --- a/docs/development/current/main/30-Backlog.md +++ b/docs/development/current/main/30-Backlog.md @@ -15,7 +15,7 @@ Related: - **Phase 29ao(active): CorePlan composition from Skeleton/Feature** - 入口: `docs/development/current/main/phases/phase-29ao/README.md` - - 状況: P0/P1/P2/P3/P4/P5/P6 ✅ 完了 / Next: P7 + - 状況: P0/P1/P2/P3/P4/P5/P6/P7 ✅ 完了 / Next: P8 - **Phase 29af(✅ COMPLETE): Boundary hygiene / regression entrypoint / carrier layout SSOT** - 入口: `docs/development/current/main/phases/phase-29af/README.md` diff --git a/docs/development/current/main/phases/phase-29ao/README.md b/docs/development/current/main/phases/phase-29ao/README.md index f9ed1d42..76a1c44e 100644 --- a/docs/development/current/main/phases/phase-29ao/README.md +++ b/docs/development/current/main/phases/phase-29ao/README.md @@ -53,7 +53,11 @@ Gate(SSOT): - 指示書: `docs/development/current/main/phases/phase-29ao/P6-VALUEJOIN-PRESENCE-GATE-INSTRUCTIONS.md` - ねらい: `value_join_needed` が立つケースは direct skeleton を採用しない(fallback維持) +## P7: ValueJoin wire(EdgeArgs layout の語彙固定 + 局所 verify)✅ + +- 指示書: `docs/development/current/main/phases/phase-29ao/P7-VALUEJOIN-EDGEARGS-LAYOUT-VERIFY-INSTRUCTIONS.md` +- ねらい: `ExprResultPlusCarriers` の語彙と最小検証を PlanVerifier に追加(未接続) + ## Next(planned) -- P7: ValueJoin wire(EdgeArgs layout の語彙固定 + 局所 verify、未接続・仕様不変) - - 指示書: `docs/development/current/main/phases/phase-29ao/P7-VALUEJOIN-EDGEARGS-LAYOUT-VERIFY-INSTRUCTIONS.md` +- P8: ValueJoin の最小 wire(strict/dev Fail-Fast 付き) diff --git a/src/mir/builder/control_flow/plan/normalizer/mod.rs b/src/mir/builder/control_flow/plan/normalizer/mod.rs index 35a1895d..c79bec4a 100644 --- a/src/mir/builder/control_flow/plan/normalizer/mod.rs +++ b/src/mir/builder/control_flow/plan/normalizer/mod.rs @@ -22,6 +22,7 @@ mod pattern9_accum_const_loop; mod pattern_scan_with_init; mod pattern_split_scan; mod skeleton_loop; +mod value_join_args; mod common; use super::{ diff --git a/src/mir/builder/control_flow/plan/normalizer/value_join_args.rs b/src/mir/builder/control_flow/plan/normalizer/value_join_args.rs new file mode 100644 index 00000000..5f345adb --- /dev/null +++ b/src/mir/builder/control_flow/plan/normalizer/value_join_args.rs @@ -0,0 +1,17 @@ +use crate::mir::basic_block::EdgeArgs; +use crate::mir::join_ir::lowering::inline_boundary::JumpArgsLayout; +use crate::mir::ValueId; + +#[allow(dead_code)] +pub(super) fn expr_result_plus_carriers_args( + expr_result: ValueId, + carriers: Vec, +) -> EdgeArgs { + let mut values = Vec::with_capacity(1 + carriers.len()); + values.push(expr_result); + values.extend(carriers); + EdgeArgs { + layout: JumpArgsLayout::ExprResultPlusCarriers, + values, + } +} diff --git a/src/mir/builder/control_flow/plan/verifier.rs b/src/mir/builder/control_flow/plan/verifier.rs index 96423683..8a5783bc 100644 --- a/src/mir/builder/control_flow/plan/verifier.rs +++ b/src/mir/builder/control_flow/plan/verifier.rs @@ -23,7 +23,9 @@ //! Phase 273 P3: V1 (Carrier completeness) removed with CoreCarrierInfo use super::{CoreEffectPlan, CoreExitPlan, CoreIfPlan, CoreLoopPlan, CorePlan}; +use crate::mir::basic_block::EdgeArgs; use crate::mir::builder::control_flow::plan::normalize::CanonicalLoopFacts; +use crate::mir::join_ir::lowering::inline_boundary::JumpArgsLayout; use crate::mir::ValueId; /// Phase 273 P1: PlanVerifier - CorePlan 不変条件検証 (fail-fast) @@ -152,6 +154,32 @@ impl PlanVerifier { Self::verify_value_id_basic(*val, depth, &format!("final_values[{}]", i))?; } + // Verify EdgeArgs layout (V13) + for (i, wire) in loop_plan.frag.wires.iter().enumerate() { + Self::verify_edge_args_layout(&wire.args, depth, &format!("frag.wires[{}]", i))?; + } + for (kind, stubs) in loop_plan.frag.exits.iter() { + for (i, stub) in stubs.iter().enumerate() { + Self::verify_edge_args_layout( + &stub.args, + depth, + &format!("frag.exits[{}][{}]", kind, i), + )?; + } + } + for (i, branch) in loop_plan.frag.branches.iter().enumerate() { + Self::verify_edge_args_layout( + &branch.then_args, + depth, + &format!("frag.branches[{}].then", i), + )?; + Self::verify_edge_args_layout( + &branch.else_args, + depth, + &format!("frag.branches[{}].else", i), + )?; + } + Ok(()) } @@ -331,6 +359,22 @@ impl PlanVerifier { let _ = (value_id, depth, context); Ok(()) } + + fn verify_edge_args_layout( + args: &EdgeArgs, + depth: usize, + context: &str, + ) -> Result<(), String> { + if matches!(args.layout, JumpArgsLayout::ExprResultPlusCarriers) + && args.values.is_empty() + { + return Err(format!( + "[V13] EdgeArgs at depth {} {} requires expr_result value", + depth, context + )); + } + Ok(()) + } } #[cfg(debug_assertions)] @@ -350,7 +394,8 @@ pub(in crate::mir::builder) fn debug_assert_value_join_invariants(_facts: &Canon mod tests { use super::*; use crate::mir::{BasicBlockId, ConstValue, ValueId}; - use crate::mir::builder::control_flow::edgecfg::api::Frag; + use crate::mir::basic_block::EdgeArgs; + use crate::mir::builder::control_flow::edgecfg::api::{EdgeStub, ExitKind, Frag}; use crate::mir::builder::control_flow::plan::CorePhiInfo; use crate::mir::builder::control_flow::plan::facts::feature_facts::{ LoopFeatureFacts, ValueJoinFacts, @@ -363,6 +408,7 @@ mod tests { SkeletonFacts, SkeletonKind, }; use crate::mir::builder::control_flow::plan::normalize::canonicalize_loop_facts; + use crate::mir::join_ir::lowering::inline_boundary::JumpArgsLayout; use std::collections::BTreeMap; fn make_loop_plan(body: Vec) -> CoreLoopPlan { @@ -520,6 +566,41 @@ mod tests { assert!(result.unwrap_err().contains("[V11]")); } + #[test] + fn test_verify_expr_result_plus_carriers_requires_value() { + let mut loop_plan = make_loop_plan(vec![]); + loop_plan.frag.wires = vec![EdgeStub { + from: loop_plan.body_bb, + kind: ExitKind::Normal, + target: Some(loop_plan.step_bb), + args: EdgeArgs { + layout: JumpArgsLayout::ExprResultPlusCarriers, + values: vec![], + }, + }]; + let plan = CorePlan::Loop(loop_plan); + let result = PlanVerifier::verify(&plan); + assert!(result.is_err()); + assert!(result.unwrap_err().contains("[V13]")); + } + + #[test] + fn test_verify_expr_result_plus_carriers_with_value_ok() { + let mut loop_plan = make_loop_plan(vec![]); + loop_plan.frag.wires = vec![EdgeStub { + from: loop_plan.body_bb, + kind: ExitKind::Normal, + target: Some(loop_plan.step_bb), + args: EdgeArgs { + layout: JumpArgsLayout::ExprResultPlusCarriers, + values: vec![ValueId(200)], + }, + }]; + let plan = CorePlan::Loop(loop_plan); + let result = PlanVerifier::verify(&plan); + assert!(result.is_ok()); + } + #[cfg(debug_assertions)] #[test] fn debug_value_join_invariant_allows_empty_when_not_needed() {