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,
|
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(in crate::mir::builder) struct Pattern2Inputs {
|
||||||
pub loop_var_name: String,
|
pub loop_var_name: String,
|
||||||
pub loop_var_id: ValueId,
|
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.
|
/// Phase 92 P3: Allow-list of LoopBodyLocal variable names permitted in conditions.
|
||||||
/// This must stay minimal (1 variable) and is validated by ReadOnlyBodyLocalSlotBox.
|
/// This must stay minimal (1 variable) and is validated by ReadOnlyBodyLocalSlotBox.
|
||||||
pub allowed_body_locals_for_conditions: Vec<String>,
|
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.
|
/// 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>,
|
pub read_only_body_local_slot: Option<crate::mir::join_ir::lowering::common::body_local_slot::ReadOnlyBodyLocalSlot>,
|
||||||
/// Policy-routed "break when true" condition node.
|
/// 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> {
|
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::balanced_depth_scan_policy_box::BalancedDepthScanPolicyBox;
|
||||||
use super::super::policies::PolicyDecision;
|
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;
|
use crate::mir::join_ir::lowering::common::body_local_slot::ReadOnlyBodyLocalSlotBox;
|
||||||
|
|
||||||
// Phase 107: balanced depth-scan (return-in-loop) policy.
|
// Phase 107: balanced depth-scan (return-in-loop) policy.
|
||||||
@ -30,6 +31,7 @@ impl ApplyPolicyStepBox {
|
|||||||
condition_bindings: facts.condition_bindings,
|
condition_bindings: facts.condition_bindings,
|
||||||
body_local_env: facts.body_local_env,
|
body_local_env: facts.body_local_env,
|
||||||
allowed_body_locals_for_conditions: result.allowed_body_locals_for_conditions,
|
allowed_body_locals_for_conditions: result.allowed_body_locals_for_conditions,
|
||||||
|
body_local_handling: BodyLocalHandlingPolicy::SkipPromotion,
|
||||||
read_only_body_local_slot: None,
|
read_only_body_local_slot: None,
|
||||||
break_condition_node: result.break_condition_node,
|
break_condition_node: result.break_condition_node,
|
||||||
is_loop_true_read_digits: false,
|
is_loop_true_read_digits: false,
|
||||||
@ -68,6 +70,7 @@ impl ApplyPolicyStepBox {
|
|||||||
condition_bindings: facts.condition_bindings,
|
condition_bindings: facts.condition_bindings,
|
||||||
body_local_env: facts.body_local_env,
|
body_local_env: facts.body_local_env,
|
||||||
allowed_body_locals_for_conditions: break_routing.allowed_body_locals_for_conditions,
|
allowed_body_locals_for_conditions: break_routing.allowed_body_locals_for_conditions,
|
||||||
|
body_local_handling: BodyLocalHandlingPolicy::DefaultPromotion,
|
||||||
read_only_body_local_slot,
|
read_only_body_local_slot,
|
||||||
break_condition_node: break_routing.break_condition_node,
|
break_condition_node: break_routing.break_condition_node,
|
||||||
is_loop_true_read_digits: break_routing.is_loop_true_read_digits,
|
is_loop_true_read_digits: break_routing.is_loop_true_read_digits,
|
||||||
|
|||||||
@ -166,10 +166,13 @@ impl PromoteStepBox {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
if cond_scope.has_loop_body_local() {
|
if cond_scope.has_loop_body_local() {
|
||||||
// Phase 107: balanced depth-scan policy already provides an allow-list + derived recipe.
|
// Policy-controlled: some families must not run promotion/slot heuristics here.
|
||||||
// Do not re-run Pattern2 body-local promotion/slot heuristics here (they assume break-guard shapes).
|
// Example: balanced depth-scan uses derived vars and doesn't have a break-guard node.
|
||||||
if inputs.balanced_depth_scan_recipe.is_some() {
|
if matches!(
|
||||||
// no-op: LoopBodyLocalInitLowerer + BalancedDepthScanEmitter will populate the env.
|
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 {
|
} else if !inputs.is_loop_true_read_digits {
|
||||||
match classify_for_pattern2(
|
match classify_for_pattern2(
|
||||||
builder,
|
builder,
|
||||||
|
|||||||
Reference in New Issue
Block a user