phase29an(p13): add cleanup facts scaffold and projections
This commit is contained in:
@ -23,6 +23,18 @@ pub(in crate::mir::builder) struct ExitMapFacts {
|
||||
pub kinds_present: BTreeSet<ExitKindFacts>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub(in crate::mir::builder) enum CleanupKindFacts {
|
||||
Return,
|
||||
Break,
|
||||
Continue,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub(in crate::mir::builder) struct CleanupFacts {
|
||||
pub kinds_present: BTreeSet<CleanupKindFacts>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq)]
|
||||
pub(in crate::mir::builder) struct LoopFeatureFacts {
|
||||
pub exit_usage: ExitUsageFacts,
|
||||
@ -34,8 +46,6 @@ pub(in crate::mir::builder) struct LoopFeatureFacts {
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub(in crate::mir::builder) struct ValueJoinFacts;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub(in crate::mir::builder) struct CleanupFacts;
|
||||
|
||||
pub(in crate::mir::builder) fn try_extract_loop_feature_facts(
|
||||
body: &[ASTNode],
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use crate::mir::builder::control_flow::plan::facts::feature_facts::{
|
||||
ExitKindFacts, ExitUsageFacts,
|
||||
CleanupKindFacts, ExitKindFacts, ExitUsageFacts,
|
||||
};
|
||||
use crate::mir::builder::control_flow::plan::facts::skeleton_facts::SkeletonKind;
|
||||
use crate::mir::builder::control_flow::plan::facts::LoopFacts;
|
||||
@ -15,6 +15,7 @@ pub(in crate::mir::builder) struct CanonicalLoopFacts {
|
||||
pub skeleton_kind: SkeletonKind,
|
||||
pub exit_usage: ExitUsageFacts,
|
||||
pub exit_kinds_present: BTreeSet<ExitKindFacts>,
|
||||
pub cleanup_kinds_present: BTreeSet<CleanupKindFacts>,
|
||||
}
|
||||
|
||||
pub(in crate::mir::builder) fn canonicalize_loop_facts(facts: LoopFacts) -> CanonicalLoopFacts {
|
||||
@ -27,6 +28,12 @@ pub(in crate::mir::builder) fn canonicalize_loop_facts(facts: LoopFacts) -> Cano
|
||||
.as_ref()
|
||||
.map(|map| map.kinds_present.clone())
|
||||
.unwrap_or_default(),
|
||||
cleanup_kinds_present: facts
|
||||
.features
|
||||
.cleanup
|
||||
.as_ref()
|
||||
.map(|cleanup| cleanup.kinds_present.clone())
|
||||
.unwrap_or_default(),
|
||||
facts,
|
||||
}
|
||||
}
|
||||
@ -36,7 +43,8 @@ mod tests {
|
||||
use super::canonicalize_loop_facts;
|
||||
use crate::ast::{ASTNode, BinaryOperator, LiteralValue, Span};
|
||||
use crate::mir::builder::control_flow::plan::facts::feature_facts::{
|
||||
ExitKindFacts, ExitMapFacts, ExitUsageFacts, LoopFeatureFacts,
|
||||
CleanupFacts, CleanupKindFacts, ExitKindFacts, ExitMapFacts, ExitUsageFacts,
|
||||
LoopFeatureFacts,
|
||||
};
|
||||
use crate::mir::builder::control_flow::plan::facts::loop_facts::LoopFacts;
|
||||
use crate::mir::builder::control_flow::plan::facts::scan_shapes::{
|
||||
@ -65,6 +73,8 @@ mod tests {
|
||||
kinds_present.insert(ExitKindFacts::Break);
|
||||
kinds_present.insert(ExitKindFacts::Continue);
|
||||
kinds_present.insert(ExitKindFacts::Return);
|
||||
let mut cleanup_kinds_present = BTreeSet::new();
|
||||
cleanup_kinds_present.insert(CleanupKindFacts::Return);
|
||||
let facts = LoopFacts {
|
||||
condition_shape: ConditionShape::Unknown,
|
||||
step_shape: StepShape::Unknown,
|
||||
@ -79,7 +89,9 @@ mod tests {
|
||||
},
|
||||
exit_map: Some(ExitMapFacts { kinds_present }),
|
||||
value_join: None,
|
||||
cleanup: None,
|
||||
cleanup: Some(CleanupFacts {
|
||||
kinds_present: cleanup_kinds_present,
|
||||
}),
|
||||
},
|
||||
scan_with_init: None,
|
||||
split_scan: None,
|
||||
@ -101,6 +113,10 @@ mod tests {
|
||||
assert!(canonical.exit_kinds_present.contains(&ExitKindFacts::Break));
|
||||
assert!(canonical.exit_kinds_present.contains(&ExitKindFacts::Continue));
|
||||
assert!(canonical.exit_kinds_present.contains(&ExitKindFacts::Return));
|
||||
assert_eq!(canonical.cleanup_kinds_present.len(), 1);
|
||||
assert!(canonical
|
||||
.cleanup_kinds_present
|
||||
.contains(&CleanupKindFacts::Return));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -125,6 +141,7 @@ mod tests {
|
||||
};
|
||||
let canonical = canonicalize_loop_facts(facts);
|
||||
assert!(canonical.exit_kinds_present.is_empty());
|
||||
assert!(canonical.cleanup_kinds_present.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
use crate::ast::ASTNode;
|
||||
|
||||
use crate::mir::builder::control_flow::plan::facts::feature_facts::{
|
||||
ExitKindFacts, ExitUsageFacts,
|
||||
CleanupKindFacts, ExitKindFacts, ExitUsageFacts,
|
||||
};
|
||||
use crate::mir::builder::control_flow::plan::facts::skeleton_facts::SkeletonKind;
|
||||
use crate::mir::builder::control_flow::plan::normalize::CanonicalLoopFacts;
|
||||
@ -62,6 +62,10 @@ pub(in crate::mir::builder) fn build_plan_from_facts_ctx(
|
||||
|
||||
let _skeleton_kind = infer_skeleton_kind(&facts);
|
||||
let _exit_usage = infer_exit_usage(&facts);
|
||||
debug_assert_cleanup_kinds_match_exit_kinds(
|
||||
&facts.cleanup_kinds_present,
|
||||
&facts.exit_kinds_present,
|
||||
);
|
||||
|
||||
let mut candidates = CandidateSet::new();
|
||||
|
||||
@ -140,6 +144,31 @@ fn debug_assert_exit_usage_matches_plan(
|
||||
) {
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
fn debug_assert_cleanup_kinds_match_exit_kinds(
|
||||
cleanup_kinds_present: &BTreeSet<CleanupKindFacts>,
|
||||
exit_kinds_present: &BTreeSet<ExitKindFacts>,
|
||||
) {
|
||||
for cleanup_kind in cleanup_kinds_present {
|
||||
let exit_kind = match cleanup_kind {
|
||||
CleanupKindFacts::Return => ExitKindFacts::Return,
|
||||
CleanupKindFacts::Break => ExitKindFacts::Break,
|
||||
CleanupKindFacts::Continue => ExitKindFacts::Continue,
|
||||
};
|
||||
debug_assert!(
|
||||
exit_kinds_present.contains(&exit_kind),
|
||||
"cleanup kind requires matching exit kind presence"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
fn debug_assert_cleanup_kinds_match_exit_kinds(
|
||||
_cleanup_kinds_present: &BTreeSet<CleanupKindFacts>,
|
||||
_exit_kinds_present: &BTreeSet<ExitKindFacts>,
|
||||
) {
|
||||
}
|
||||
|
||||
fn push_scan_with_init(candidates: &mut CandidateSet, facts: &CanonicalLoopFacts) {
|
||||
let Some(scan) = &facts.facts.scan_with_init else {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user