feat(mir): Phase 25.1f完了 - Conservative PHI + ControlForm観測レイヤー

🎉 Conservative PHI Box理論による完全SSA構築

**Phase 7-B: Conservative PHI実装**
- 片方branchのみ定義変数に対応(emit_void使用)
- 全変数にPHI生成(Conservative Box理論)
- Stage-1 resolver全テスト緑化(3/3 PASS)

**Phase 25.1f: ControlForm観測レイヤー**
- LoopShape/IfShape/ControlForm構造定義
- Loop/If統一インターフェース実装
- debug_dump/debug_validate機能追加
- NYASH_CONTROL_FORM_TRACE環境変数対応

**主な変更**:
- src/mir/builder/phi.rs: Conservative PHI実装
- src/mir/control_form.rs: ControlForm構造(NEW)
- src/mir/loop_builder.rs: LoopForm v2デフォルト化

**テスト結果**:
 mir_stage1_using_resolver_min_fragment_verifies
 mir_stage1_using_resolver_full_collect_entries_verifies
 mir_parserbox_parse_program2_harness_parses_minimal_source

🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: ChatGPT <chatgpt@openai.com>
This commit is contained in:
nyash-codex
2025-11-18 18:56:35 +09:00
parent 8b37e9711d
commit d3cbc71c9b
81 changed files with 907 additions and 147 deletions

View File

@ -6,6 +6,7 @@
*/
use super::{BasicBlockId, ConstValue, MirInstruction, ValueId};
use crate::mir::control_form::{ControlForm, IfShape, LoopShape, is_control_form_trace_on};
use crate::mir::phi_core::loop_phi::IncompletePhi;
use crate::mir::phi_core::loopform_builder::{LoopFormBuilder, LoopFormOps};
use crate::ast::ASTNode;
@ -342,7 +343,6 @@ impl<'a> LoopBuilder<'a> {
// Jump to latch if not already terminated
let actual_latch_id = if !is_current_block_terminated(self.parent_builder)? {
let cur_body_end = self.current_block()?;
self.emit_jump(latch_id)?;
latch_id
} else {
@ -375,6 +375,38 @@ impl<'a> LoopBuilder<'a> {
// Pop loop context
crate::mir::builder::loops::pop_loop_context(self.parent_builder);
// ControlForm 観測: 環境フラグ未設定時は既定ONのとき LoopShape をダンプ
if is_control_form_trace_on() {
// continue / break のターゲットブロックをユニーク化して収集
use std::collections::HashSet;
let mut cont_set: HashSet<BasicBlockId> = HashSet::new();
let mut break_set: HashSet<BasicBlockId> = HashSet::new();
for (bb, _) in &self.continue_snapshots {
cont_set.insert(*bb);
}
for (bb, _) in &self.exit_snapshots {
break_set.insert(*bb);
}
let continue_targets: Vec<BasicBlockId> = cont_set.into_iter().collect();
let break_targets: Vec<BasicBlockId> = break_set.into_iter().collect();
let loop_shape = LoopShape {
preheader: preheader_id,
header: header_id,
body: body_id,
latch: latch_id,
exit: exit_id,
continue_targets,
break_targets,
};
let form = ControlForm::from_loop(loop_shape.clone());
form.debug_dump();
#[cfg(debug_assertions)]
if let Some(ref func) = self.parent_builder.current_function {
loop_shape.debug_validate(func);
}
}
// Return void value
let void_dst = self.new_value();
self.emit_const(void_dst, ConstValue::Void)?;
@ -486,7 +518,7 @@ impl<'a> LoopBuilder<'a> {
}
// Add PHI nodes for new pinned variables in header block
for (name, value, preheader_value) in new_pinned_vars {
for (name, _value, preheader_value) in new_pinned_vars {
let phi_id = self.new_value();
self.emit_phi_at_block_start(header_id, phi_id, vec![(preheader_id, preheader_value)])?;
// Update variable map to use PHI value
@ -1156,6 +1188,22 @@ impl<'a> LoopBuilder<'a> {
&else_var_map_end_opt,
None,
)?;
// ControlForm 観測: 環境フラグ未設定時は既定ONのとき IfShape をダンプ
if is_control_form_trace_on() {
let if_shape = IfShape {
cond_block: pre_branch_bb,
then_block: then_bb,
else_block: Some(else_bb),
merge_block: merge_bb,
};
let form = ControlForm::from_if(if_shape.clone());
form.debug_dump();
#[cfg(debug_assertions)]
if let Some(ref func) = self.parent_builder.current_function {
if_shape.debug_validate(func);
}
}
let void_id = self.new_value();
self.emit_const(void_id, ConstValue::Void)?;
// Pop merge debug region