refactor(joinir): make Pattern2 body-local handling policy-driven
This commit is contained in:
@ -53,6 +53,12 @@ pub(in crate::mir::builder) struct Pattern2Facts {
|
||||
pub body_local_env: LoopBodyLocalEnv,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub(crate) enum BodyLocalHandlingPolicy {
|
||||
DefaultPromotion,
|
||||
SkipPromotion,
|
||||
}
|
||||
|
||||
pub(in crate::mir::builder) struct Pattern2Inputs {
|
||||
pub loop_var_name: String,
|
||||
pub loop_var_id: ValueId,
|
||||
@ -66,6 +72,8 @@ pub(in crate::mir::builder) struct Pattern2Inputs {
|
||||
/// Phase 92 P3: Allow-list of LoopBodyLocal variable names permitted in conditions.
|
||||
/// This must stay minimal (1 variable) and is validated by ReadOnlyBodyLocalSlotBox.
|
||||
pub allowed_body_locals_for_conditions: Vec<String>,
|
||||
/// Phase 107: For some policy-routed families, Pattern2 must not run promotion/slot heuristics.
|
||||
pub body_local_handling: BodyLocalHandlingPolicy,
|
||||
/// Phase 92 P3: Diagnostics / debug metadata for the allow-listed variable.
|
||||
pub read_only_body_local_slot: Option<crate::mir::join_ir::lowering::common::body_local_slot::ReadOnlyBodyLocalSlot>,
|
||||
/// Policy-routed "break when true" condition node.
|
||||
|
||||
@ -13,6 +13,7 @@ impl ApplyPolicyStepBox {
|
||||
pub(crate) fn apply(condition: &ASTNode, body: &[ASTNode], facts: Pattern2Facts) -> Result<Pattern2Inputs, String> {
|
||||
use super::super::policies::balanced_depth_scan_policy_box::BalancedDepthScanPolicyBox;
|
||||
use super::super::policies::PolicyDecision;
|
||||
use crate::mir::builder::control_flow::joinir::patterns::pattern2_inputs_facts_box::BodyLocalHandlingPolicy;
|
||||
use crate::mir::join_ir::lowering::common::body_local_slot::ReadOnlyBodyLocalSlotBox;
|
||||
|
||||
// Phase 107: balanced depth-scan (return-in-loop) policy.
|
||||
@ -30,6 +31,7 @@ impl ApplyPolicyStepBox {
|
||||
condition_bindings: facts.condition_bindings,
|
||||
body_local_env: facts.body_local_env,
|
||||
allowed_body_locals_for_conditions: result.allowed_body_locals_for_conditions,
|
||||
body_local_handling: BodyLocalHandlingPolicy::SkipPromotion,
|
||||
read_only_body_local_slot: None,
|
||||
break_condition_node: result.break_condition_node,
|
||||
is_loop_true_read_digits: false,
|
||||
@ -68,6 +70,7 @@ impl ApplyPolicyStepBox {
|
||||
condition_bindings: facts.condition_bindings,
|
||||
body_local_env: facts.body_local_env,
|
||||
allowed_body_locals_for_conditions: break_routing.allowed_body_locals_for_conditions,
|
||||
body_local_handling: BodyLocalHandlingPolicy::DefaultPromotion,
|
||||
read_only_body_local_slot,
|
||||
break_condition_node: break_routing.break_condition_node,
|
||||
is_loop_true_read_digits: break_routing.is_loop_true_read_digits,
|
||||
|
||||
@ -166,10 +166,13 @@ impl PromoteStepBox {
|
||||
.collect();
|
||||
|
||||
if cond_scope.has_loop_body_local() {
|
||||
// Phase 107: balanced depth-scan policy already provides an allow-list + derived recipe.
|
||||
// Do not re-run Pattern2 body-local promotion/slot heuristics here (they assume break-guard shapes).
|
||||
if inputs.balanced_depth_scan_recipe.is_some() {
|
||||
// no-op: LoopBodyLocalInitLowerer + BalancedDepthScanEmitter will populate the env.
|
||||
// Policy-controlled: some families must not run promotion/slot heuristics here.
|
||||
// Example: balanced depth-scan uses derived vars and doesn't have a break-guard node.
|
||||
if matches!(
|
||||
inputs.body_local_handling,
|
||||
crate::mir::builder::control_flow::joinir::patterns::pattern2_inputs_facts_box::BodyLocalHandlingPolicy::SkipPromotion
|
||||
) {
|
||||
// no-op: lowerers will populate LoopBodyLocalEnv via init/derived emission.
|
||||
} else if !inputs.is_loop_true_read_digits {
|
||||
match classify_for_pattern2(
|
||||
builder,
|
||||
|
||||
Reference in New Issue
Block a user