phase29ao(p8): ssot compose preserves edgeargs for valuejoin
This commit is contained in:
@ -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 P8)**
|
||||
`docs/development/current/main/phases/phase-29ao/P8-VALUEJOIN-EDGEARGS-COMPOSE-PRESERVE-INSTRUCTIONS.md`
|
||||
**Next implementation (Phase 29ao P9)**
|
||||
`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 移行の土台を作った。
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
## Current Focus: Phase 29ao(CorePlan composition)
|
||||
|
||||
Next: Phase 29ao P8(ValueJoin: EdgeArgs compose preservation SSOT)
|
||||
Next: Phase 29ao P9(ValueJoin minimal wire)
|
||||
指示書: `docs/development/current/main/phases/phase-29ao/P8-VALUEJOIN-EDGEARGS-COMPOSE-PRESERVE-INSTRUCTIONS.md`
|
||||
運用ルール: integration filter で phase143_* は回さない(JoinIR 回帰は phase29ae pack のみ)
|
||||
運用ルール: phase286_pattern9_* は legacy pack (SKIP) を使う
|
||||
@ -48,6 +48,11 @@ Next: Phase 29ao P8(ValueJoin: EdgeArgs compose preservation SSOT)
|
||||
- 変更: `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-30: Phase 29ao P8 完了** ✅
|
||||
- 目的: compose::seq/if_/cleanup が EdgeArgs(layout+values) を保持することをテストで固定
|
||||
- 変更: `src/mir/builder/control_flow/edgecfg/api/compose/seq.rs` / `src/mir/builder/control_flow/edgecfg/api/compose/if_.rs` / `src/mir/builder/control_flow/edgecfg/api/compose/cleanup.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 test --release -p nyash-rust` / `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`
|
||||
|
||||
@ -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/P7 ✅ 完了 / Next: P8
|
||||
- 状況: P0/P1/P2/P3/P4/P5/P6/P7/P8 ✅ 完了 / Next: P9
|
||||
- Next 指示書: `docs/development/current/main/phases/phase-29ao/P8-VALUEJOIN-EDGEARGS-COMPOSE-PRESERVE-INSTRUCTIONS.md`
|
||||
|
||||
- **Phase 29af(✅ COMPLETE): Boundary hygiene / regression entrypoint / carrier layout SSOT**
|
||||
|
||||
@ -58,7 +58,11 @@ Gate(SSOT):
|
||||
- 指示書: `docs/development/current/main/phases/phase-29ao/P7-VALUEJOIN-EDGEARGS-LAYOUT-VERIFY-INSTRUCTIONS.md`
|
||||
- ねらい: `ExprResultPlusCarriers` の語彙と最小検証を PlanVerifier に追加(未接続)
|
||||
|
||||
## P8: compose が EdgeArgs を保持することの検証(仕様不変)✅
|
||||
|
||||
- 指示書: `docs/development/current/main/phases/phase-29ao/P8-VALUEJOIN-EDGEARGS-COMPOSE-PRESERVE-INSTRUCTIONS.md`
|
||||
- ねらい: compose::seq/if_/cleanup が EdgeArgs(layout+values) を保持することをテストで固定
|
||||
|
||||
## Next(planned)
|
||||
|
||||
- P8: ValueJoin の前提固定(compose が EdgeArgs を壊さないことをテストでSSOT化)
|
||||
- 指示書: `docs/development/current/main/phases/phase-29ao/P8-VALUEJOIN-EDGEARGS-COMPOSE-PRESERVE-INSTRUCTIONS.md`
|
||||
- P9: ValueJoin の最小 wire(strict/dev Fail-Fast 付き)
|
||||
|
||||
@ -133,3 +133,47 @@ pub(crate) fn cleanup(
|
||||
branches,
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::cleanup;
|
||||
use crate::mir::basic_block::{BasicBlockId, EdgeArgs};
|
||||
use crate::mir::builder::control_flow::edgecfg::api::edge_stub::EdgeStub;
|
||||
use crate::mir::builder::control_flow::edgecfg::api::exit_kind::ExitKind;
|
||||
use crate::mir::builder::control_flow::edgecfg::api::frag::Frag;
|
||||
use crate::mir::join_ir::lowering::inline_boundary::JumpArgsLayout;
|
||||
use crate::mir::ValueId;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
#[test]
|
||||
fn cleanup_preserves_edgeargs_for_return_exit() {
|
||||
let main = Frag::new(BasicBlockId::new(1));
|
||||
let cleanup_entry = BasicBlockId::new(2);
|
||||
let args = EdgeArgs {
|
||||
layout: JumpArgsLayout::ExprResultPlusCarriers,
|
||||
values: vec![ValueId(30)],
|
||||
};
|
||||
let mut exits = BTreeMap::new();
|
||||
exits.insert(
|
||||
ExitKind::Return,
|
||||
vec![EdgeStub {
|
||||
from: cleanup_entry,
|
||||
kind: ExitKind::Return,
|
||||
target: None,
|
||||
args: args.clone(),
|
||||
}],
|
||||
);
|
||||
let cleanup_frag = Frag {
|
||||
entry: cleanup_entry,
|
||||
exits,
|
||||
wires: vec![],
|
||||
branches: vec![],
|
||||
};
|
||||
|
||||
let composed =
|
||||
cleanup(main, cleanup_frag, None, None).expect("cleanup ok");
|
||||
assert_eq!(composed.wires.len(), 1);
|
||||
assert_eq!(composed.wires[0].args, args);
|
||||
assert!(composed.wires[0].target.is_none());
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,3 +137,93 @@ pub(crate) fn if_(
|
||||
branches, // Phase 267 P0: header の BranchStub + t/e/join の branches
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::if_;
|
||||
use crate::mir::basic_block::{BasicBlockId, EdgeArgs};
|
||||
use crate::mir::builder::control_flow::edgecfg::api::edge_stub::EdgeStub;
|
||||
use crate::mir::builder::control_flow::edgecfg::api::exit_kind::ExitKind;
|
||||
use crate::mir::builder::control_flow::edgecfg::api::frag::Frag;
|
||||
use crate::mir::join_ir::lowering::inline_boundary::JumpArgsLayout;
|
||||
use crate::mir::value_id::ValueId;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
#[test]
|
||||
fn if_preserves_edgeargs_for_then_else_normal_exits() {
|
||||
let header = BasicBlockId::new(1);
|
||||
let then_entry = BasicBlockId::new(2);
|
||||
let else_entry = BasicBlockId::new(3);
|
||||
let join_entry = BasicBlockId::new(4);
|
||||
let cond = ValueId(10);
|
||||
let then_entry_args = EdgeArgs {
|
||||
layout: JumpArgsLayout::CarriersOnly,
|
||||
values: vec![],
|
||||
};
|
||||
let else_entry_args = EdgeArgs {
|
||||
layout: JumpArgsLayout::CarriersOnly,
|
||||
values: vec![],
|
||||
};
|
||||
let then_args = EdgeArgs {
|
||||
layout: JumpArgsLayout::ExprResultPlusCarriers,
|
||||
values: vec![ValueId(20)],
|
||||
};
|
||||
let else_args = EdgeArgs {
|
||||
layout: JumpArgsLayout::ExprResultPlusCarriers,
|
||||
values: vec![ValueId(21)],
|
||||
};
|
||||
|
||||
let mut then_exits = BTreeMap::new();
|
||||
then_exits.insert(
|
||||
ExitKind::Normal,
|
||||
vec![EdgeStub {
|
||||
from: then_entry,
|
||||
kind: ExitKind::Normal,
|
||||
target: None,
|
||||
args: then_args.clone(),
|
||||
}],
|
||||
);
|
||||
let then_frag = Frag {
|
||||
entry: then_entry,
|
||||
exits: then_exits,
|
||||
wires: vec![],
|
||||
branches: vec![],
|
||||
};
|
||||
|
||||
let mut else_exits = BTreeMap::new();
|
||||
else_exits.insert(
|
||||
ExitKind::Normal,
|
||||
vec![EdgeStub {
|
||||
from: else_entry,
|
||||
kind: ExitKind::Normal,
|
||||
target: None,
|
||||
args: else_args.clone(),
|
||||
}],
|
||||
);
|
||||
let else_frag = Frag {
|
||||
entry: else_entry,
|
||||
exits: else_exits,
|
||||
wires: vec![],
|
||||
branches: vec![],
|
||||
};
|
||||
|
||||
let join_frag = Frag::new(join_entry);
|
||||
let composed = if_(
|
||||
header,
|
||||
cond,
|
||||
then_frag,
|
||||
then_entry_args,
|
||||
else_frag,
|
||||
else_entry_args,
|
||||
join_frag,
|
||||
);
|
||||
|
||||
assert_eq!(composed.wires.len(), 2);
|
||||
assert!(composed.wires.iter().any(|stub| {
|
||||
stub.target == Some(join_entry) && stub.args == then_args
|
||||
}));
|
||||
assert!(composed.wires.iter().any(|stub| {
|
||||
stub.target == Some(join_entry) && stub.args == else_args
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,3 +87,44 @@ pub(crate) fn seq(a: Frag, b: Frag) -> Frag {
|
||||
branches, // Phase 267 P0: a.branches + b.branches
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::seq;
|
||||
use crate::mir::basic_block::{BasicBlockId, EdgeArgs};
|
||||
use crate::mir::builder::control_flow::edgecfg::api::edge_stub::EdgeStub;
|
||||
use crate::mir::builder::control_flow::edgecfg::api::exit_kind::ExitKind;
|
||||
use crate::mir::builder::control_flow::edgecfg::api::frag::Frag;
|
||||
use crate::mir::join_ir::lowering::inline_boundary::JumpArgsLayout;
|
||||
use crate::mir::ValueId;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
#[test]
|
||||
fn seq_preserves_edgeargs_for_normal_exit() {
|
||||
let a_entry = BasicBlockId::new(1);
|
||||
let b_entry = BasicBlockId::new(2);
|
||||
let args = EdgeArgs {
|
||||
layout: JumpArgsLayout::ExprResultPlusCarriers,
|
||||
values: vec![ValueId(10)],
|
||||
};
|
||||
let stub = EdgeStub {
|
||||
from: a_entry,
|
||||
kind: ExitKind::Normal,
|
||||
target: None,
|
||||
args: args.clone(),
|
||||
};
|
||||
let mut exits = BTreeMap::new();
|
||||
exits.insert(ExitKind::Normal, vec![stub]);
|
||||
let a = Frag {
|
||||
entry: a_entry,
|
||||
exits,
|
||||
wires: vec![],
|
||||
branches: vec![],
|
||||
};
|
||||
let b = Frag::new(b_entry);
|
||||
let composed = seq(a, b);
|
||||
assert_eq!(composed.wires.len(), 1);
|
||||
assert_eq!(composed.wires[0].target, Some(b_entry));
|
||||
assert_eq!(composed.wires[0].args, args);
|
||||
}
|
||||
}
|
||||
|
||||
@ -397,16 +397,21 @@ mod tests {
|
||||
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;
|
||||
#[cfg(debug_assertions)]
|
||||
use crate::mir::builder::control_flow::plan::facts::feature_facts::{
|
||||
LoopFeatureFacts, ValueJoinFacts,
|
||||
};
|
||||
#[cfg(debug_assertions)]
|
||||
use crate::mir::builder::control_flow::plan::facts::loop_facts::LoopFacts;
|
||||
#[cfg(debug_assertions)]
|
||||
use crate::mir::builder::control_flow::plan::facts::scan_shapes::{
|
||||
ConditionShape, StepShape,
|
||||
};
|
||||
#[cfg(debug_assertions)]
|
||||
use crate::mir::builder::control_flow::plan::facts::skeleton_facts::{
|
||||
SkeletonFacts, SkeletonKind,
|
||||
};
|
||||
#[cfg(debug_assertions)]
|
||||
use crate::mir::builder::control_flow::plan::normalize::canonicalize_loop_facts;
|
||||
use crate::mir::join_ir::lowering::inline_boundary::JumpArgsLayout;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
Reference in New Issue
Block a user