phase29an(p4): require skeleton/features in loop facts
This commit is contained in:
@ -43,8 +43,8 @@ use super::feature_facts::{LoopFeatureFacts, try_extract_loop_feature_facts};
|
||||
pub(in crate::mir::builder) struct LoopFacts {
|
||||
pub condition_shape: ConditionShape,
|
||||
pub step_shape: StepShape,
|
||||
pub skeleton: Option<SkeletonFacts>,
|
||||
pub features: Option<LoopFeatureFacts>,
|
||||
pub skeleton: SkeletonFacts,
|
||||
pub features: LoopFeatureFacts,
|
||||
pub scan_with_init: Option<ScanWithInitFacts>,
|
||||
pub split_scan: Option<SplitScanFacts>,
|
||||
pub pattern1_simplewhile: Option<Pattern1SimpleWhileFacts>,
|
||||
@ -146,8 +146,15 @@ fn try_build_loop_facts_inner(
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let skeleton = try_extract_loop_skeleton_facts(condition, body)?;
|
||||
let features = Some(try_extract_loop_feature_facts(body)?);
|
||||
let skeleton = match try_extract_loop_skeleton_facts(condition, body)? {
|
||||
Some(skeleton) => skeleton,
|
||||
None => {
|
||||
return Err(Freeze::bug(
|
||||
"loop facts require skeleton when patterns are present",
|
||||
));
|
||||
}
|
||||
};
|
||||
let features = try_extract_loop_feature_facts(body)?;
|
||||
|
||||
Ok(Some(LoopFacts {
|
||||
condition_shape,
|
||||
@ -259,6 +266,56 @@ fn try_extract_step_shape(body: &[ASTNode]) -> Result<Option<StepShape>, Freeze>
|
||||
}))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{try_build_loop_facts, LoopFacts};
|
||||
use crate::ast::{ASTNode, BinaryOperator, LiteralValue, Span};
|
||||
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 loop_facts_require_skeleton_and_features_when_present() {
|
||||
let condition = ASTNode::BinaryOp {
|
||||
operator: BinaryOperator::Less,
|
||||
left: Box::new(v("i")),
|
||||
right: Box::new(lit_int(3)),
|
||||
span: Span::unknown(),
|
||||
};
|
||||
let body = vec![ASTNode::Assignment {
|
||||
target: Box::new(v("i")),
|
||||
value: Box::new(ASTNode::BinaryOp {
|
||||
operator: BinaryOperator::Add,
|
||||
left: Box::new(v("i")),
|
||||
right: Box::new(lit_int(1)),
|
||||
span: Span::unknown(),
|
||||
}),
|
||||
span: Span::unknown(),
|
||||
}];
|
||||
|
||||
let facts = try_build_loop_facts(&condition, &body)
|
||||
.expect("Ok")
|
||||
.expect("Some");
|
||||
assert_eq!(facts.skeleton.kind, SkeletonKind::Loop);
|
||||
assert!(!facts.features.exit_usage.has_break);
|
||||
assert!(!facts.features.exit_usage.has_continue);
|
||||
assert!(!facts.features.exit_usage.has_return);
|
||||
let _: LoopFacts = facts;
|
||||
}
|
||||
}
|
||||
|
||||
fn try_extract_scan_with_init_facts(
|
||||
body: &[ASTNode],
|
||||
condition_shape: &ConditionShape,
|
||||
|
||||
@ -70,15 +70,11 @@ pub(in crate::mir::builder) fn build_plan_from_facts_ctx(
|
||||
}
|
||||
|
||||
fn infer_skeleton_kind(facts: &CanonicalLoopFacts) -> Option<SkeletonKind> {
|
||||
facts.facts.skeleton.as_ref().map(|s| s.kind)
|
||||
Some(facts.facts.skeleton.kind)
|
||||
}
|
||||
|
||||
fn infer_exit_usage(facts: &CanonicalLoopFacts) -> Option<ExitUsageFacts> {
|
||||
facts
|
||||
.facts
|
||||
.features
|
||||
.as_ref()
|
||||
.map(|features| features.exit_usage.clone())
|
||||
Some(facts.facts.features.exit_usage.clone())
|
||||
}
|
||||
|
||||
fn push_scan_with_init(candidates: &mut CandidateSet, facts: &CanonicalLoopFacts) {
|
||||
@ -318,8 +314,10 @@ mod tests {
|
||||
let facts = LoopFacts {
|
||||
condition_shape: ConditionShape::Unknown,
|
||||
step_shape: StepShape::Unknown,
|
||||
skeleton: None,
|
||||
features: None,
|
||||
skeleton: SkeletonFacts {
|
||||
kind: SkeletonKind::Loop,
|
||||
},
|
||||
features: LoopFeatureFacts::default(),
|
||||
scan_with_init: None,
|
||||
split_scan: Some(SplitScanFacts {
|
||||
s_var: "s".to_string(),
|
||||
@ -357,8 +355,10 @@ mod tests {
|
||||
let facts = LoopFacts {
|
||||
condition_shape: ConditionShape::Unknown,
|
||||
step_shape: StepShape::Unknown,
|
||||
skeleton: None,
|
||||
features: None,
|
||||
skeleton: SkeletonFacts {
|
||||
kind: SkeletonKind::Loop,
|
||||
},
|
||||
features: LoopFeatureFacts::default(),
|
||||
scan_with_init: None,
|
||||
split_scan: None,
|
||||
pattern1_simplewhile: None,
|
||||
@ -380,8 +380,10 @@ mod tests {
|
||||
let facts = LoopFacts {
|
||||
condition_shape: ConditionShape::Unknown,
|
||||
step_shape: StepShape::Unknown,
|
||||
skeleton: None,
|
||||
features: None,
|
||||
skeleton: SkeletonFacts {
|
||||
kind: SkeletonKind::Loop,
|
||||
},
|
||||
features: LoopFeatureFacts::default(),
|
||||
scan_with_init: Some(ScanWithInitFacts {
|
||||
loop_var: "i".to_string(),
|
||||
haystack: "s".to_string(),
|
||||
@ -413,10 +415,10 @@ mod tests {
|
||||
let facts = LoopFacts {
|
||||
condition_shape: ConditionShape::Unknown,
|
||||
step_shape: StepShape::Unknown,
|
||||
skeleton: Some(SkeletonFacts {
|
||||
skeleton: SkeletonFacts {
|
||||
kind: SkeletonKind::Loop,
|
||||
}),
|
||||
features: Some(LoopFeatureFacts {
|
||||
},
|
||||
features: LoopFeatureFacts {
|
||||
exit_usage: ExitUsageFacts {
|
||||
has_break: true,
|
||||
has_continue: false,
|
||||
@ -424,7 +426,7 @@ mod tests {
|
||||
},
|
||||
value_join: None,
|
||||
cleanup: None,
|
||||
}),
|
||||
},
|
||||
scan_with_init: Some(ScanWithInitFacts {
|
||||
loop_var: "i".to_string(),
|
||||
haystack: "s".to_string(),
|
||||
@ -467,8 +469,10 @@ mod tests {
|
||||
let facts = LoopFacts {
|
||||
condition_shape: ConditionShape::Unknown,
|
||||
step_shape: StepShape::Unknown,
|
||||
skeleton: None,
|
||||
features: None,
|
||||
skeleton: SkeletonFacts {
|
||||
kind: SkeletonKind::Loop,
|
||||
},
|
||||
features: LoopFeatureFacts::default(),
|
||||
scan_with_init: None,
|
||||
split_scan: None,
|
||||
pattern1_simplewhile: Some(Pattern1SimpleWhileFacts {
|
||||
@ -531,8 +535,10 @@ mod tests {
|
||||
let facts = LoopFacts {
|
||||
condition_shape: ConditionShape::Unknown,
|
||||
step_shape: StepShape::Unknown,
|
||||
skeleton: None,
|
||||
features: None,
|
||||
skeleton: SkeletonFacts {
|
||||
kind: SkeletonKind::Loop,
|
||||
},
|
||||
features: LoopFeatureFacts::default(),
|
||||
scan_with_init: None,
|
||||
split_scan: None,
|
||||
pattern1_simplewhile: None,
|
||||
@ -594,8 +600,10 @@ mod tests {
|
||||
let facts = LoopFacts {
|
||||
condition_shape: ConditionShape::Unknown,
|
||||
step_shape: StepShape::Unknown,
|
||||
skeleton: None,
|
||||
features: None,
|
||||
skeleton: SkeletonFacts {
|
||||
kind: SkeletonKind::Loop,
|
||||
},
|
||||
features: LoopFeatureFacts::default(),
|
||||
scan_with_init: None,
|
||||
split_scan: None,
|
||||
pattern1_simplewhile: None,
|
||||
@ -643,8 +651,10 @@ mod tests {
|
||||
let facts = LoopFacts {
|
||||
condition_shape: ConditionShape::Unknown,
|
||||
step_shape: StepShape::Unknown,
|
||||
skeleton: None,
|
||||
features: None,
|
||||
skeleton: SkeletonFacts {
|
||||
kind: SkeletonKind::Loop,
|
||||
},
|
||||
features: LoopFeatureFacts::default(),
|
||||
scan_with_init: None,
|
||||
split_scan: None,
|
||||
pattern1_simplewhile: None,
|
||||
@ -693,8 +703,10 @@ mod tests {
|
||||
let facts = LoopFacts {
|
||||
condition_shape: ConditionShape::Unknown,
|
||||
step_shape: StepShape::Unknown,
|
||||
skeleton: None,
|
||||
features: None,
|
||||
skeleton: SkeletonFacts {
|
||||
kind: SkeletonKind::Loop,
|
||||
},
|
||||
features: LoopFeatureFacts::default(),
|
||||
scan_with_init: None,
|
||||
split_scan: None,
|
||||
pattern1_simplewhile: None,
|
||||
@ -751,8 +763,10 @@ mod tests {
|
||||
let facts = LoopFacts {
|
||||
condition_shape: ConditionShape::Unknown,
|
||||
step_shape: StepShape::Unknown,
|
||||
skeleton: None,
|
||||
features: None,
|
||||
skeleton: SkeletonFacts {
|
||||
kind: SkeletonKind::Loop,
|
||||
},
|
||||
features: LoopFeatureFacts::default(),
|
||||
scan_with_init: None,
|
||||
split_scan: None,
|
||||
pattern1_simplewhile: None,
|
||||
@ -815,8 +829,10 @@ mod tests {
|
||||
let facts = LoopFacts {
|
||||
condition_shape: ConditionShape::Unknown,
|
||||
step_shape: StepShape::Unknown,
|
||||
skeleton: None,
|
||||
features: None,
|
||||
skeleton: SkeletonFacts {
|
||||
kind: SkeletonKind::Loop,
|
||||
},
|
||||
features: LoopFeatureFacts::default(),
|
||||
scan_with_init: None,
|
||||
split_scan: None,
|
||||
pattern1_simplewhile: None,
|
||||
|
||||
Reference in New Issue
Block a user