phase29an(p0): add skeleton facts ssot (no wiring)
This commit is contained in:
@ -36,11 +36,13 @@ use super::pattern2_break_facts::{Pattern2BreakFacts, try_extract_pattern2_break
|
||||
use super::pattern2_loopbodylocal_facts::{
|
||||
Pattern2LoopBodyLocalFacts, try_extract_pattern2_loopbodylocal_facts,
|
||||
};
|
||||
use super::skeleton_facts::{SkeletonFacts, try_extract_loop_skeleton_facts};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(in crate::mir::builder) struct LoopFacts {
|
||||
pub condition_shape: ConditionShape,
|
||||
pub step_shape: StepShape,
|
||||
pub skeleton: Option<SkeletonFacts>,
|
||||
pub scan_with_init: Option<ScanWithInitFacts>,
|
||||
pub split_scan: Option<SplitScanFacts>,
|
||||
pub pattern1_simplewhile: Option<Pattern1SimpleWhileFacts>,
|
||||
@ -128,23 +130,26 @@ fn try_build_loop_facts_inner(
|
||||
let pattern2_break = try_extract_pattern2_break_facts(condition, body)?;
|
||||
let pattern2_loopbodylocal = try_extract_pattern2_loopbodylocal_facts(condition, body)?;
|
||||
|
||||
if scan_with_init.is_none()
|
||||
&& split_scan.is_none()
|
||||
&& pattern1_simplewhile.is_none()
|
||||
&& pattern3_ifphi.is_none()
|
||||
&& pattern4_continue.is_none()
|
||||
&& pattern5_infinite_early_exit.is_none()
|
||||
&& pattern8_bool_predicate_scan.is_none()
|
||||
&& pattern9_accum_const_loop.is_none()
|
||||
&& pattern2_break.is_none()
|
||||
&& pattern2_loopbodylocal.is_none()
|
||||
{
|
||||
let has_any = scan_with_init.is_some()
|
||||
|| split_scan.is_some()
|
||||
|| pattern1_simplewhile.is_some()
|
||||
|| pattern3_ifphi.is_some()
|
||||
|| pattern4_continue.is_some()
|
||||
|| pattern5_infinite_early_exit.is_some()
|
||||
|| pattern8_bool_predicate_scan.is_some()
|
||||
|| pattern9_accum_const_loop.is_some()
|
||||
|| pattern2_break.is_some()
|
||||
|| pattern2_loopbodylocal.is_some();
|
||||
if !has_any {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let skeleton = try_extract_loop_skeleton_facts(condition, body)?;
|
||||
|
||||
Ok(Some(LoopFacts {
|
||||
condition_shape,
|
||||
step_shape,
|
||||
skeleton,
|
||||
scan_with_init,
|
||||
split_scan,
|
||||
pattern1_simplewhile,
|
||||
|
||||
@ -16,6 +16,7 @@ pub(in crate::mir::builder) mod pattern9_accum_const_loop_facts;
|
||||
pub(in crate::mir::builder) mod pattern2_break_facts;
|
||||
pub(in crate::mir::builder) mod pattern2_loopbodylocal_facts;
|
||||
pub(in crate::mir::builder) mod scan_shapes;
|
||||
pub(in crate::mir::builder) mod skeleton_facts;
|
||||
|
||||
pub(in crate::mir::builder) use loop_facts::{
|
||||
try_build_loop_facts, try_build_loop_facts_with_ctx, LoopFacts,
|
||||
|
||||
82
src/mir/builder/control_flow/plan/facts/skeleton_facts.rs
Normal file
82
src/mir/builder/control_flow/plan/facts/skeleton_facts.rs
Normal file
@ -0,0 +1,82 @@
|
||||
//! Phase 29an P0: SkeletonFacts SSOT (Loop/If/BranchN/StraightLine)
|
||||
|
||||
use crate::ast::ASTNode;
|
||||
use crate::mir::builder::control_flow::plan::planner::Freeze;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub(in crate::mir::builder) enum SkeletonKind {
|
||||
Loop,
|
||||
If2,
|
||||
BranchN,
|
||||
StraightLine,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub(in crate::mir::builder) struct SkeletonFacts {
|
||||
pub kind: SkeletonKind,
|
||||
}
|
||||
|
||||
pub(in crate::mir::builder) fn try_extract_skeleton_facts_from_stmt(
|
||||
stmt: &ASTNode,
|
||||
) -> Result<Option<SkeletonFacts>, Freeze> {
|
||||
let kind = match stmt {
|
||||
ASTNode::Loop { .. } => SkeletonKind::Loop,
|
||||
ASTNode::If {
|
||||
else_body: Some(_),
|
||||
..
|
||||
} => SkeletonKind::If2,
|
||||
ASTNode::MatchExpr { .. } => SkeletonKind::BranchN,
|
||||
_ => return Ok(None),
|
||||
};
|
||||
|
||||
Ok(Some(SkeletonFacts { kind }))
|
||||
}
|
||||
|
||||
pub(in crate::mir::builder) fn try_extract_loop_skeleton_facts(
|
||||
condition: &ASTNode,
|
||||
body: &[ASTNode],
|
||||
) -> Result<Option<SkeletonFacts>, Freeze> {
|
||||
let _ = (condition, body);
|
||||
Ok(Some(SkeletonFacts {
|
||||
kind: SkeletonKind::Loop,
|
||||
}))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{try_extract_skeleton_facts_from_stmt, SkeletonKind};
|
||||
use crate::ast::{ASTNode, LiteralValue, Span};
|
||||
|
||||
#[test]
|
||||
fn skeleton_facts_loop_is_detected() {
|
||||
let loop_node = ASTNode::Loop {
|
||||
condition: Box::new(ASTNode::Literal {
|
||||
value: LiteralValue::Bool(true),
|
||||
span: Span::unknown(),
|
||||
}),
|
||||
body: vec![],
|
||||
span: Span::unknown(),
|
||||
};
|
||||
let facts = try_extract_skeleton_facts_from_stmt(&loop_node)
|
||||
.expect("Ok")
|
||||
.expect("Some");
|
||||
assert_eq!(facts.kind, SkeletonKind::Loop);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn skeleton_facts_straight_line_is_none() {
|
||||
let assign = ASTNode::Assignment {
|
||||
target: Box::new(ASTNode::Variable {
|
||||
name: "x".to_string(),
|
||||
span: Span::unknown(),
|
||||
}),
|
||||
value: Box::new(ASTNode::Literal {
|
||||
value: LiteralValue::Integer(1),
|
||||
span: Span::unknown(),
|
||||
}),
|
||||
span: Span::unknown(),
|
||||
};
|
||||
let facts = try_extract_skeleton_facts_from_stmt(&assign).expect("Ok");
|
||||
assert!(facts.is_none());
|
||||
}
|
||||
}
|
||||
@ -248,6 +248,7 @@ mod tests {
|
||||
let facts = LoopFacts {
|
||||
condition_shape: ConditionShape::Unknown,
|
||||
step_shape: StepShape::Unknown,
|
||||
skeleton: None,
|
||||
scan_with_init: None,
|
||||
split_scan: Some(SplitScanFacts {
|
||||
s_var: "s".to_string(),
|
||||
@ -285,6 +286,7 @@ mod tests {
|
||||
let facts = LoopFacts {
|
||||
condition_shape: ConditionShape::Unknown,
|
||||
step_shape: StepShape::Unknown,
|
||||
skeleton: None,
|
||||
scan_with_init: None,
|
||||
split_scan: None,
|
||||
pattern1_simplewhile: None,
|
||||
@ -306,6 +308,7 @@ mod tests {
|
||||
let facts = LoopFacts {
|
||||
condition_shape: ConditionShape::Unknown,
|
||||
step_shape: StepShape::Unknown,
|
||||
skeleton: None,
|
||||
scan_with_init: Some(ScanWithInitFacts {
|
||||
loop_var: "i".to_string(),
|
||||
haystack: "s".to_string(),
|
||||
@ -350,6 +353,7 @@ mod tests {
|
||||
let facts = LoopFacts {
|
||||
condition_shape: ConditionShape::Unknown,
|
||||
step_shape: StepShape::Unknown,
|
||||
skeleton: None,
|
||||
scan_with_init: None,
|
||||
split_scan: None,
|
||||
pattern1_simplewhile: Some(Pattern1SimpleWhileFacts {
|
||||
@ -412,6 +416,7 @@ mod tests {
|
||||
let facts = LoopFacts {
|
||||
condition_shape: ConditionShape::Unknown,
|
||||
step_shape: StepShape::Unknown,
|
||||
skeleton: None,
|
||||
scan_with_init: None,
|
||||
split_scan: None,
|
||||
pattern1_simplewhile: None,
|
||||
@ -473,6 +478,7 @@ mod tests {
|
||||
let facts = LoopFacts {
|
||||
condition_shape: ConditionShape::Unknown,
|
||||
step_shape: StepShape::Unknown,
|
||||
skeleton: None,
|
||||
scan_with_init: None,
|
||||
split_scan: None,
|
||||
pattern1_simplewhile: None,
|
||||
@ -520,6 +526,7 @@ mod tests {
|
||||
let facts = LoopFacts {
|
||||
condition_shape: ConditionShape::Unknown,
|
||||
step_shape: StepShape::Unknown,
|
||||
skeleton: None,
|
||||
scan_with_init: None,
|
||||
split_scan: None,
|
||||
pattern1_simplewhile: None,
|
||||
@ -568,6 +575,7 @@ mod tests {
|
||||
let facts = LoopFacts {
|
||||
condition_shape: ConditionShape::Unknown,
|
||||
step_shape: StepShape::Unknown,
|
||||
skeleton: None,
|
||||
scan_with_init: None,
|
||||
split_scan: None,
|
||||
pattern1_simplewhile: None,
|
||||
@ -624,6 +632,7 @@ mod tests {
|
||||
let facts = LoopFacts {
|
||||
condition_shape: ConditionShape::Unknown,
|
||||
step_shape: StepShape::Unknown,
|
||||
skeleton: None,
|
||||
scan_with_init: None,
|
||||
split_scan: None,
|
||||
pattern1_simplewhile: None,
|
||||
@ -686,6 +695,7 @@ mod tests {
|
||||
let facts = LoopFacts {
|
||||
condition_shape: ConditionShape::Unknown,
|
||||
step_shape: StepShape::Unknown,
|
||||
skeleton: None,
|
||||
scan_with_init: None,
|
||||
split_scan: None,
|
||||
pattern1_simplewhile: None,
|
||||
|
||||
Reference in New Issue
Block a user