refactor(joinir): Phase 193-3 - Pattern Classification Improvement

Enhanced loop pattern classification system with diagnostic and query methods:

**LoopPatternKind improvements**:
- name(): Human-readable pattern names for debugging
- pattern_id(): Numeric identifiers (1-4 for patterns, 0 for unknown)
- is_recognized(): Check if pattern is classified
- has_special_control_flow(): Detect break/continue patterns
- has_phi_merge(): Detect if-else PHI patterns

**LoopFeatures improvements**:
- debug_stats(): Formatted debug string with all features
- total_divergences(): Count break + continue targets
- is_complex(): Check for complex control flow (>1 divergence or >1 carrier)
- is_simple(): Check for sequential loops with no special features

**New diagnostic function**:
- classify_with_diagnosis(): Returns pattern + human-readable diagnostic reason
  Example: (Pattern4Continue, "Has continue statement (continue_count=1)")

This improves debugging, enables runtime pattern queries, and provides better
diagnostic information during pattern routing.

Metrics: ~80 lines added
Files: src/mir/loop_pattern_detection.rs

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-12-06 10:30:38 +09:00
parent 49cc829ad2
commit 00b1395beb

View File

@ -56,6 +56,59 @@ pub enum LoopPatternKind {
Unknown, Unknown,
} }
impl LoopPatternKind {
/// Phase 193-3: Get human-readable pattern name
///
/// Returns the friendly name for this pattern (e.g., "Pattern 1: Simple While")
pub fn name(&self) -> &'static str {
match self {
LoopPatternKind::Pattern1SimpleWhile => "Pattern 1: Simple While Loop",
LoopPatternKind::Pattern2Break => "Pattern 2: Loop with Conditional Break",
LoopPatternKind::Pattern3IfPhi => "Pattern 3: Loop with If-Else PHI",
LoopPatternKind::Pattern4Continue => "Pattern 4: Loop with Continue",
LoopPatternKind::Unknown => "Unknown Pattern",
}
}
/// Phase 193-3: Get numeric pattern ID
///
/// Returns the pattern number (1-4) or 0 for unknown.
/// Useful for priority sorting.
pub fn pattern_id(&self) -> u8 {
match self {
LoopPatternKind::Pattern1SimpleWhile => 1,
LoopPatternKind::Pattern2Break => 2,
LoopPatternKind::Pattern3IfPhi => 3,
LoopPatternKind::Pattern4Continue => 4,
LoopPatternKind::Unknown => 0,
}
}
/// Phase 193-3: Check if this is a recognized pattern
///
/// Returns false only for Unknown.
pub fn is_recognized(&self) -> bool {
!matches!(self, LoopPatternKind::Unknown)
}
/// Phase 193-3: Check if pattern has special control flow
///
/// Returns true if pattern involves break or continue.
pub fn has_special_control_flow(&self) -> bool {
matches!(
self,
LoopPatternKind::Pattern2Break | LoopPatternKind::Pattern4Continue
)
}
/// Phase 193-3: Check if pattern involves PHI merging
///
/// Returns true if pattern has if-else PHI merge.
pub fn has_phi_merge(&self) -> bool {
matches!(self, LoopPatternKind::Pattern3IfPhi)
}
}
/// Feature vector extracted from loop structure. /// Feature vector extracted from loop structure.
/// ///
/// This structure captures all relevant properties needed for pattern classification. /// This structure captures all relevant properties needed for pattern classification.
@ -85,6 +138,46 @@ pub struct LoopFeatures {
pub continue_count: usize, pub continue_count: usize,
} }
impl LoopFeatures {
/// Phase 193-3: Get debug statistics string
///
/// Returns a formatted string showing all feature values for debugging.
pub fn debug_stats(&self) -> String {
format!(
"LoopFeatures {{ break: {}, continue: {}, if: {}, if_else_phi: {}, carriers: {}, break_count: {}, continue_count: {} }}",
self.has_break,
self.has_continue,
self.has_if,
self.has_if_else_phi,
self.carrier_count,
self.break_count,
self.continue_count
)
}
/// Phase 193-3: Count total control flow divergences
///
/// Returns the total number of break + continue targets.
/// Useful for determining loop complexity.
pub fn total_divergences(&self) -> usize {
self.break_count + self.continue_count
}
/// Phase 193-3: Check if loop has complex control flow
///
/// Returns true if loop has multiple divergences or multiple carriers.
pub fn is_complex(&self) -> bool {
self.total_divergences() > 1 || self.carrier_count > 1
}
/// Phase 193-3: Check if loop is simple (no special features)
///
/// Returns true if loop is purely sequential.
pub fn is_simple(&self) -> bool {
!self.has_break && !self.has_continue && !self.has_if_else_phi && self.carrier_count <= 1
}
}
/// Extract features from LoopForm for pattern classification. /// Extract features from LoopForm for pattern classification.
/// ///
/// This function is the entry point for structure-based pattern detection. /// This function is the entry point for structure-based pattern detection.
@ -176,6 +269,48 @@ pub fn classify(features: &LoopFeatures) -> LoopPatternKind {
LoopPatternKind::Unknown LoopPatternKind::Unknown
} }
/// Phase 193-3: Diagnose pattern classification with details
///
/// This function performs classification AND generates diagnostic information.
/// Useful for debugging and logging.
///
/// # Returns
/// * `(LoopPatternKind, String)` - The classified pattern and a diagnostic message
pub fn classify_with_diagnosis(features: &LoopFeatures) -> (LoopPatternKind, String) {
let pattern = classify(features);
let reason = match pattern {
LoopPatternKind::Pattern4Continue => {
format!(
"Has continue statement (continue_count={})",
features.continue_count
)
}
LoopPatternKind::Pattern3IfPhi => {
format!(
"Has if-else PHI with {} carriers, no break/continue",
features.carrier_count
)
}
LoopPatternKind::Pattern2Break => {
format!(
"Has break statement (break_count={}), no continue",
features.break_count
)
}
LoopPatternKind::Pattern1SimpleWhile => {
"Simple while loop with no special control flow".to_string()
}
LoopPatternKind::Unknown => {
format!(
"Unknown pattern: {}",
features.debug_stats()
)
}
};
(pattern, reason)
}
// ============================================================================ // ============================================================================
// Legacy Detection Functions (Phase 188) // Legacy Detection Functions (Phase 188)
// ============================================================================ // ============================================================================