2025-09-25 10:23:14 +09:00
|
|
|
|
/*!
|
|
|
|
|
|
* phi_core::common – shared types and invariants (scaffold)
|
|
|
|
|
|
*
|
|
|
|
|
|
* Phase 1 keeps this minimal; future phases may move debug asserts and
|
|
|
|
|
|
* predicate set checks here for both if/loop PHI normalization.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/// Placeholder for future shared PHI input type alias.
|
|
|
|
|
|
/// Using the same tuple form as MIR Phi instruction inputs.
|
|
|
|
|
|
pub type PhiInput = (crate::mir::BasicBlockId, crate::mir::ValueId);
|
|
|
|
|
|
|
|
|
|
|
|
#[cfg(debug_assertions)]
|
|
|
|
|
|
pub fn debug_verify_phi_inputs(
|
|
|
|
|
|
function: &crate::mir::MirFunction,
|
|
|
|
|
|
merge_bb: crate::mir::BasicBlockId,
|
|
|
|
|
|
inputs: &[(crate::mir::BasicBlockId, crate::mir::ValueId)],
|
|
|
|
|
|
) {
|
|
|
|
|
|
use std::collections::HashSet;
|
2025-11-01 15:23:28 +09:00
|
|
|
|
// Make a local, up-to-date view of CFG predecessors by rebuilding from successors.
|
|
|
|
|
|
// This avoids false positives when callers verify immediately after emitting terminators.
|
|
|
|
|
|
let mut func = function.clone();
|
|
|
|
|
|
func.update_cfg();
|
2025-09-25 10:23:14 +09:00
|
|
|
|
let mut seen = HashSet::new();
|
|
|
|
|
|
for (pred, _v) in inputs.iter() {
|
|
|
|
|
|
debug_assert_ne!(
|
|
|
|
|
|
*pred, merge_bb,
|
|
|
|
|
|
"PHI incoming predecessor must not be the merge block itself"
|
|
|
|
|
|
);
|
|
|
|
|
|
debug_assert!(
|
|
|
|
|
|
seen.insert(*pred),
|
|
|
|
|
|
"Duplicate PHI incoming predecessor detected: {:?}",
|
|
|
|
|
|
pred
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
2025-11-01 15:23:28 +09:00
|
|
|
|
if let Some(block) = func.blocks.get(&merge_bb) {
|
2025-09-25 10:23:14 +09:00
|
|
|
|
for (pred, _v) in inputs.iter() {
|
2025-11-01 15:23:28 +09:00
|
|
|
|
// Accept either declared predecessor or a direct successor edge pred -> merge_bb
|
|
|
|
|
|
let ok_pred = block.predecessors.contains(pred)
|
|
|
|
|
|
|| func
|
|
|
|
|
|
.blocks
|
|
|
|
|
|
.get(pred)
|
|
|
|
|
|
.map(|p| p.successors.contains(&merge_bb))
|
|
|
|
|
|
.unwrap_or(false);
|
|
|
|
|
|
if !ok_pred {
|
|
|
|
|
|
eprintln!(
|
|
|
|
|
|
"[phi-verify][warn] incoming pred {:?} is not a predecessor of merge bb {:?}",
|
|
|
|
|
|
pred, merge_bb
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
2025-09-25 10:23:14 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[cfg(not(debug_assertions))]
|
|
|
|
|
|
pub fn debug_verify_phi_inputs(
|
|
|
|
|
|
_function: &crate::mir::MirFunction,
|
|
|
|
|
|
_merge_bb: crate::mir::BasicBlockId,
|
|
|
|
|
|
_inputs: &[(crate::mir::BasicBlockId, crate::mir::ValueId)],
|
|
|
|
|
|
) {
|
|
|
|
|
|
}
|