phase29an(p7): add canonical projections for skeleton/features
This commit is contained in:
@ -2,13 +2,124 @@
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
use crate::mir::builder::control_flow::plan::facts::feature_facts::ExitUsageFacts;
|
||||
use crate::mir::builder::control_flow::plan::facts::skeleton_facts::SkeletonKind;
|
||||
use crate::mir::builder::control_flow::plan::facts::LoopFacts;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(in crate::mir::builder) struct CanonicalLoopFacts {
|
||||
pub facts: LoopFacts,
|
||||
pub skeleton_kind: SkeletonKind,
|
||||
pub exit_usage: ExitUsageFacts,
|
||||
}
|
||||
|
||||
pub(in crate::mir::builder) fn canonicalize_loop_facts(facts: LoopFacts) -> CanonicalLoopFacts {
|
||||
CanonicalLoopFacts { facts }
|
||||
CanonicalLoopFacts {
|
||||
skeleton_kind: facts.skeleton.kind,
|
||||
exit_usage: facts.features.exit_usage.clone(),
|
||||
facts,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::canonicalize_loop_facts;
|
||||
use crate::ast::{ASTNode, BinaryOperator, LiteralValue, Span};
|
||||
use crate::mir::builder::control_flow::plan::facts::loop_facts::LoopFacts;
|
||||
use crate::mir::builder::control_flow::plan::facts::scan_shapes::{
|
||||
ConditionShape, StepShape,
|
||||
};
|
||||
use crate::mir::builder::control_flow::plan::facts::skeleton_facts::SkeletonKind;
|
||||
|
||||
fn v(name: &str) -> ASTNode {
|
||||
ASTNode::Variable {
|
||||
name: name.to_string(),
|
||||
span: Span::unknown(),
|
||||
}
|
||||
}
|
||||
|
||||
fn lit_int(value: i64) -> ASTNode {
|
||||
ASTNode::Literal {
|
||||
value: LiteralValue::Integer(value),
|
||||
span: Span::unknown(),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn canonical_projects_skeleton_and_exit_usage() {
|
||||
let facts = LoopFacts {
|
||||
condition_shape: ConditionShape::Unknown,
|
||||
step_shape: StepShape::Unknown,
|
||||
skeleton: crate::mir::builder::control_flow::plan::facts::skeleton_facts::SkeletonFacts {
|
||||
kind: SkeletonKind::Loop,
|
||||
},
|
||||
features:
|
||||
crate::mir::builder::control_flow::plan::facts::feature_facts::LoopFeatureFacts {
|
||||
exit_usage:
|
||||
crate::mir::builder::control_flow::plan::facts::feature_facts::ExitUsageFacts {
|
||||
has_break: true,
|
||||
has_continue: true,
|
||||
has_return: true,
|
||||
},
|
||||
value_join: None,
|
||||
cleanup: None,
|
||||
},
|
||||
scan_with_init: None,
|
||||
split_scan: None,
|
||||
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);
|
||||
assert_eq!(canonical.skeleton_kind, SkeletonKind::Loop);
|
||||
assert!(canonical.exit_usage.has_break);
|
||||
assert!(canonical.exit_usage.has_continue);
|
||||
assert!(canonical.exit_usage.has_return);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn canonical_preserves_loop_facts_content() {
|
||||
let facts = LoopFacts {
|
||||
condition_shape: ConditionShape::Unknown,
|
||||
step_shape: StepShape::Unknown,
|
||||
skeleton: crate::mir::builder::control_flow::plan::facts::skeleton_facts::SkeletonFacts {
|
||||
kind: SkeletonKind::Loop,
|
||||
},
|
||||
features:
|
||||
crate::mir::builder::control_flow::plan::facts::feature_facts::LoopFeatureFacts::default(),
|
||||
scan_with_init: None,
|
||||
split_scan: None,
|
||||
pattern1_simplewhile: Some(
|
||||
crate::mir::builder::control_flow::plan::facts::pattern1_simplewhile_facts::Pattern1SimpleWhileFacts {
|
||||
loop_var: "i".to_string(),
|
||||
condition: ASTNode::BinaryOp {
|
||||
operator: BinaryOperator::Less,
|
||||
left: Box::new(v("i")),
|
||||
right: Box::new(lit_int(3)),
|
||||
span: Span::unknown(),
|
||||
},
|
||||
loop_increment: ASTNode::BinaryOp {
|
||||
operator: BinaryOperator::Add,
|
||||
left: Box::new(v("i")),
|
||||
right: Box::new(lit_int(1)),
|
||||
span: Span::unknown(),
|
||||
},
|
||||
},
|
||||
),
|
||||
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);
|
||||
assert!(canonical.facts.pattern1_simplewhile.is_some());
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ pub(in crate::mir::builder) fn build_plan_from_facts_ctx(
|
||||
// unreachable in normal execution today. We still implement the SSOT
|
||||
// boundary here so that future Facts work cannot drift.
|
||||
|
||||
match facts.facts.skeleton.kind {
|
||||
match facts.skeleton_kind {
|
||||
SkeletonKind::Loop => {}
|
||||
_ => return Ok(None),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user