phase29an(p0): add skeleton facts ssot (no wiring)

This commit is contained in:
2025-12-29 17:32:19 +09:00
parent fceae90f63
commit ea32d61a5d
4 changed files with 109 additions and 11 deletions

View File

@ -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,

View File

@ -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,

View 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());
}
}

View File

@ -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,