feat(joinir): Phase 224-cont - Promoted variable tracking for lowerer
- Add promoted_loopbodylocals field to CarrierInfo - Record promoted variables in Pattern2 promotion handler - Filter promoted variables in lowerer LoopBodyLocal check - digit_pos → is_digit_pos promotion now continues to lowering Closes Phase 224 lowerer integration gap. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -308,6 +308,9 @@ impl MirBuilder {
|
|||||||
promoted_var, carrier_name
|
promoted_var, carrier_name
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Phase 224: Record promoted variable before merging
|
||||||
|
carrier_info.promoted_loopbodylocals.push(promoted_var.clone());
|
||||||
|
|
||||||
// Merge promoted carrier into existing CarrierInfo
|
// Merge promoted carrier into existing CarrierInfo
|
||||||
carrier_info.merge_from(&promoted_carrier);
|
carrier_info.merge_from(&promoted_carrier);
|
||||||
|
|
||||||
@ -316,6 +319,10 @@ impl MirBuilder {
|
|||||||
carrier_name,
|
carrier_name,
|
||||||
carrier_info.carrier_count()
|
carrier_info.carrier_count()
|
||||||
);
|
);
|
||||||
|
eprintln!(
|
||||||
|
"[pattern2/cond_promoter] Phase 224: Recorded promoted variable '{}' in carrier_info.promoted_loopbodylocals",
|
||||||
|
promoted_var
|
||||||
|
);
|
||||||
|
|
||||||
// Check if this is a safe Trim pattern
|
// Check if this is a safe Trim pattern
|
||||||
if let Some(helper) = carrier_info.trim_helper() {
|
if let Some(helper) = carrier_info.trim_helper() {
|
||||||
|
|||||||
@ -72,6 +72,7 @@ impl Pattern4CarrierAnalyzer {
|
|||||||
loop_var_id: all_carriers.loop_var_id,
|
loop_var_id: all_carriers.loop_var_id,
|
||||||
carriers: updated_carriers,
|
carriers: updated_carriers,
|
||||||
trim_helper: all_carriers.trim_helper.clone(),
|
trim_helper: all_carriers.trim_helper.clone(),
|
||||||
|
promoted_loopbodylocals: all_carriers.promoted_loopbodylocals.clone(), // Phase 224
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,6 +288,7 @@ mod tests {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
trim_helper: None,
|
trim_helper: None,
|
||||||
|
promoted_loopbodylocals: Vec::new(), // Phase 224
|
||||||
};
|
};
|
||||||
|
|
||||||
// Analyze carriers
|
// Analyze carriers
|
||||||
|
|||||||
@ -404,6 +404,7 @@ mod tests {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
trim_helper: None,
|
trim_helper: None,
|
||||||
|
promoted_loopbodylocals: Vec::new(), // Phase 224
|
||||||
},
|
},
|
||||||
loop_scope: LoopScopeShapeBuilder::empty_body_locals(
|
loop_scope: LoopScopeShapeBuilder::empty_body_locals(
|
||||||
BasicBlockId(0),
|
BasicBlockId(0),
|
||||||
@ -442,6 +443,7 @@ mod tests {
|
|||||||
carrier_name: "is_whitespace".to_string(),
|
carrier_name: "is_whitespace".to_string(),
|
||||||
whitespace_chars: vec![" ".to_string(), "\t".to_string()],
|
whitespace_chars: vec![" ".to_string(), "\t".to_string()],
|
||||||
}),
|
}),
|
||||||
|
promoted_loopbodylocals: Vec::new(), // Phase 224
|
||||||
},
|
},
|
||||||
loop_scope: LoopScopeShapeBuilder::empty_body_locals(
|
loop_scope: LoopScopeShapeBuilder::empty_body_locals(
|
||||||
BasicBlockId(0),
|
BasicBlockId(0),
|
||||||
|
|||||||
@ -46,6 +46,12 @@ pub struct CarrierInfo {
|
|||||||
pub carriers: Vec<CarrierVar>,
|
pub carriers: Vec<CarrierVar>,
|
||||||
/// Phase 171-C-5: Trim pattern helper (if this CarrierInfo was created from Trim promotion)
|
/// Phase 171-C-5: Trim pattern helper (if this CarrierInfo was created from Trim promotion)
|
||||||
pub trim_helper: Option<crate::mir::loop_pattern_detection::trim_loop_helper::TrimLoopHelper>,
|
pub trim_helper: Option<crate::mir::loop_pattern_detection::trim_loop_helper::TrimLoopHelper>,
|
||||||
|
/// Phase 224: Promoted LoopBodyLocal variables (e.g., "digit_pos" promoted to "is_digit_pos")
|
||||||
|
///
|
||||||
|
/// These variables were originally LoopBodyLocal but have been promoted to carriers
|
||||||
|
/// during condition promotion (e.g., DigitPosPromoter). The lowerer should skip
|
||||||
|
/// LoopBodyLocal checks for these variables.
|
||||||
|
pub promoted_loopbodylocals: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CarrierInfo {
|
impl CarrierInfo {
|
||||||
@ -106,6 +112,7 @@ impl CarrierInfo {
|
|||||||
loop_var_id,
|
loop_var_id,
|
||||||
carriers,
|
carriers,
|
||||||
trim_helper: None, // Phase 171-C-5: No Trim pattern by default
|
trim_helper: None, // Phase 171-C-5: No Trim pattern by default
|
||||||
|
promoted_loopbodylocals: Vec::new(), // Phase 224: No promoted variables by default
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,6 +170,7 @@ impl CarrierInfo {
|
|||||||
loop_var_id,
|
loop_var_id,
|
||||||
carriers,
|
carriers,
|
||||||
trim_helper: None, // Phase 171-C-5: No Trim pattern by default
|
trim_helper: None, // Phase 171-C-5: No Trim pattern by default
|
||||||
|
promoted_loopbodylocals: Vec::new(), // Phase 224: No promoted variables by default
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,6 +197,7 @@ impl CarrierInfo {
|
|||||||
loop_var_id,
|
loop_var_id,
|
||||||
carriers,
|
carriers,
|
||||||
trim_helper: None, // Phase 171-C-5: No Trim pattern by default
|
trim_helper: None, // Phase 171-C-5: No Trim pattern by default
|
||||||
|
promoted_loopbodylocals: Vec::new(), // Phase 224: No promoted variables by default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,6 +251,13 @@ impl CarrierInfo {
|
|||||||
if other.trim_helper.is_some() {
|
if other.trim_helper.is_some() {
|
||||||
self.trim_helper = other.trim_helper.clone();
|
self.trim_helper = other.trim_helper.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Phase 224: Merge promoted_loopbodylocals (deduplicate)
|
||||||
|
for promoted_var in &other.promoted_loopbodylocals {
|
||||||
|
if !self.promoted_loopbodylocals.contains(promoted_var) {
|
||||||
|
self.promoted_loopbodylocals.push(promoted_var.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Phase 171-C-5: Get Trim pattern helper
|
/// Phase 171-C-5: Get Trim pattern helper
|
||||||
|
|||||||
@ -154,8 +154,29 @@ pub(crate) fn lower_loop_with_break_minimal(
|
|||||||
);
|
);
|
||||||
|
|
||||||
if loop_cond_scope.has_loop_body_local() {
|
if loop_cond_scope.has_loop_body_local() {
|
||||||
|
// Phase 224: Filter out promoted variables from body-local check
|
||||||
|
// Variables that were promoted to carriers should not trigger the error
|
||||||
let body_local_names = extract_body_local_names(&loop_cond_scope.vars);
|
let body_local_names = extract_body_local_names(&loop_cond_scope.vars);
|
||||||
return Err(format_unsupported_condition_error("pattern2", &body_local_names));
|
let unpromoted_locals: Vec<&String> = body_local_names
|
||||||
|
.iter()
|
||||||
|
.filter(|name| !carrier_info.promoted_loopbodylocals.contains(*name))
|
||||||
|
.copied()
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
if !unpromoted_locals.is_empty() {
|
||||||
|
eprintln!(
|
||||||
|
"[joinir/pattern2] Phase 224: {} body-local variables after promotion filter: {:?}",
|
||||||
|
unpromoted_locals.len(),
|
||||||
|
unpromoted_locals
|
||||||
|
);
|
||||||
|
return Err(format_unsupported_condition_error("pattern2", &unpromoted_locals));
|
||||||
|
}
|
||||||
|
|
||||||
|
eprintln!(
|
||||||
|
"[joinir/pattern2] Phase 224: All {} body-local variables were promoted: {:?}",
|
||||||
|
body_local_names.len(),
|
||||||
|
body_local_names
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
eprintln!(
|
eprintln!(
|
||||||
|
|||||||
Reference in New Issue
Block a user