Files
hakorune/src/mir/verification/ssa.rs
nyash-codex 3a82633924 refactor(funcscanner): Region+next_i パターン統一 & SSA テスト追加
**FuncScanner .hako 側改善**:
- scan_all_boxes を Region + next_i 形式に統一(continue 多発による SSA/PHI 複雑さ削減)
- インデント修正(タブ→スペース統一)
- デバッグ print 削除

**SSA テスト追加**:
- lang/src/compiler/tests/funcscanner_scan_methods_min.hako
- src/tests/mir_funcscanner_ssa.rs (scan_methods & fib_min SSA デバッグテスト)

**Phase 25.3 ドキュメント**:
- docs/development/roadmap/phases/phase-25.3-funcscanner/ 追加

**関連**: Phase 25.3 FuncScanner 箱化準備作業

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 06:38:43 +09:00

50 lines
1.9 KiB
Rust

use crate::mir::function::MirFunction;
use crate::mir::{ValueId};
use crate::mir::verification_types::VerificationError;
/// Verify SSA form: single assignment and all uses defined
pub fn check_ssa_form(function: &MirFunction) -> Result<(), Vec<VerificationError>> {
use std::collections::HashMap;
let mut errors = Vec::new();
let mut definitions: HashMap<ValueId, (crate::mir::BasicBlockId, usize)> = HashMap::new();
// Treat parameters as defined at the entry block.
for pid in &function.params {
definitions.insert(*pid, (function.entry_block, 0));
}
for (block_id, block) in &function.blocks {
for (inst_idx, instruction) in block.all_instructions().enumerate() {
if let Some(dst) = instruction.dst_value() {
if let Some((first_block, _)) = definitions.insert(dst, (*block_id, inst_idx)) {
errors.push(VerificationError::MultipleDefinition {
value: dst,
first_block,
second_block: *block_id,
});
}
}
}
}
for (block_id, block) in &function.blocks {
for (inst_idx, instruction) in block.all_instructions().enumerate() {
for used_value in instruction.used_values() {
if !definitions.contains_key(&used_value) {
eprintln!(
"[ssa-undef-debug] fn={} bb={:?} inst_idx={} used={:?} inst={:?}",
function.signature.name, block_id, inst_idx, used_value, instruction
);
errors.push(VerificationError::UndefinedValue {
value: used_value,
block: *block_id,
instruction_index: inst_idx,
});
}
}
}
}
if errors.is_empty() { Ok(()) } else { Err(errors) }
}