phase29ao(p11): normalizer demo generates block_params 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 P11)**
|
||||
`docs/development/current/main/phases/phase-29ao/P11-VALUEJOIN-NORMALIZER-GENERATES-BLOCKPARAMS-INSTRUCTIONS.md`
|
||||
**Next implementation (Phase 29ao P12, TBD)**
|
||||
`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,8 +2,8 @@
|
||||
|
||||
## Current Focus: Phase 29ao(CorePlan composition)
|
||||
|
||||
Next: Phase 29ao P11(Normalizer generates block_params for ValueJoin, minimal)
|
||||
指示書: `docs/development/current/main/phases/phase-29ao/P11-VALUEJOIN-NORMALIZER-GENERATES-BLOCKPARAMS-INSTRUCTIONS.md`
|
||||
Next: Phase 29ao P12(ValueJoin first real usage, TBD)
|
||||
指示書: `docs/development/current/main/phases/phase-29ao/README.md`
|
||||
運用ルール: integration filter で phase143_* は回さない(JoinIR 回帰は phase29ae pack のみ)
|
||||
運用ルール: phase286_pattern9_* は legacy pack (SKIP) を使う
|
||||
移行道筋 SSOT: `docs/development/current/main/design/coreplan-migration-roadmap-ssot.md`
|
||||
@ -63,6 +63,11 @@ Next: Phase 29ao P11(Normalizer generates block_params for ValueJoin, minimal
|
||||
- 変更: `src/mir/builder/control_flow/edgecfg/api/emit.rs` / `src/mir/builder/control_flow/edgecfg/api/verify.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 --lib` / `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 P11 完了** ✅
|
||||
- 目的: Normalizer が `Frag.block_params` を生成する最小ケース(If2 demo)を追加し、PHI挿入まで unit test で固定
|
||||
- 変更: `src/mir/builder/control_flow/plan/normalizer/value_join_demo_if2.rs` / `src/mir/builder/control_flow/plan/normalizer/mod.rs` / `src/mir/builder/control_flow/edgecfg/api/emit.rs` / `src/mir/builder/control_flow/edgecfg/api/verify.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 --lib` / `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,8 +15,8 @@ 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/P8/P9/P10 ✅ 完了 / Next: P11(TBD)
|
||||
- Next 指示書: `docs/development/current/main/phases/phase-29ao/P11-VALUEJOIN-NORMALIZER-GENERATES-BLOCKPARAMS-INSTRUCTIONS.md`
|
||||
- 状況: P0/P1/P2/P3/P4/P5/P6/P7/P8/P9/P10/P11 ✅ 完了 / Next: P12(TBD)
|
||||
- Next 指示書: `docs/development/current/main/phases/phase-29ao/README.md`
|
||||
|
||||
- **Phase 29af(✅ COMPLETE): Boundary hygiene / regression entrypoint / carrier layout SSOT**
|
||||
- 入口: `docs/development/current/main/phases/phase-29af/README.md`
|
||||
|
||||
@ -73,7 +73,11 @@ Gate(SSOT):
|
||||
- 指示書: `docs/development/current/main/phases/phase-29ao/P10-VALUEJOIN-BLOCKPARAMS-PHI-INSERTION-INSTRUCTIONS.md`
|
||||
- ねらい: `Frag.block_params` を `emit_frag()` で PHI に落とす唯一の接続点を追加(未接続のまま)
|
||||
|
||||
## P11: Normalizer generates block_params (If2 demo) ✅
|
||||
|
||||
- 指示書: `docs/development/current/main/phases/phase-29ao/P11-VALUEJOIN-NORMALIZER-GENERATES-BLOCKPARAMS-INSTRUCTIONS.md`
|
||||
- ねらい: Normalizer が `Frag.block_params` を生成する最小ケースを追加し、PHI挿入まで unit test で固定
|
||||
|
||||
## Next(planned)
|
||||
|
||||
- P11: Normalizer が block_params を生成する最小ケース(ValueJoin “最初の生成”)
|
||||
- 指示書: `docs/development/current/main/phases/phase-29ao/P11-VALUEJOIN-NORMALIZER-GENERATES-BLOCKPARAMS-INSTRUCTIONS.md`
|
||||
- P12: ValueJoin の最初の実使用(Normalizer の実経路で block_params を生成し、fixture を 1 本緑にする)
|
||||
|
||||
@ -24,6 +24,8 @@ mod pattern_split_scan;
|
||||
mod skeleton_loop;
|
||||
mod value_join_args;
|
||||
mod common;
|
||||
#[cfg(test)]
|
||||
mod value_join_demo_if2;
|
||||
|
||||
use super::{
|
||||
CoreEffectPlan, CoreLoopPlan, CorePhiInfo, CorePlan, DomainPlan, Pattern1SimpleWhilePlan,
|
||||
|
||||
@ -0,0 +1,172 @@
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::collections::BTreeMap;
|
||||
use std::env;
|
||||
|
||||
use crate::mir::basic_block::{BasicBlockId, EdgeArgs};
|
||||
use crate::mir::builder::control_flow::edgecfg::api::{
|
||||
block_params::BlockParams, BranchStub, EdgeStub, ExitKind, Frag, emit_frag,
|
||||
};
|
||||
use crate::mir::function::{FunctionSignature, MirFunction};
|
||||
use crate::mir::join_ir::lowering::inline_boundary::JumpArgsLayout;
|
||||
use crate::mir::types::MirType;
|
||||
use crate::mir::{BasicBlock, EffectMask, MirInstruction, ValueId};
|
||||
|
||||
struct DemoIf2 {
|
||||
frag: Frag,
|
||||
function: MirFunction,
|
||||
then_bb: BasicBlockId,
|
||||
else_bb: BasicBlockId,
|
||||
join_bb: BasicBlockId,
|
||||
expr_param: ValueId,
|
||||
then_val: ValueId,
|
||||
else_val: ValueId,
|
||||
}
|
||||
|
||||
fn strict_env_guard() -> impl Drop {
|
||||
env::set_var("NYASH_JOINIR_STRICT", "1");
|
||||
struct Guard;
|
||||
impl Drop for Guard {
|
||||
fn drop(&mut self) {
|
||||
let _ = env::remove_var("NYASH_JOINIR_STRICT");
|
||||
}
|
||||
}
|
||||
Guard
|
||||
}
|
||||
|
||||
fn create_test_function() -> MirFunction {
|
||||
let signature = FunctionSignature {
|
||||
name: "value_join_demo_if2".to_string(),
|
||||
params: vec![],
|
||||
return_type: MirType::Integer,
|
||||
effects: EffectMask::PURE,
|
||||
};
|
||||
MirFunction::new(signature, BasicBlockId(0))
|
||||
}
|
||||
|
||||
fn build_demo_if2_valuejoin_frag() -> DemoIf2 {
|
||||
let mut function = create_test_function();
|
||||
let header = BasicBlockId(0);
|
||||
let then_bb = BasicBlockId(1);
|
||||
let else_bb = BasicBlockId(2);
|
||||
let join_bb = BasicBlockId(3);
|
||||
function.add_block(BasicBlock::new(then_bb));
|
||||
function.add_block(BasicBlock::new(else_bb));
|
||||
function.add_block(BasicBlock::new(join_bb));
|
||||
|
||||
let cond = ValueId(10);
|
||||
let then_val = ValueId(11);
|
||||
let else_val = ValueId(12);
|
||||
let expr_param = ValueId(100);
|
||||
|
||||
let branch = BranchStub {
|
||||
from: header,
|
||||
cond,
|
||||
then_target: then_bb,
|
||||
then_args: EdgeArgs {
|
||||
layout: JumpArgsLayout::CarriersOnly,
|
||||
values: vec![],
|
||||
},
|
||||
else_target: else_bb,
|
||||
else_args: EdgeArgs {
|
||||
layout: JumpArgsLayout::CarriersOnly,
|
||||
values: vec![],
|
||||
},
|
||||
};
|
||||
|
||||
let wires = vec![
|
||||
EdgeStub {
|
||||
from: then_bb,
|
||||
kind: ExitKind::Normal,
|
||||
target: Some(join_bb),
|
||||
args: EdgeArgs {
|
||||
layout: JumpArgsLayout::ExprResultPlusCarriers,
|
||||
values: vec![then_val],
|
||||
},
|
||||
},
|
||||
EdgeStub {
|
||||
from: else_bb,
|
||||
kind: ExitKind::Normal,
|
||||
target: Some(join_bb),
|
||||
args: EdgeArgs {
|
||||
layout: JumpArgsLayout::ExprResultPlusCarriers,
|
||||
values: vec![else_val],
|
||||
},
|
||||
},
|
||||
EdgeStub {
|
||||
from: join_bb,
|
||||
kind: ExitKind::Return,
|
||||
target: None,
|
||||
args: EdgeArgs {
|
||||
layout: JumpArgsLayout::CarriersOnly,
|
||||
values: vec![expr_param],
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
let mut block_params = BTreeMap::new();
|
||||
block_params.insert(
|
||||
join_bb,
|
||||
BlockParams {
|
||||
layout: JumpArgsLayout::ExprResultPlusCarriers,
|
||||
params: vec![expr_param],
|
||||
},
|
||||
);
|
||||
|
||||
let frag = Frag {
|
||||
entry: header,
|
||||
block_params,
|
||||
exits: BTreeMap::new(),
|
||||
wires,
|
||||
branches: vec![branch],
|
||||
};
|
||||
|
||||
DemoIf2 {
|
||||
frag,
|
||||
function,
|
||||
then_bb,
|
||||
else_bb,
|
||||
join_bb,
|
||||
expr_param,
|
||||
then_val,
|
||||
else_val,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demo_if2_valuejoin_emits_phi_and_return() {
|
||||
let _guard = strict_env_guard();
|
||||
let mut demo = build_demo_if2_valuejoin_frag();
|
||||
|
||||
emit_frag(&mut demo.function, &demo.frag)
|
||||
.expect("emit_frag should succeed");
|
||||
|
||||
let join_block = demo
|
||||
.function
|
||||
.get_block(demo.join_bb)
|
||||
.expect("join block exists");
|
||||
|
||||
let phi = join_block
|
||||
.instructions
|
||||
.iter()
|
||||
.find(|inst| matches!(inst, MirInstruction::Phi { dst, .. } if *dst == demo.expr_param))
|
||||
.expect("phi should be inserted at join");
|
||||
|
||||
match phi {
|
||||
MirInstruction::Phi { inputs, .. } => {
|
||||
assert_eq!(
|
||||
inputs,
|
||||
&vec![(demo.then_bb, demo.then_val), (demo.else_bb, demo.else_val)]
|
||||
);
|
||||
}
|
||||
_ => unreachable!("phi matcher ensured MirInstruction::Phi"),
|
||||
}
|
||||
|
||||
match &join_block.terminator {
|
||||
Some(MirInstruction::Return { value }) => {
|
||||
assert_eq!(*value, Some(demo.expr_param));
|
||||
}
|
||||
other => panic!("Expected Return terminator, got {:?}", other),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user