feat(mir): Phase 25.1g完了 - ControlForm導線追加(Rust側)
**実装内容**: - ✅ Task G-1: If PHI wrapper (`merge_modified_with_control`) 追加 - ✅ Task G-2: Exit PHI wrapper (`build_exit_phis_for_control`) 追加 - ✅ 既存実装へのTODO/NOTEコメント追加(将来の統合導線確立) **変更ファイル**: - src/mir/phi_core/if_phi.rs: merge_modified_with_control() 追加 - src/mir/phi_core/loopform_builder.rs: build_exit_phis_for_control() 追加 - src/mir/loop_builder.rs: TODO/NOTEコメント追加(2箇所) **テスト結果**: - ✅ mir_stage1_using_resolver_min_fragment_verifies - ✅ mir_stage1_using_resolver_full_collect_entries_verifies - ✅ mir_stageb_loop_break_continue (2 tests) - ✅ mir_loopform_exit_phi (4 tests) - ⚠️ test_stageb_min.sh Test2は既知の問題(Phase 25.1g前から) **設計方針**: - Thin wrapper pattern: ControlFormを受け取り既存実装に委譲 - 挙動変更なし: SSA/PHI生成ロジックは完全に既存のまま - 観測のみ: NYASH_IF_TRACE/NYASH_LOOPFORM_DEBUGでControlForm使用をログ - 段階移行準備: 将来の統合時に切り替え導線が明確 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -368,6 +368,10 @@ impl<'a> LoopBuilder<'a> {
|
||||
// Exit block
|
||||
self.set_current_block(exit_id)?;
|
||||
|
||||
// NOTE(25.1g+): ControlForm 統合後は build_exit_phis_for_control(...) 経由で
|
||||
// LoopShape から exit_id/branch_source_block を決める導線に寄せる予定。
|
||||
// 現在は既存実装のまま(挙動変更なし)。
|
||||
|
||||
// Build exit PHIs for break statements
|
||||
let exit_snaps = self.exit_snapshots.clone();
|
||||
loopform.build_exit_phis(self, exit_id, branch_source_block, &exit_snaps)?;
|
||||
@ -1176,6 +1180,10 @@ impl<'a> LoopBuilder<'a> {
|
||||
// Reset to pre-if snapshot, then delegate to shared helper
|
||||
self.parent_builder.variable_map = pre_if_var_map.clone();
|
||||
let mut ops = Ops(self);
|
||||
|
||||
// TODO(25.1g+): ControlForm 統合版に切り替えるときは、
|
||||
// IfShape から ControlForm を渡して merge_modified_with_control() を呼ぶ。
|
||||
// 現在は既存実装のまま(挙動変更なし)。
|
||||
crate::mir::phi_core::if_phi::merge_modified_at_merge_with(
|
||||
&mut ops,
|
||||
merge_bb,
|
||||
|
||||
@ -241,3 +241,55 @@ pub fn merge_with_reset_at_merge_with<O: PhiMergeOps>(
|
||||
skip_var,
|
||||
)
|
||||
}
|
||||
|
||||
/// Phase 25.1g: ControlForm-based wrapper for If PHI generation.
|
||||
/// This provides a thin adapter layer that accepts ControlForm and delegates
|
||||
/// to the existing merge_modified_at_merge_with implementation.
|
||||
///
|
||||
/// **Important**: This does NOT change any PHI generation logic - it merely
|
||||
/// provides a ControlForm-based entry point while preserving existing behavior.
|
||||
pub fn merge_modified_with_control<O: PhiMergeOps>(
|
||||
ops: &mut O,
|
||||
form: &crate::mir::control_form::ControlForm,
|
||||
pre_if_snapshot: &HashMap<String, ValueId>,
|
||||
then_map_end: &HashMap<String, ValueId>,
|
||||
else_map_end_opt: &Option<HashMap<String, ValueId>>,
|
||||
skip_var: Option<&str>,
|
||||
// Existing implementation requires pred info, so we accept it as parameters
|
||||
then_pred_opt: Option<crate::mir::BasicBlockId>,
|
||||
else_pred_opt: Option<crate::mir::BasicBlockId>,
|
||||
) -> Result<(), String> {
|
||||
use crate::mir::control_form::ControlKind;
|
||||
|
||||
// Only process If structures; silently succeed for other control kinds
|
||||
let shape = match &form.kind {
|
||||
ControlKind::If(shape) => shape,
|
||||
_ => return Ok(()),
|
||||
};
|
||||
|
||||
// Extract merge_bb from IfShape
|
||||
let merge_bb = shape.merge_block;
|
||||
|
||||
// Log ControlForm usage when trace is enabled
|
||||
let trace = std::env::var("NYASH_IF_TRACE").ok().as_deref() == Some("1");
|
||||
if trace {
|
||||
eprintln!(
|
||||
"[if-phi/control-form] Using ControlForm wrapper: merge={:?} then={:?} else={:?}",
|
||||
merge_bb, shape.then_block, shape.else_block
|
||||
);
|
||||
}
|
||||
|
||||
// Delegate to existing implementation - no behavioral changes
|
||||
merge_modified_at_merge_with(
|
||||
ops,
|
||||
merge_bb,
|
||||
shape.then_block,
|
||||
shape.else_block.unwrap_or(shape.then_block),
|
||||
then_pred_opt,
|
||||
else_pred_opt,
|
||||
pre_if_snapshot,
|
||||
then_map_end,
|
||||
else_map_end_opt,
|
||||
skip_var,
|
||||
)
|
||||
}
|
||||
|
||||
@ -479,6 +479,44 @@ fn sanitize_phi_inputs(inputs: &mut Vec<(BasicBlockId, ValueId)>) {
|
||||
*inputs = vec;
|
||||
}
|
||||
|
||||
/// Phase 25.1g: ControlForm-based wrapper for LoopForm Exit PHI generation.
|
||||
/// This provides a thin adapter layer that accepts ControlForm and delegates
|
||||
/// to the existing LoopFormBuilder::build_exit_phis implementation.
|
||||
///
|
||||
/// **Important**: This does NOT change any PHI generation logic - it merely
|
||||
/// provides a ControlForm-based entry point while preserving existing behavior.
|
||||
pub fn build_exit_phis_for_control<O: LoopFormOps>(
|
||||
loopform: &LoopFormBuilder,
|
||||
ops: &mut O,
|
||||
form: &crate::mir::control_form::ControlForm,
|
||||
exit_snapshots: &[(crate::mir::BasicBlockId, std::collections::HashMap<String, crate::mir::ValueId>)],
|
||||
// Existing implementation requires branch_source_block, so we accept it as a parameter
|
||||
branch_source_block: crate::mir::BasicBlockId,
|
||||
) -> Result<(), String> {
|
||||
use crate::mir::control_form::ControlKind;
|
||||
|
||||
// Only process Loop structures; silently succeed for other control kinds
|
||||
let shape = match &form.kind {
|
||||
ControlKind::Loop(shape) => shape,
|
||||
_ => return Ok(()),
|
||||
};
|
||||
|
||||
// Extract exit_id from LoopShape
|
||||
let exit_id = shape.exit;
|
||||
|
||||
// Log ControlForm usage when trace is enabled
|
||||
let trace = std::env::var("NYASH_LOOPFORM_DEBUG").ok().is_some();
|
||||
if trace {
|
||||
eprintln!(
|
||||
"[loopform/exit-phi/control-form] Using ControlForm wrapper: exit={:?} branch_source={:?}",
|
||||
exit_id, branch_source_block
|
||||
);
|
||||
}
|
||||
|
||||
// Delegate to existing implementation - no behavioral changes
|
||||
loopform.build_exit_phis(ops, exit_id, branch_source_block, exit_snapshots)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
Reference in New Issue
Block a user