phase29ao(p7): verify edgeargs layout for valuejoin (unconnected)
This commit is contained in:
@ -22,6 +22,7 @@ mod pattern9_accum_const_loop;
|
||||
mod pattern_scan_with_init;
|
||||
mod pattern_split_scan;
|
||||
mod skeleton_loop;
|
||||
mod value_join_args;
|
||||
mod common;
|
||||
|
||||
use super::{
|
||||
|
||||
@ -0,0 +1,17 @@
|
||||
use crate::mir::basic_block::EdgeArgs;
|
||||
use crate::mir::join_ir::lowering::inline_boundary::JumpArgsLayout;
|
||||
use crate::mir::ValueId;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub(super) fn expr_result_plus_carriers_args(
|
||||
expr_result: ValueId,
|
||||
carriers: Vec<ValueId>,
|
||||
) -> EdgeArgs {
|
||||
let mut values = Vec::with_capacity(1 + carriers.len());
|
||||
values.push(expr_result);
|
||||
values.extend(carriers);
|
||||
EdgeArgs {
|
||||
layout: JumpArgsLayout::ExprResultPlusCarriers,
|
||||
values,
|
||||
}
|
||||
}
|
||||
@ -23,7 +23,9 @@
|
||||
//! Phase 273 P3: V1 (Carrier completeness) removed with CoreCarrierInfo
|
||||
|
||||
use super::{CoreEffectPlan, CoreExitPlan, CoreIfPlan, CoreLoopPlan, CorePlan};
|
||||
use crate::mir::basic_block::EdgeArgs;
|
||||
use crate::mir::builder::control_flow::plan::normalize::CanonicalLoopFacts;
|
||||
use crate::mir::join_ir::lowering::inline_boundary::JumpArgsLayout;
|
||||
use crate::mir::ValueId;
|
||||
|
||||
/// Phase 273 P1: PlanVerifier - CorePlan 不変条件検証 (fail-fast)
|
||||
@ -152,6 +154,32 @@ impl PlanVerifier {
|
||||
Self::verify_value_id_basic(*val, depth, &format!("final_values[{}]", i))?;
|
||||
}
|
||||
|
||||
// Verify EdgeArgs layout (V13)
|
||||
for (i, wire) in loop_plan.frag.wires.iter().enumerate() {
|
||||
Self::verify_edge_args_layout(&wire.args, depth, &format!("frag.wires[{}]", i))?;
|
||||
}
|
||||
for (kind, stubs) in loop_plan.frag.exits.iter() {
|
||||
for (i, stub) in stubs.iter().enumerate() {
|
||||
Self::verify_edge_args_layout(
|
||||
&stub.args,
|
||||
depth,
|
||||
&format!("frag.exits[{}][{}]", kind, i),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
for (i, branch) in loop_plan.frag.branches.iter().enumerate() {
|
||||
Self::verify_edge_args_layout(
|
||||
&branch.then_args,
|
||||
depth,
|
||||
&format!("frag.branches[{}].then", i),
|
||||
)?;
|
||||
Self::verify_edge_args_layout(
|
||||
&branch.else_args,
|
||||
depth,
|
||||
&format!("frag.branches[{}].else", i),
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -331,6 +359,22 @@ impl PlanVerifier {
|
||||
let _ = (value_id, depth, context);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn verify_edge_args_layout(
|
||||
args: &EdgeArgs,
|
||||
depth: usize,
|
||||
context: &str,
|
||||
) -> Result<(), String> {
|
||||
if matches!(args.layout, JumpArgsLayout::ExprResultPlusCarriers)
|
||||
&& args.values.is_empty()
|
||||
{
|
||||
return Err(format!(
|
||||
"[V13] EdgeArgs at depth {} {} requires expr_result value",
|
||||
depth, context
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
@ -350,7 +394,8 @@ pub(in crate::mir::builder) fn debug_assert_value_join_invariants(_facts: &Canon
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::mir::{BasicBlockId, ConstValue, ValueId};
|
||||
use crate::mir::builder::control_flow::edgecfg::api::Frag;
|
||||
use crate::mir::basic_block::EdgeArgs;
|
||||
use crate::mir::builder::control_flow::edgecfg::api::{EdgeStub, ExitKind, Frag};
|
||||
use crate::mir::builder::control_flow::plan::CorePhiInfo;
|
||||
use crate::mir::builder::control_flow::plan::facts::feature_facts::{
|
||||
LoopFeatureFacts, ValueJoinFacts,
|
||||
@ -363,6 +408,7 @@ mod tests {
|
||||
SkeletonFacts, SkeletonKind,
|
||||
};
|
||||
use crate::mir::builder::control_flow::plan::normalize::canonicalize_loop_facts;
|
||||
use crate::mir::join_ir::lowering::inline_boundary::JumpArgsLayout;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
fn make_loop_plan(body: Vec<CorePlan>) -> CoreLoopPlan {
|
||||
@ -520,6 +566,41 @@ mod tests {
|
||||
assert!(result.unwrap_err().contains("[V11]"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_verify_expr_result_plus_carriers_requires_value() {
|
||||
let mut loop_plan = make_loop_plan(vec![]);
|
||||
loop_plan.frag.wires = vec![EdgeStub {
|
||||
from: loop_plan.body_bb,
|
||||
kind: ExitKind::Normal,
|
||||
target: Some(loop_plan.step_bb),
|
||||
args: EdgeArgs {
|
||||
layout: JumpArgsLayout::ExprResultPlusCarriers,
|
||||
values: vec![],
|
||||
},
|
||||
}];
|
||||
let plan = CorePlan::Loop(loop_plan);
|
||||
let result = PlanVerifier::verify(&plan);
|
||||
assert!(result.is_err());
|
||||
assert!(result.unwrap_err().contains("[V13]"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_verify_expr_result_plus_carriers_with_value_ok() {
|
||||
let mut loop_plan = make_loop_plan(vec![]);
|
||||
loop_plan.frag.wires = vec![EdgeStub {
|
||||
from: loop_plan.body_bb,
|
||||
kind: ExitKind::Normal,
|
||||
target: Some(loop_plan.step_bb),
|
||||
args: EdgeArgs {
|
||||
layout: JumpArgsLayout::ExprResultPlusCarriers,
|
||||
values: vec![ValueId(200)],
|
||||
},
|
||||
}];
|
||||
let plan = CorePlan::Loop(loop_plan);
|
||||
let result = PlanVerifier::verify(&plan);
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
fn debug_value_join_invariant_allows_empty_when_not_needed() {
|
||||
|
||||
Reference in New Issue
Block a user