phase29ao(p52): split-scan v0 reject + adopt gating
This commit is contained in:
@ -606,4 +606,54 @@ mod tests {
|
||||
try_compose_core_loop_v0(&mut builder, &canonical, &ctx).expect("Ok");
|
||||
assert!(composed.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn coreloop_v0_split_scan_rejects_value_join_direct() {
|
||||
let condition = ASTNode::Literal {
|
||||
value: LiteralValue::Bool(true),
|
||||
span: Span::unknown(),
|
||||
};
|
||||
let features = LoopFeatureFacts {
|
||||
value_join: Some(ValueJoinFacts { needed: true }),
|
||||
..LoopFeatureFacts::default()
|
||||
};
|
||||
let facts = LoopFacts {
|
||||
condition_shape: ConditionShape::Unknown,
|
||||
step_shape: StepShape::Unknown,
|
||||
skeleton: SkeletonFacts {
|
||||
kind: SkeletonKind::Loop,
|
||||
},
|
||||
features,
|
||||
scan_with_init: None,
|
||||
split_scan: Some(crate::mir::builder::control_flow::plan::facts::loop_facts::SplitScanFacts {
|
||||
s_var: "s".to_string(),
|
||||
sep_var: "sep".to_string(),
|
||||
result_var: "result".to_string(),
|
||||
i_var: "i".to_string(),
|
||||
start_var: "start".to_string(),
|
||||
shape: SplitScanShape::Minimal,
|
||||
}),
|
||||
pattern1_simplewhile: None,
|
||||
pattern3_ifphi: None,
|
||||
pattern4_continue: None,
|
||||
pattern5_infinite_early_exit: None,
|
||||
pattern8_bool_predicate_scan: None,
|
||||
pattern9_accum_const_loop: None,
|
||||
pattern2_break: None,
|
||||
pattern2_loopbodylocal: None,
|
||||
};
|
||||
let canonical = canonicalize_loop_facts(facts);
|
||||
let mut builder = MirBuilder::new();
|
||||
builder.enter_function_for_test("coreloop_v0_split_scan_join_direct".to_string());
|
||||
let ctx = LoopPatternContext::new(
|
||||
&condition,
|
||||
&[],
|
||||
"coreloop_v0_split_scan_join_direct",
|
||||
false,
|
||||
false,
|
||||
);
|
||||
let composed =
|
||||
try_compose_core_loop_v0_split_scan(&mut builder, &canonical, &ctx).expect("Ok");
|
||||
assert!(composed.is_none());
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,26 +12,7 @@ use crate::mir::builder::control_flow::plan::{
|
||||
};
|
||||
use crate::mir::builder::MirBuilder;
|
||||
|
||||
pub(in crate::mir::builder) fn try_compose_core_loop_v1(
|
||||
builder: &mut MirBuilder,
|
||||
facts: &CanonicalLoopFacts,
|
||||
ctx: &LoopPatternContext,
|
||||
) -> Result<Option<CorePlan>, String> {
|
||||
if let Some(core) = try_compose_core_loop_v1_pattern2_break(builder, facts, ctx)? {
|
||||
return Ok(Some(core));
|
||||
}
|
||||
if let Some(core) = try_compose_core_loop_v1_pattern5_infinite_early_exit(
|
||||
builder, facts, ctx,
|
||||
)? {
|
||||
return Ok(Some(core));
|
||||
}
|
||||
if let Some(core) = try_compose_core_loop_v1_pattern3_ifphi(builder, facts, ctx)? {
|
||||
return Ok(Some(core));
|
||||
}
|
||||
try_compose_core_loop_v1_split_scan(builder, facts, ctx)
|
||||
}
|
||||
|
||||
fn try_compose_core_loop_v1_split_scan(
|
||||
pub(in crate::mir::builder) fn try_compose_core_loop_v1_split_scan(
|
||||
builder: &mut MirBuilder,
|
||||
facts: &CanonicalLoopFacts,
|
||||
ctx: &LoopPatternContext,
|
||||
@ -148,7 +129,11 @@ pub(in crate::mir::builder) fn try_compose_core_loop_v1_pattern3_ifphi(
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::try_compose_core_loop_v1;
|
||||
use super::{
|
||||
try_compose_core_loop_v1_pattern2_break, try_compose_core_loop_v1_pattern3_ifphi,
|
||||
try_compose_core_loop_v1_pattern5_infinite_early_exit,
|
||||
try_compose_core_loop_v1_split_scan,
|
||||
};
|
||||
use crate::ast::{ASTNode, BinaryOperator, LiteralValue, Span};
|
||||
use crate::mir::builder::control_flow::plan::facts::feature_facts::{
|
||||
CleanupFacts, CleanupKindFacts, ExitKindFacts, ExitMapFacts, LoopFeatureFacts,
|
||||
@ -251,7 +236,7 @@ mod tests {
|
||||
let ctx =
|
||||
LoopPatternContext::new(&condition, &[], "coreloop_v1_split_scan", false, false);
|
||||
let composed =
|
||||
try_compose_core_loop_v1(&mut builder, &canonical, &ctx).expect("Ok");
|
||||
try_compose_core_loop_v1_split_scan(&mut builder, &canonical, &ctx).expect("Ok");
|
||||
assert!(matches!(composed, Some(crate::mir::builder::control_flow::plan::CorePlan::Loop(_))));
|
||||
}
|
||||
|
||||
@ -292,7 +277,7 @@ mod tests {
|
||||
let ctx =
|
||||
LoopPatternContext::new(&condition, &[], "coreloop_v1_split_scan_no_join", false, false);
|
||||
let composed =
|
||||
try_compose_core_loop_v1(&mut builder, &canonical, &ctx).expect("Ok");
|
||||
try_compose_core_loop_v1_split_scan(&mut builder, &canonical, &ctx).expect("Ok");
|
||||
assert!(composed.is_none());
|
||||
}
|
||||
|
||||
@ -345,7 +330,7 @@ mod tests {
|
||||
false,
|
||||
);
|
||||
let composed =
|
||||
try_compose_core_loop_v1(&mut builder, &canonical, &ctx).expect("Ok");
|
||||
try_compose_core_loop_v1_split_scan(&mut builder, &canonical, &ctx).expect("Ok");
|
||||
assert!(composed.is_none());
|
||||
}
|
||||
|
||||
@ -422,7 +407,8 @@ mod tests {
|
||||
let ctx =
|
||||
LoopPatternContext::new(&loop_condition, &[], "coreloop_v1_pattern2", false, false);
|
||||
let composed =
|
||||
try_compose_core_loop_v1(&mut builder, &canonical, &ctx).expect("Ok");
|
||||
try_compose_core_loop_v1_pattern2_break(&mut builder, &canonical, &ctx)
|
||||
.expect("Ok");
|
||||
assert!(matches!(composed, Some(crate::mir::builder::control_flow::plan::CorePlan::Loop(_))));
|
||||
}
|
||||
|
||||
@ -476,7 +462,8 @@ mod tests {
|
||||
false,
|
||||
);
|
||||
let composed =
|
||||
try_compose_core_loop_v1(&mut builder, &canonical, &ctx).expect("Ok");
|
||||
try_compose_core_loop_v1_pattern2_break(&mut builder, &canonical, &ctx)
|
||||
.expect("Ok");
|
||||
assert!(composed.is_none());
|
||||
}
|
||||
|
||||
@ -551,7 +538,10 @@ mod tests {
|
||||
let ctx =
|
||||
LoopPatternContext::new(&condition, &[], "coreloop_v1_pattern5", false, false);
|
||||
let composed =
|
||||
try_compose_core_loop_v1(&mut builder, &canonical, &ctx).expect("Ok");
|
||||
try_compose_core_loop_v1_pattern5_infinite_early_exit(
|
||||
&mut builder, &canonical, &ctx,
|
||||
)
|
||||
.expect("Ok");
|
||||
assert!(matches!(composed, Some(crate::mir::builder::control_flow::plan::CorePlan::Loop(_))));
|
||||
}
|
||||
|
||||
@ -605,7 +595,10 @@ mod tests {
|
||||
false,
|
||||
);
|
||||
let composed =
|
||||
try_compose_core_loop_v1(&mut builder, &canonical, &ctx).expect("Ok");
|
||||
try_compose_core_loop_v1_pattern5_infinite_early_exit(
|
||||
&mut builder, &canonical, &ctx,
|
||||
)
|
||||
.expect("Ok");
|
||||
assert!(composed.is_none());
|
||||
}
|
||||
|
||||
@ -688,7 +681,8 @@ mod tests {
|
||||
let ctx =
|
||||
LoopPatternContext::new(&condition, &[], "coreloop_v1_pattern3", false, false);
|
||||
let composed =
|
||||
try_compose_core_loop_v1(&mut builder, &canonical, &ctx).expect("Ok");
|
||||
try_compose_core_loop_v1_pattern3_ifphi(&mut builder, &canonical, &ctx)
|
||||
.expect("Ok");
|
||||
assert!(matches!(composed, Some(crate::mir::builder::control_flow::plan::CorePlan::Loop(_))));
|
||||
}
|
||||
|
||||
@ -742,7 +736,8 @@ mod tests {
|
||||
false,
|
||||
);
|
||||
let composed =
|
||||
try_compose_core_loop_v1(&mut builder, &canonical, &ctx).expect("Ok");
|
||||
try_compose_core_loop_v1_pattern3_ifphi(&mut builder, &canonical, &ctx)
|
||||
.expect("Ok");
|
||||
assert!(composed.is_none());
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,10 +3,9 @@
|
||||
use super::coreloop_v0::{
|
||||
try_compose_core_loop_v0_scan_with_init, try_compose_core_loop_v0_split_scan,
|
||||
};
|
||||
use super::coreloop_v1::try_compose_core_loop_v1;
|
||||
use super::coreloop_v1::{
|
||||
try_compose_core_loop_v1_pattern2_break, try_compose_core_loop_v1_pattern3_ifphi,
|
||||
try_compose_core_loop_v1_pattern5_infinite_early_exit,
|
||||
try_compose_core_loop_v1_pattern5_infinite_early_exit, try_compose_core_loop_v1_split_scan,
|
||||
};
|
||||
use super::PlanNormalizer;
|
||||
use crate::mir::builder::control_flow::joinir::patterns::router::LoopPatternContext;
|
||||
@ -105,7 +104,7 @@ pub(in crate::mir::builder) fn try_release_adopt_core_plan_for_pattern7_split_sc
|
||||
}
|
||||
|
||||
let composed = if facts.value_join_needed {
|
||||
try_compose_core_loop_v1(builder, facts, ctx)
|
||||
try_compose_core_loop_v1_split_scan(builder, facts, ctx)
|
||||
} else {
|
||||
try_compose_core_loop_v0_split_scan(builder, facts, ctx)
|
||||
};
|
||||
@ -394,11 +393,11 @@ pub(in crate::mir::builder) fn try_shadow_adopt_core_plan(
|
||||
return Err("pattern7 strict/dev adopt failed: facts mismatch".to_string());
|
||||
}
|
||||
let core_plan = if facts.value_join_needed {
|
||||
try_compose_core_loop_v1(builder, facts, ctx)?
|
||||
try_compose_core_loop_v1_split_scan(builder, facts, ctx)?
|
||||
} else {
|
||||
try_compose_core_loop_v0_split_scan(builder, facts, ctx)?
|
||||
}
|
||||
.ok_or_else(|| "pattern7 strict/dev adopt failed: compose rejected".to_string())?;
|
||||
.ok_or_else(|| "pattern7 strict/dev adopt failed: compose rejected".to_string())?;
|
||||
Ok(Some(ShadowAdoptOutcome {
|
||||
core_plan,
|
||||
tag: "[coreplan/shadow_adopt:pattern7_split_scan]",
|
||||
|
||||
Reference in New Issue
Block a user