Files
hakorune/src/mir/join_ir/lowering/step_schedule.rs

417 lines
14 KiB
Rust
Raw Normal View History

feat(joinir): Phase 47-A-IMPL - P3 Normalized infrastructure Implement Pattern3 (if-sum) Normalized infrastructure, extending existing P2 StepSchedule and ShapeGuard systems. Key changes: 1. StepSchedule generalization (P2 → P2/P3): - Renamed: pattern2_step_schedule.rs → step_schedule.rs - Extended StepKind enum with P3 variants: - IfCond (if condition in body) - ThenUpdates (carrier updates in then branch) - ElseUpdates (carrier updates in else branch) - Added pattern3_if_sum_schedule() function - Added unit test: test_pattern3_if_sum_schedule() - Updated module references (mod.rs, loop_with_break_minimal.rs) 2. ShapeGuard extension: - Added Pattern3IfSumMinimal variant to NormalizedDevShape - Added is_pattern3_if_sum_minimal() detector (placeholder) - Updated shape detector table - Extended capability_for_shape() mapping 3. Bridge integration: - bridge.rs: Added P3 shape handling in normalize_for_shape() - normalized.rs: Added P3 roundtrip match (uses P2 temporarily) 4. P2/P3 separation: - loop_with_break_minimal.rs: Added panic for P3 steps in P2 lowering - Clear boundary enforcement (P2 lowerer rejects P3 steps) 5. Documentation: - CURRENT_TASK.md: Phase 47-A-IMPL status - phase47-norm-p3-design.md: Implementation status section Benefits: - Reuses 90% of P2 infrastructure (ConditionEnv, CarrierInfo, ExitLine) - Clean P2/P3 separation via StepKind - Pure additive changes (no P2 behavioral changes) - Ready for Phase 47-A-LOWERING (full P3 Normalized implementation) Tests: 938/938 PASS (+1 from step_schedule unit test) - All existing P1/P2 tests pass (no regressions) - P3 test uses Structured path temporarily (proper lowering in next phase) Next phase: Implement full P3 Normalized→MIR(direct) lowering
2025-12-12 05:23:18 +09:00
//! Phase 47-A: Generic step scheduling for Pattern2/Pattern3 loops
//!
feat(joinir): Phase 47-A-IMPL - P3 Normalized infrastructure Implement Pattern3 (if-sum) Normalized infrastructure, extending existing P2 StepSchedule and ShapeGuard systems. Key changes: 1. StepSchedule generalization (P2 → P2/P3): - Renamed: pattern2_step_schedule.rs → step_schedule.rs - Extended StepKind enum with P3 variants: - IfCond (if condition in body) - ThenUpdates (carrier updates in then branch) - ElseUpdates (carrier updates in else branch) - Added pattern3_if_sum_schedule() function - Added unit test: test_pattern3_if_sum_schedule() - Updated module references (mod.rs, loop_with_break_minimal.rs) 2. ShapeGuard extension: - Added Pattern3IfSumMinimal variant to NormalizedDevShape - Added is_pattern3_if_sum_minimal() detector (placeholder) - Updated shape detector table - Extended capability_for_shape() mapping 3. Bridge integration: - bridge.rs: Added P3 shape handling in normalize_for_shape() - normalized.rs: Added P3 roundtrip match (uses P2 temporarily) 4. P2/P3 separation: - loop_with_break_minimal.rs: Added panic for P3 steps in P2 lowering - Clear boundary enforcement (P2 lowerer rejects P3 steps) 5. Documentation: - CURRENT_TASK.md: Phase 47-A-IMPL status - phase47-norm-p3-design.md: Implementation status section Benefits: - Reuses 90% of P2 infrastructure (ConditionEnv, CarrierInfo, ExitLine) - Clean P2/P3 separation via StepKind - Pure additive changes (no P2 behavioral changes) - Ready for Phase 47-A-LOWERING (full P3 Normalized implementation) Tests: 938/938 PASS (+1 from step_schedule unit test) - All existing P1/P2 tests pass (no regressions) - P3 test uses Structured path temporarily (proper lowering in next phase) Next phase: Implement full P3 Normalized→MIR(direct) lowering
2025-12-12 05:23:18 +09:00
//! Determines evaluation order for loop steps (header cond, body init, break check, etc).
//! Used by both P2 (break) and P3 (if-sum) patterns.
//!
//! This keeps the lowerer focused on emitting fragments, while this box decides
//! how to interleave them (e.g., body-local init before break checks when the
//! break depends on body-local values).
use crate::config::env;
use crate::config::env::joinir_dev::joinir_test_debug_enabled;
use crate::mir::join_ir::lowering::carrier_info::{CarrierInfo, CarrierInit};
use crate::mir::join_ir::lowering::loop_body_local_env::LoopBodyLocalEnv;
/// Steps that can be reordered by the scheduler.
#[allow(dead_code)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum Pattern2StepKind {
feat(joinir): Phase 47-A-IMPL - P3 Normalized infrastructure Implement Pattern3 (if-sum) Normalized infrastructure, extending existing P2 StepSchedule and ShapeGuard systems. Key changes: 1. StepSchedule generalization (P2 → P2/P3): - Renamed: pattern2_step_schedule.rs → step_schedule.rs - Extended StepKind enum with P3 variants: - IfCond (if condition in body) - ThenUpdates (carrier updates in then branch) - ElseUpdates (carrier updates in else branch) - Added pattern3_if_sum_schedule() function - Added unit test: test_pattern3_if_sum_schedule() - Updated module references (mod.rs, loop_with_break_minimal.rs) 2. ShapeGuard extension: - Added Pattern3IfSumMinimal variant to NormalizedDevShape - Added is_pattern3_if_sum_minimal() detector (placeholder) - Updated shape detector table - Extended capability_for_shape() mapping 3. Bridge integration: - bridge.rs: Added P3 shape handling in normalize_for_shape() - normalized.rs: Added P3 roundtrip match (uses P2 temporarily) 4. P2/P3 separation: - loop_with_break_minimal.rs: Added panic for P3 steps in P2 lowering - Clear boundary enforcement (P2 lowerer rejects P3 steps) 5. Documentation: - CURRENT_TASK.md: Phase 47-A-IMPL status - phase47-norm-p3-design.md: Implementation status section Benefits: - Reuses 90% of P2 infrastructure (ConditionEnv, CarrierInfo, ExitLine) - Clean P2/P3 separation via StepKind - Pure additive changes (no P2 behavioral changes) - Ready for Phase 47-A-LOWERING (full P3 Normalized implementation) Tests: 938/938 PASS (+1 from step_schedule unit test) - All existing P1/P2 tests pass (no regressions) - P3 test uses Structured path temporarily (proper lowering in next phase) Next phase: Implement full P3 Normalized→MIR(direct) lowering
2025-12-12 05:23:18 +09:00
// P2 (Pattern2 Break) steps
HeaderCond, // loop(cond)
BodyInit, // local ch = ...
BreakCheck, // if (cond) break
Updates, // sum = sum + 1
Tail, // i = i + 1
feat(joinir): Phase 47-A-IMPL - P3 Normalized infrastructure Implement Pattern3 (if-sum) Normalized infrastructure, extending existing P2 StepSchedule and ShapeGuard systems. Key changes: 1. StepSchedule generalization (P2 → P2/P3): - Renamed: pattern2_step_schedule.rs → step_schedule.rs - Extended StepKind enum with P3 variants: - IfCond (if condition in body) - ThenUpdates (carrier updates in then branch) - ElseUpdates (carrier updates in else branch) - Added pattern3_if_sum_schedule() function - Added unit test: test_pattern3_if_sum_schedule() - Updated module references (mod.rs, loop_with_break_minimal.rs) 2. ShapeGuard extension: - Added Pattern3IfSumMinimal variant to NormalizedDevShape - Added is_pattern3_if_sum_minimal() detector (placeholder) - Updated shape detector table - Extended capability_for_shape() mapping 3. Bridge integration: - bridge.rs: Added P3 shape handling in normalize_for_shape() - normalized.rs: Added P3 roundtrip match (uses P2 temporarily) 4. P2/P3 separation: - loop_with_break_minimal.rs: Added panic for P3 steps in P2 lowering - Clear boundary enforcement (P2 lowerer rejects P3 steps) 5. Documentation: - CURRENT_TASK.md: Phase 47-A-IMPL status - phase47-norm-p3-design.md: Implementation status section Benefits: - Reuses 90% of P2 infrastructure (ConditionEnv, CarrierInfo, ExitLine) - Clean P2/P3 separation via StepKind - Pure additive changes (no P2 behavioral changes) - Ready for Phase 47-A-LOWERING (full P3 Normalized implementation) Tests: 938/938 PASS (+1 from step_schedule unit test) - All existing P1/P2 tests pass (no regressions) - P3 test uses Structured path temporarily (proper lowering in next phase) Next phase: Implement full P3 Normalized→MIR(direct) lowering
2025-12-12 05:23:18 +09:00
// Phase 47-A: P3 (Pattern3 If-Sum) steps
IfCond, // if (cond) in body
ThenUpdates, // carrier updates in then branch
ElseUpdates, // carrier updates in else branch (if any)
feat(joinir): Phase 48-A - P4 (continue) Normalized minimal implementation Pattern4 (continue) integration into Normalized JoinIR pipeline complete. Key changes: - P4 minimal fixture: skip i==2 pattern, single carrier (acc) - ShapeGuard: Pattern4ContinueMinimal detector (structure-based) - StepScheduleBox: ContinueCheck step (eval order: HeaderCond → ContinueCheck → Updates → Tail) - normalize_pattern4_continue_minimal(): Delegates to P2 (95% infrastructure reuse) - Tests: 4 integration tests (normalization/runner/VM Bridge comparison×2) Design validation: - P4 (continue) = reverse control flow of P2 (break) - Same loop_step(env, k_exit) skeleton - Same EnvLayout/ConditionEnv/CarrierInfo infrastructure - Only difference: evaluation order and control flow direction Architecture proof: - Normalized JoinIR successfully handles P1/P2/P3/P4 uniformly - Infrastructure reuse rate: 95%+ as designed Tests: 939/939 PASS (+1 from baseline 938, target exceeded!) Files modified: 10 files (~305 lines added, pure additive) - pattern4_continue_min.program.json (NEW +126 lines) - P4 fixture - fixtures.rs (+31 lines) - P4 fixture loader - shape_guard.rs (+60 lines) - Shape detection - step_schedule.rs (+18 lines) - Schedule + test - normalized.rs (+35 lines) - Normalization function - loop_with_break_minimal.rs (+4 lines) - ContinueCheck handler - bridge.rs (+5 lines) - VM bridge routing - ast_lowerer/mod.rs (+2 lines) - Function registration - normalized_joinir_min.rs (+84 lines) - Integration tests - CURRENT_TASK.md (+13 lines) - Phase 48-A completion Next steps: - Phase 48-B: Extended P4 (multi-carrier, complex continue) - Phase 48-C: Canonical promotion (always use Normalized for P4)
2025-12-12 06:31:13 +09:00
// Phase 48-A: P4 (Pattern4 Continue) steps
ContinueCheck, // if (cond) continue
}
impl Pattern2StepKind {
fn as_str(&self) -> &'static str {
match self {
Pattern2StepKind::HeaderCond => "header-cond",
Pattern2StepKind::BodyInit => "body-init",
Pattern2StepKind::BreakCheck => "break",
Pattern2StepKind::Updates => "updates",
Pattern2StepKind::Tail => "tail",
feat(joinir): Phase 47-A-IMPL - P3 Normalized infrastructure Implement Pattern3 (if-sum) Normalized infrastructure, extending existing P2 StepSchedule and ShapeGuard systems. Key changes: 1. StepSchedule generalization (P2 → P2/P3): - Renamed: pattern2_step_schedule.rs → step_schedule.rs - Extended StepKind enum with P3 variants: - IfCond (if condition in body) - ThenUpdates (carrier updates in then branch) - ElseUpdates (carrier updates in else branch) - Added pattern3_if_sum_schedule() function - Added unit test: test_pattern3_if_sum_schedule() - Updated module references (mod.rs, loop_with_break_minimal.rs) 2. ShapeGuard extension: - Added Pattern3IfSumMinimal variant to NormalizedDevShape - Added is_pattern3_if_sum_minimal() detector (placeholder) - Updated shape detector table - Extended capability_for_shape() mapping 3. Bridge integration: - bridge.rs: Added P3 shape handling in normalize_for_shape() - normalized.rs: Added P3 roundtrip match (uses P2 temporarily) 4. P2/P3 separation: - loop_with_break_minimal.rs: Added panic for P3 steps in P2 lowering - Clear boundary enforcement (P2 lowerer rejects P3 steps) 5. Documentation: - CURRENT_TASK.md: Phase 47-A-IMPL status - phase47-norm-p3-design.md: Implementation status section Benefits: - Reuses 90% of P2 infrastructure (ConditionEnv, CarrierInfo, ExitLine) - Clean P2/P3 separation via StepKind - Pure additive changes (no P2 behavioral changes) - Ready for Phase 47-A-LOWERING (full P3 Normalized implementation) Tests: 938/938 PASS (+1 from step_schedule unit test) - All existing P1/P2 tests pass (no regressions) - P3 test uses Structured path temporarily (proper lowering in next phase) Next phase: Implement full P3 Normalized→MIR(direct) lowering
2025-12-12 05:23:18 +09:00
// Phase 47-A: P3 steps
Pattern2StepKind::IfCond => "if-cond",
Pattern2StepKind::ThenUpdates => "then-updates",
Pattern2StepKind::ElseUpdates => "else-updates",
feat(joinir): Phase 48-A - P4 (continue) Normalized minimal implementation Pattern4 (continue) integration into Normalized JoinIR pipeline complete. Key changes: - P4 minimal fixture: skip i==2 pattern, single carrier (acc) - ShapeGuard: Pattern4ContinueMinimal detector (structure-based) - StepScheduleBox: ContinueCheck step (eval order: HeaderCond → ContinueCheck → Updates → Tail) - normalize_pattern4_continue_minimal(): Delegates to P2 (95% infrastructure reuse) - Tests: 4 integration tests (normalization/runner/VM Bridge comparison×2) Design validation: - P4 (continue) = reverse control flow of P2 (break) - Same loop_step(env, k_exit) skeleton - Same EnvLayout/ConditionEnv/CarrierInfo infrastructure - Only difference: evaluation order and control flow direction Architecture proof: - Normalized JoinIR successfully handles P1/P2/P3/P4 uniformly - Infrastructure reuse rate: 95%+ as designed Tests: 939/939 PASS (+1 from baseline 938, target exceeded!) Files modified: 10 files (~305 lines added, pure additive) - pattern4_continue_min.program.json (NEW +126 lines) - P4 fixture - fixtures.rs (+31 lines) - P4 fixture loader - shape_guard.rs (+60 lines) - Shape detection - step_schedule.rs (+18 lines) - Schedule + test - normalized.rs (+35 lines) - Normalization function - loop_with_break_minimal.rs (+4 lines) - ContinueCheck handler - bridge.rs (+5 lines) - VM bridge routing - ast_lowerer/mod.rs (+2 lines) - Function registration - normalized_joinir_min.rs (+84 lines) - Integration tests - CURRENT_TASK.md (+13 lines) - Phase 48-A completion Next steps: - Phase 48-B: Extended P4 (multi-carrier, complex continue) - Phase 48-C: Canonical promotion (always use Normalized for P4)
2025-12-12 06:31:13 +09:00
// Phase 48-A: P4 steps
Pattern2StepKind::ContinueCheck => "continue-check",
}
}
}
/// Data-driven schedule for Pattern 2 lowering.
#[derive(Debug, Clone)]
pub(crate) struct Pattern2StepSchedule {
steps: Vec<Pattern2StepKind>,
reason: &'static str,
}
impl Pattern2StepSchedule {
pub(crate) fn iter(&self) -> impl Iterator<Item = Pattern2StepKind> + '_ {
self.steps.iter().copied()
}
pub(crate) fn reason(&self) -> &'static str {
self.reason
}
pub(crate) fn steps(&self) -> &[Pattern2StepKind] {
&self.steps
}
}
/// Schedule decision result with reasoning (SSOT)
refactor(mir): Phase 93 リファクタリング - 箱化モジュール化 ## 概要 Phase 93 P0実装後のコード整理。スケジュール決定ロジックとbreak semanticsを 明確化し、デバッグログを統一。 ## 変更内容 ### 1. スケジュール決定ロジックの関数化 (step_schedule.rs) - `ScheduleDecision`構造体追加(判定結果+理由+デバッグコンテキスト) - `decide_pattern2_schedule()` - スケジュール決定のSSOT - `build_pattern2_schedule_from_decision()` - 新しい決定ベースAPI - 判定理由が4種類で明確化(ConditionOnly → body-local → loop-local → default) - 後方互換性維持(`Pattern2ScheduleContext`はwrapperに) ### 2. ConditionOnlyRecipe強化 (condition_only_emitter.rs) - `BreakSemantics` enum追加(WhenMatch vs WhenNotMatch) - `generate_break_condition()` - semanticsに基づくAST生成 - `from_trim_helper_condition_only()` - factory method追加 - break semanticsがrecipeに明示的に含まれる ### 3. trim_loop_lowering.rs簡素化 - `generate_condition_only_break_condition()`削除(DRY原則) - `recipe.generate_break_condition()`で統一 - break条件生成ロジックが1箇所に集約 ### 4. デバッグログ統一 - `[phase93/schedule]` - スケジュール決定 - `[phase93/condition-only]` - ConditionOnlyレシピ作成 - `[phase93/break-cond]` - break条件生成 - 既存の`joinir_dev_enabled()`使用(新規env var不要) ## テスト結果 - step_schedule: 10 tests PASS - condition_only_emitter: 4 tests PASS - 後方互換性維持 ## 統計 - 3ファイル変更 - +249行 / -57行 = +192 net 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-16 23:43:03 +09:00
#[derive(Debug, Clone)]
pub(crate) struct ScheduleDecision {
/// Whether body-init should come before break check
pub body_init_first: bool,
/// Human-readable reason for this decision
pub reason: &'static str,
/// Debug context for logging
pub debug_ctx: ScheduleDebugContext,
}
/// Debug context for schedule decisions
#[derive(Debug, Clone)]
pub(crate) struct ScheduleDebugContext {
pub has_body_local_init: bool,
pub has_loop_local_carrier: bool,
pub has_condition_only_recipe: bool,
pub has_body_local_derived_recipe: bool,
refactor(mir): Phase 93 リファクタリング - 箱化モジュール化 ## 概要 Phase 93 P0実装後のコード整理。スケジュール決定ロジックとbreak semanticsを 明確化し、デバッグログを統一。 ## 変更内容 ### 1. スケジュール決定ロジックの関数化 (step_schedule.rs) - `ScheduleDecision`構造体追加(判定結果+理由+デバッグコンテキスト) - `decide_pattern2_schedule()` - スケジュール決定のSSOT - `build_pattern2_schedule_from_decision()` - 新しい決定ベースAPI - 判定理由が4種類で明確化(ConditionOnly → body-local → loop-local → default) - 後方互換性維持(`Pattern2ScheduleContext`はwrapperに) ### 2. ConditionOnlyRecipe強化 (condition_only_emitter.rs) - `BreakSemantics` enum追加(WhenMatch vs WhenNotMatch) - `generate_break_condition()` - semanticsに基づくAST生成 - `from_trim_helper_condition_only()` - factory method追加 - break semanticsがrecipeに明示的に含まれる ### 3. trim_loop_lowering.rs簡素化 - `generate_condition_only_break_condition()`削除(DRY原則) - `recipe.generate_break_condition()`で統一 - break条件生成ロジックが1箇所に集約 ### 4. デバッグログ統一 - `[phase93/schedule]` - スケジュール決定 - `[phase93/condition-only]` - ConditionOnlyレシピ作成 - `[phase93/break-cond]` - break条件生成 - 既存の`joinir_dev_enabled()`使用(新規env var不要) ## テスト結果 - step_schedule: 10 tests PASS - condition_only_emitter: 4 tests PASS - 後方互換性維持 ## 統計 - 3ファイル変更 - +249行 / -57行 = +192 net 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-16 23:43:03 +09:00
}
/// Facts about Pattern2 that drive step scheduling.
///
/// This struct is intentionally "facts only" (no decision).
#[derive(Debug, Clone)]
pub(crate) struct Pattern2ScheduleFacts {
pub has_body_local_init: bool,
pub has_loop_local_carrier: bool,
pub has_condition_only_recipe: bool,
pub has_body_local_derived_recipe: bool,
}
pub(crate) struct Pattern2ScheduleFactsBox;
impl Pattern2ScheduleFactsBox {
pub(crate) fn gather(
body_local_env: Option<&LoopBodyLocalEnv>,
carrier_info: &CarrierInfo,
has_condition_only_recipe: bool,
has_body_local_derived_recipe: bool,
has_allowed_body_locals_in_conditions: bool,
) -> Pattern2ScheduleFacts {
// NOTE: `body_local_env` may be empty here because it's populated after schedule
// decision (Phase 191 body-local init lowering happens later).
//
// For Phase 92+ patterns where conditions reference allowed body-local variables
// (e.g., `ch == ""`), we must still schedule BodyInit before BreakCheck.
let has_body_local_init = body_local_env.map(|env| !env.is_empty()).unwrap_or(false)
|| has_allowed_body_locals_in_conditions;
let has_loop_local_carrier = carrier_info
.carriers
.iter()
.any(|c| matches!(c.init, CarrierInit::LoopLocalZero));
Pattern2ScheduleFacts {
has_body_local_init,
has_loop_local_carrier,
has_condition_only_recipe,
has_body_local_derived_recipe,
}
}
}
/// Decide Pattern2 schedule based on loop characteristics (SSOT).
refactor(mir): Phase 93 リファクタリング - 箱化モジュール化 ## 概要 Phase 93 P0実装後のコード整理。スケジュール決定ロジックとbreak semanticsを 明確化し、デバッグログを統一。 ## 変更内容 ### 1. スケジュール決定ロジックの関数化 (step_schedule.rs) - `ScheduleDecision`構造体追加(判定結果+理由+デバッグコンテキスト) - `decide_pattern2_schedule()` - スケジュール決定のSSOT - `build_pattern2_schedule_from_decision()` - 新しい決定ベースAPI - 判定理由が4種類で明確化(ConditionOnly → body-local → loop-local → default) - 後方互換性維持(`Pattern2ScheduleContext`はwrapperに) ### 2. ConditionOnlyRecipe強化 (condition_only_emitter.rs) - `BreakSemantics` enum追加(WhenMatch vs WhenNotMatch) - `generate_break_condition()` - semanticsに基づくAST生成 - `from_trim_helper_condition_only()` - factory method追加 - break semanticsがrecipeに明示的に含まれる ### 3. trim_loop_lowering.rs簡素化 - `generate_condition_only_break_condition()`削除(DRY原則) - `recipe.generate_break_condition()`で統一 - break条件生成ロジックが1箇所に集約 ### 4. デバッグログ統一 - `[phase93/schedule]` - スケジュール決定 - `[phase93/condition-only]` - ConditionOnlyレシピ作成 - `[phase93/break-cond]` - break条件生成 - 既存の`joinir_dev_enabled()`使用(新規env var不要) ## テスト結果 - step_schedule: 10 tests PASS - condition_only_emitter: 4 tests PASS - 後方互換性維持 ## 統計 - 3ファイル変更 - +249行 / -57行 = +192 net 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-16 23:43:03 +09:00
///
/// Phase 93 Refactoring: Single source of truth for schedule decisions
///
/// # Decision Logic
///
/// Body-init comes BEFORE break check if any of these conditions are true:
/// 1. ConditionOnly recipe exists (derived slots need recalculation)
/// 2. Body-local variables exist (break condition depends on them)
/// 3. Loop-local carriers exist (need initialization before use)
///
/// # Arguments
///
/// * `body_local_env` - Body-local variable environment
/// * `carrier_info` - Carrier information (for loop-local detection)
/// * `has_condition_only_recipe` - Whether ConditionOnly derived slots exist
///
/// # Returns
///
/// `ScheduleDecision` with decision, reason, and debug context
pub(crate) fn decide_pattern2_schedule(facts: &Pattern2ScheduleFacts) -> ScheduleDecision {
let body_init_first = facts.has_condition_only_recipe
|| facts.has_body_local_derived_recipe
|| facts.has_body_local_init
|| facts.has_loop_local_carrier;
refactor(mir): Phase 93 リファクタリング - 箱化モジュール化 ## 概要 Phase 93 P0実装後のコード整理。スケジュール決定ロジックとbreak semanticsを 明確化し、デバッグログを統一。 ## 変更内容 ### 1. スケジュール決定ロジックの関数化 (step_schedule.rs) - `ScheduleDecision`構造体追加(判定結果+理由+デバッグコンテキスト) - `decide_pattern2_schedule()` - スケジュール決定のSSOT - `build_pattern2_schedule_from_decision()` - 新しい決定ベースAPI - 判定理由が4種類で明確化(ConditionOnly → body-local → loop-local → default) - 後方互換性維持(`Pattern2ScheduleContext`はwrapperに) ### 2. ConditionOnlyRecipe強化 (condition_only_emitter.rs) - `BreakSemantics` enum追加(WhenMatch vs WhenNotMatch) - `generate_break_condition()` - semanticsに基づくAST生成 - `from_trim_helper_condition_only()` - factory method追加 - break semanticsがrecipeに明示的に含まれる ### 3. trim_loop_lowering.rs簡素化 - `generate_condition_only_break_condition()`削除(DRY原則) - `recipe.generate_break_condition()`で統一 - break条件生成ロジックが1箇所に集約 ### 4. デバッグログ統一 - `[phase93/schedule]` - スケジュール決定 - `[phase93/condition-only]` - ConditionOnlyレシピ作成 - `[phase93/break-cond]` - break条件生成 - 既存の`joinir_dev_enabled()`使用(新規env var不要) ## テスト結果 - step_schedule: 10 tests PASS - condition_only_emitter: 4 tests PASS - 後方互換性維持 ## 統計 - 3ファイル変更 - +249行 / -57行 = +192 net 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-16 23:43:03 +09:00
let reason = if facts.has_condition_only_recipe {
refactor(mir): Phase 93 リファクタリング - 箱化モジュール化 ## 概要 Phase 93 P0実装後のコード整理。スケジュール決定ロジックとbreak semanticsを 明確化し、デバッグログを統一。 ## 変更内容 ### 1. スケジュール決定ロジックの関数化 (step_schedule.rs) - `ScheduleDecision`構造体追加(判定結果+理由+デバッグコンテキスト) - `decide_pattern2_schedule()` - スケジュール決定のSSOT - `build_pattern2_schedule_from_decision()` - 新しい決定ベースAPI - 判定理由が4種類で明確化(ConditionOnly → body-local → loop-local → default) - 後方互換性維持(`Pattern2ScheduleContext`はwrapperに) ### 2. ConditionOnlyRecipe強化 (condition_only_emitter.rs) - `BreakSemantics` enum追加(WhenMatch vs WhenNotMatch) - `generate_break_condition()` - semanticsに基づくAST生成 - `from_trim_helper_condition_only()` - factory method追加 - break semanticsがrecipeに明示的に含まれる ### 3. trim_loop_lowering.rs簡素化 - `generate_condition_only_break_condition()`削除(DRY原則) - `recipe.generate_break_condition()`で統一 - break条件生成ロジックが1箇所に集約 ### 4. デバッグログ統一 - `[phase93/schedule]` - スケジュール決定 - `[phase93/condition-only]` - ConditionOnlyレシピ作成 - `[phase93/break-cond]` - break条件生成 - 既存の`joinir_dev_enabled()`使用(新規env var不要) ## テスト結果 - step_schedule: 10 tests PASS - condition_only_emitter: 4 tests PASS - 後方互換性維持 ## 統計 - 3ファイル変更 - +249行 / -57行 = +192 net 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-16 23:43:03 +09:00
"ConditionOnly requires body-init before break"
} else if facts.has_body_local_derived_recipe {
"BodyLocalDerived requires body-init before break"
} else if facts.has_body_local_init {
refactor(mir): Phase 93 リファクタリング - 箱化モジュール化 ## 概要 Phase 93 P0実装後のコード整理。スケジュール決定ロジックとbreak semanticsを 明確化し、デバッグログを統一。 ## 変更内容 ### 1. スケジュール決定ロジックの関数化 (step_schedule.rs) - `ScheduleDecision`構造体追加(判定結果+理由+デバッグコンテキスト) - `decide_pattern2_schedule()` - スケジュール決定のSSOT - `build_pattern2_schedule_from_decision()` - 新しい決定ベースAPI - 判定理由が4種類で明確化(ConditionOnly → body-local → loop-local → default) - 後方互換性維持(`Pattern2ScheduleContext`はwrapperに) ### 2. ConditionOnlyRecipe強化 (condition_only_emitter.rs) - `BreakSemantics` enum追加(WhenMatch vs WhenNotMatch) - `generate_break_condition()` - semanticsに基づくAST生成 - `from_trim_helper_condition_only()` - factory method追加 - break semanticsがrecipeに明示的に含まれる ### 3. trim_loop_lowering.rs簡素化 - `generate_condition_only_break_condition()`削除(DRY原則) - `recipe.generate_break_condition()`で統一 - break条件生成ロジックが1箇所に集約 ### 4. デバッグログ統一 - `[phase93/schedule]` - スケジュール決定 - `[phase93/condition-only]` - ConditionOnlyレシピ作成 - `[phase93/break-cond]` - break条件生成 - 既存の`joinir_dev_enabled()`使用(新規env var不要) ## テスト結果 - step_schedule: 10 tests PASS - condition_only_emitter: 4 tests PASS - 後方互換性維持 ## 統計 - 3ファイル変更 - +249行 / -57行 = +192 net 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-16 23:43:03 +09:00
"body-local variables require init before break"
} else if facts.has_loop_local_carrier {
refactor(mir): Phase 93 リファクタリング - 箱化モジュール化 ## 概要 Phase 93 P0実装後のコード整理。スケジュール決定ロジックとbreak semanticsを 明確化し、デバッグログを統一。 ## 変更内容 ### 1. スケジュール決定ロジックの関数化 (step_schedule.rs) - `ScheduleDecision`構造体追加(判定結果+理由+デバッグコンテキスト) - `decide_pattern2_schedule()` - スケジュール決定のSSOT - `build_pattern2_schedule_from_decision()` - 新しい決定ベースAPI - 判定理由が4種類で明確化(ConditionOnly → body-local → loop-local → default) - 後方互換性維持(`Pattern2ScheduleContext`はwrapperに) ### 2. ConditionOnlyRecipe強化 (condition_only_emitter.rs) - `BreakSemantics` enum追加(WhenMatch vs WhenNotMatch) - `generate_break_condition()` - semanticsに基づくAST生成 - `from_trim_helper_condition_only()` - factory method追加 - break semanticsがrecipeに明示的に含まれる ### 3. trim_loop_lowering.rs簡素化 - `generate_condition_only_break_condition()`削除(DRY原則) - `recipe.generate_break_condition()`で統一 - break条件生成ロジックが1箇所に集約 ### 4. デバッグログ統一 - `[phase93/schedule]` - スケジュール決定 - `[phase93/condition-only]` - ConditionOnlyレシピ作成 - `[phase93/break-cond]` - break条件生成 - 既存の`joinir_dev_enabled()`使用(新規env var不要) ## テスト結果 - step_schedule: 10 tests PASS - condition_only_emitter: 4 tests PASS - 後方互換性維持 ## 統計 - 3ファイル変更 - +249行 / -57行 = +192 net 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-16 23:43:03 +09:00
"loop-local carrier requires init before break"
} else {
"default schedule"
};
ScheduleDecision {
body_init_first,
reason,
debug_ctx: ScheduleDebugContext {
has_body_local_init: facts.has_body_local_init,
has_loop_local_carrier: facts.has_loop_local_carrier,
has_condition_only_recipe: facts.has_condition_only_recipe,
has_body_local_derived_recipe: facts.has_body_local_derived_recipe,
refactor(mir): Phase 93 リファクタリング - 箱化モジュール化 ## 概要 Phase 93 P0実装後のコード整理。スケジュール決定ロジックとbreak semanticsを 明確化し、デバッグログを統一。 ## 変更内容 ### 1. スケジュール決定ロジックの関数化 (step_schedule.rs) - `ScheduleDecision`構造体追加(判定結果+理由+デバッグコンテキスト) - `decide_pattern2_schedule()` - スケジュール決定のSSOT - `build_pattern2_schedule_from_decision()` - 新しい決定ベースAPI - 判定理由が4種類で明確化(ConditionOnly → body-local → loop-local → default) - 後方互換性維持(`Pattern2ScheduleContext`はwrapperに) ### 2. ConditionOnlyRecipe強化 (condition_only_emitter.rs) - `BreakSemantics` enum追加(WhenMatch vs WhenNotMatch) - `generate_break_condition()` - semanticsに基づくAST生成 - `from_trim_helper_condition_only()` - factory method追加 - break semanticsがrecipeに明示的に含まれる ### 3. trim_loop_lowering.rs簡素化 - `generate_condition_only_break_condition()`削除(DRY原則) - `recipe.generate_break_condition()`で統一 - break条件生成ロジックが1箇所に集約 ### 4. デバッグログ統一 - `[phase93/schedule]` - スケジュール決定 - `[phase93/condition-only]` - ConditionOnlyレシピ作成 - `[phase93/break-cond]` - break条件生成 - 既存の`joinir_dev_enabled()`使用(新規env var不要) ## テスト結果 - step_schedule: 10 tests PASS - condition_only_emitter: 4 tests PASS - 後方互換性維持 ## 統計 - 3ファイル変更 - +249行 / -57行 = +192 net 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-16 23:43:03 +09:00
},
}
}
/// Build a schedule for Pattern 2 lowering.
///
refactor(mir): Phase 93 リファクタリング - 箱化モジュール化 ## 概要 Phase 93 P0実装後のコード整理。スケジュール決定ロジックとbreak semanticsを 明確化し、デバッグログを統一。 ## 変更内容 ### 1. スケジュール決定ロジックの関数化 (step_schedule.rs) - `ScheduleDecision`構造体追加(判定結果+理由+デバッグコンテキスト) - `decide_pattern2_schedule()` - スケジュール決定のSSOT - `build_pattern2_schedule_from_decision()` - 新しい決定ベースAPI - 判定理由が4種類で明確化(ConditionOnly → body-local → loop-local → default) - 後方互換性維持(`Pattern2ScheduleContext`はwrapperに) ### 2. ConditionOnlyRecipe強化 (condition_only_emitter.rs) - `BreakSemantics` enum追加(WhenMatch vs WhenNotMatch) - `generate_break_condition()` - semanticsに基づくAST生成 - `from_trim_helper_condition_only()` - factory method追加 - break semanticsがrecipeに明示的に含まれる ### 3. trim_loop_lowering.rs簡素化 - `generate_condition_only_break_condition()`削除(DRY原則) - `recipe.generate_break_condition()`で統一 - break条件生成ロジックが1箇所に集約 ### 4. デバッグログ統一 - `[phase93/schedule]` - スケジュール決定 - `[phase93/condition-only]` - ConditionOnlyレシピ作成 - `[phase93/break-cond]` - break条件生成 - 既存の`joinir_dev_enabled()`使用(新規env var不要) ## テスト結果 - step_schedule: 10 tests PASS - condition_only_emitter: 4 tests PASS - 後方互換性維持 ## 統計 - 3ファイル変更 - +249行 / -57行 = +192 net 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-16 23:43:03 +09:00
/// - Default P2: header → break → body-init → updates → tail
/// - Body-local break dependency (DigitPos/_atoi style):
/// header → body-init → break → updates → tail
pub(crate) fn build_pattern2_schedule_from_decision(
decision: &ScheduleDecision,
) -> Pattern2StepSchedule {
let schedule = if decision.body_init_first {
Pattern2StepSchedule {
steps: vec![
Pattern2StepKind::HeaderCond,
Pattern2StepKind::BodyInit,
Pattern2StepKind::BreakCheck,
Pattern2StepKind::Updates,
Pattern2StepKind::Tail,
],
reason: decision.reason,
}
} else {
Pattern2StepSchedule {
steps: vec![
Pattern2StepKind::HeaderCond,
Pattern2StepKind::BreakCheck,
Pattern2StepKind::BodyInit,
Pattern2StepKind::Updates,
Pattern2StepKind::Tail,
],
reason: decision.reason,
}
};
log_schedule_from_decision(decision, &schedule);
schedule
}
fn log_schedule_from_decision(decision: &ScheduleDecision, schedule: &Pattern2StepSchedule) {
if !(env::joinir_dev_enabled() || joinir_test_debug_enabled()) {
return;
}
let steps_desc = schedule
.steps()
.iter()
.map(Pattern2StepKind::as_str)
.collect::<Vec<_>>()
.join(" -> ");
eprintln!(
"[phase93/schedule] steps={} reason={} ctx={{body_local_init={}, loop_local_carrier={}, condition_only={}, body_local_derived={}}}",
refactor(mir): Phase 93 リファクタリング - 箱化モジュール化 ## 概要 Phase 93 P0実装後のコード整理。スケジュール決定ロジックとbreak semanticsを 明確化し、デバッグログを統一。 ## 変更内容 ### 1. スケジュール決定ロジックの関数化 (step_schedule.rs) - `ScheduleDecision`構造体追加(判定結果+理由+デバッグコンテキスト) - `decide_pattern2_schedule()` - スケジュール決定のSSOT - `build_pattern2_schedule_from_decision()` - 新しい決定ベースAPI - 判定理由が4種類で明確化(ConditionOnly → body-local → loop-local → default) - 後方互換性維持(`Pattern2ScheduleContext`はwrapperに) ### 2. ConditionOnlyRecipe強化 (condition_only_emitter.rs) - `BreakSemantics` enum追加(WhenMatch vs WhenNotMatch) - `generate_break_condition()` - semanticsに基づくAST生成 - `from_trim_helper_condition_only()` - factory method追加 - break semanticsがrecipeに明示的に含まれる ### 3. trim_loop_lowering.rs簡素化 - `generate_condition_only_break_condition()`削除(DRY原則) - `recipe.generate_break_condition()`で統一 - break条件生成ロジックが1箇所に集約 ### 4. デバッグログ統一 - `[phase93/schedule]` - スケジュール決定 - `[phase93/condition-only]` - ConditionOnlyレシピ作成 - `[phase93/break-cond]` - break条件生成 - 既存の`joinir_dev_enabled()`使用(新規env var不要) ## テスト結果 - step_schedule: 10 tests PASS - condition_only_emitter: 4 tests PASS - 後方互換性維持 ## 統計 - 3ファイル変更 - +249行 / -57行 = +192 net 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-16 23:43:03 +09:00
steps_desc,
schedule.reason(),
decision.debug_ctx.has_body_local_init,
decision.debug_ctx.has_loop_local_carrier,
decision.debug_ctx.has_condition_only_recipe,
decision.debug_ctx.has_body_local_derived_recipe
);
}
feat(joinir): Phase 47-A-IMPL - P3 Normalized infrastructure Implement Pattern3 (if-sum) Normalized infrastructure, extending existing P2 StepSchedule and ShapeGuard systems. Key changes: 1. StepSchedule generalization (P2 → P2/P3): - Renamed: pattern2_step_schedule.rs → step_schedule.rs - Extended StepKind enum with P3 variants: - IfCond (if condition in body) - ThenUpdates (carrier updates in then branch) - ElseUpdates (carrier updates in else branch) - Added pattern3_if_sum_schedule() function - Added unit test: test_pattern3_if_sum_schedule() - Updated module references (mod.rs, loop_with_break_minimal.rs) 2. ShapeGuard extension: - Added Pattern3IfSumMinimal variant to NormalizedDevShape - Added is_pattern3_if_sum_minimal() detector (placeholder) - Updated shape detector table - Extended capability_for_shape() mapping 3. Bridge integration: - bridge.rs: Added P3 shape handling in normalize_for_shape() - normalized.rs: Added P3 roundtrip match (uses P2 temporarily) 4. P2/P3 separation: - loop_with_break_minimal.rs: Added panic for P3 steps in P2 lowering - Clear boundary enforcement (P2 lowerer rejects P3 steps) 5. Documentation: - CURRENT_TASK.md: Phase 47-A-IMPL status - phase47-norm-p3-design.md: Implementation status section Benefits: - Reuses 90% of P2 infrastructure (ConditionEnv, CarrierInfo, ExitLine) - Clean P2/P3 separation via StepKind - Pure additive changes (no P2 behavioral changes) - Ready for Phase 47-A-LOWERING (full P3 Normalized implementation) Tests: 938/938 PASS (+1 from step_schedule unit test) - All existing P1/P2 tests pass (no regressions) - P3 test uses Structured path temporarily (proper lowering in next phase) Next phase: Implement full P3 Normalized→MIR(direct) lowering
2025-12-12 05:23:18 +09:00
/// Phase 47-A: Generate step schedule for Pattern3 (if-sum) loops
#[allow(dead_code)]
feat(joinir): Phase 47-A-IMPL - P3 Normalized infrastructure Implement Pattern3 (if-sum) Normalized infrastructure, extending existing P2 StepSchedule and ShapeGuard systems. Key changes: 1. StepSchedule generalization (P2 → P2/P3): - Renamed: pattern2_step_schedule.rs → step_schedule.rs - Extended StepKind enum with P3 variants: - IfCond (if condition in body) - ThenUpdates (carrier updates in then branch) - ElseUpdates (carrier updates in else branch) - Added pattern3_if_sum_schedule() function - Added unit test: test_pattern3_if_sum_schedule() - Updated module references (mod.rs, loop_with_break_minimal.rs) 2. ShapeGuard extension: - Added Pattern3IfSumMinimal variant to NormalizedDevShape - Added is_pattern3_if_sum_minimal() detector (placeholder) - Updated shape detector table - Extended capability_for_shape() mapping 3. Bridge integration: - bridge.rs: Added P3 shape handling in normalize_for_shape() - normalized.rs: Added P3 roundtrip match (uses P2 temporarily) 4. P2/P3 separation: - loop_with_break_minimal.rs: Added panic for P3 steps in P2 lowering - Clear boundary enforcement (P2 lowerer rejects P3 steps) 5. Documentation: - CURRENT_TASK.md: Phase 47-A-IMPL status - phase47-norm-p3-design.md: Implementation status section Benefits: - Reuses 90% of P2 infrastructure (ConditionEnv, CarrierInfo, ExitLine) - Clean P2/P3 separation via StepKind - Pure additive changes (no P2 behavioral changes) - Ready for Phase 47-A-LOWERING (full P3 Normalized implementation) Tests: 938/938 PASS (+1 from step_schedule unit test) - All existing P1/P2 tests pass (no regressions) - P3 test uses Structured path temporarily (proper lowering in next phase) Next phase: Implement full P3 Normalized→MIR(direct) lowering
2025-12-12 05:23:18 +09:00
pub(crate) fn pattern3_if_sum_schedule() -> Vec<Pattern2StepKind> {
vec![
Pattern2StepKind::HeaderCond, // loop(i < n)
Pattern2StepKind::IfCond, // if (i > 0)
Pattern2StepKind::ThenUpdates, // sum = sum + i
feat(joinir): Phase 47-A-IMPL - P3 Normalized infrastructure Implement Pattern3 (if-sum) Normalized infrastructure, extending existing P2 StepSchedule and ShapeGuard systems. Key changes: 1. StepSchedule generalization (P2 → P2/P3): - Renamed: pattern2_step_schedule.rs → step_schedule.rs - Extended StepKind enum with P3 variants: - IfCond (if condition in body) - ThenUpdates (carrier updates in then branch) - ElseUpdates (carrier updates in else branch) - Added pattern3_if_sum_schedule() function - Added unit test: test_pattern3_if_sum_schedule() - Updated module references (mod.rs, loop_with_break_minimal.rs) 2. ShapeGuard extension: - Added Pattern3IfSumMinimal variant to NormalizedDevShape - Added is_pattern3_if_sum_minimal() detector (placeholder) - Updated shape detector table - Extended capability_for_shape() mapping 3. Bridge integration: - bridge.rs: Added P3 shape handling in normalize_for_shape() - normalized.rs: Added P3 roundtrip match (uses P2 temporarily) 4. P2/P3 separation: - loop_with_break_minimal.rs: Added panic for P3 steps in P2 lowering - Clear boundary enforcement (P2 lowerer rejects P3 steps) 5. Documentation: - CURRENT_TASK.md: Phase 47-A-IMPL status - phase47-norm-p3-design.md: Implementation status section Benefits: - Reuses 90% of P2 infrastructure (ConditionEnv, CarrierInfo, ExitLine) - Clean P2/P3 separation via StepKind - Pure additive changes (no P2 behavioral changes) - Ready for Phase 47-A-LOWERING (full P3 Normalized implementation) Tests: 938/938 PASS (+1 from step_schedule unit test) - All existing P1/P2 tests pass (no regressions) - P3 test uses Structured path temporarily (proper lowering in next phase) Next phase: Implement full P3 Normalized→MIR(direct) lowering
2025-12-12 05:23:18 +09:00
// ElseUpdates omitted for minimal (no else branch)
Pattern2StepKind::Tail, // i = i + 1
feat(joinir): Phase 47-A-IMPL - P3 Normalized infrastructure Implement Pattern3 (if-sum) Normalized infrastructure, extending existing P2 StepSchedule and ShapeGuard systems. Key changes: 1. StepSchedule generalization (P2 → P2/P3): - Renamed: pattern2_step_schedule.rs → step_schedule.rs - Extended StepKind enum with P3 variants: - IfCond (if condition in body) - ThenUpdates (carrier updates in then branch) - ElseUpdates (carrier updates in else branch) - Added pattern3_if_sum_schedule() function - Added unit test: test_pattern3_if_sum_schedule() - Updated module references (mod.rs, loop_with_break_minimal.rs) 2. ShapeGuard extension: - Added Pattern3IfSumMinimal variant to NormalizedDevShape - Added is_pattern3_if_sum_minimal() detector (placeholder) - Updated shape detector table - Extended capability_for_shape() mapping 3. Bridge integration: - bridge.rs: Added P3 shape handling in normalize_for_shape() - normalized.rs: Added P3 roundtrip match (uses P2 temporarily) 4. P2/P3 separation: - loop_with_break_minimal.rs: Added panic for P3 steps in P2 lowering - Clear boundary enforcement (P2 lowerer rejects P3 steps) 5. Documentation: - CURRENT_TASK.md: Phase 47-A-IMPL status - phase47-norm-p3-design.md: Implementation status section Benefits: - Reuses 90% of P2 infrastructure (ConditionEnv, CarrierInfo, ExitLine) - Clean P2/P3 separation via StepKind - Pure additive changes (no P2 behavioral changes) - Ready for Phase 47-A-LOWERING (full P3 Normalized implementation) Tests: 938/938 PASS (+1 from step_schedule unit test) - All existing P1/P2 tests pass (no regressions) - P3 test uses Structured path temporarily (proper lowering in next phase) Next phase: Implement full P3 Normalized→MIR(direct) lowering
2025-12-12 05:23:18 +09:00
]
}
feat(joinir): Phase 48-A - P4 (continue) Normalized minimal implementation Pattern4 (continue) integration into Normalized JoinIR pipeline complete. Key changes: - P4 minimal fixture: skip i==2 pattern, single carrier (acc) - ShapeGuard: Pattern4ContinueMinimal detector (structure-based) - StepScheduleBox: ContinueCheck step (eval order: HeaderCond → ContinueCheck → Updates → Tail) - normalize_pattern4_continue_minimal(): Delegates to P2 (95% infrastructure reuse) - Tests: 4 integration tests (normalization/runner/VM Bridge comparison×2) Design validation: - P4 (continue) = reverse control flow of P2 (break) - Same loop_step(env, k_exit) skeleton - Same EnvLayout/ConditionEnv/CarrierInfo infrastructure - Only difference: evaluation order and control flow direction Architecture proof: - Normalized JoinIR successfully handles P1/P2/P3/P4 uniformly - Infrastructure reuse rate: 95%+ as designed Tests: 939/939 PASS (+1 from baseline 938, target exceeded!) Files modified: 10 files (~305 lines added, pure additive) - pattern4_continue_min.program.json (NEW +126 lines) - P4 fixture - fixtures.rs (+31 lines) - P4 fixture loader - shape_guard.rs (+60 lines) - Shape detection - step_schedule.rs (+18 lines) - Schedule + test - normalized.rs (+35 lines) - Normalization function - loop_with_break_minimal.rs (+4 lines) - ContinueCheck handler - bridge.rs (+5 lines) - VM bridge routing - ast_lowerer/mod.rs (+2 lines) - Function registration - normalized_joinir_min.rs (+84 lines) - Integration tests - CURRENT_TASK.md (+13 lines) - Phase 48-A completion Next steps: - Phase 48-B: Extended P4 (multi-carrier, complex continue) - Phase 48-C: Canonical promotion (always use Normalized for P4)
2025-12-12 06:31:13 +09:00
/// Phase 48-A: Generate step schedule for Pattern4 (continue) loops
#[allow(dead_code)]
feat(joinir): Phase 48-A - P4 (continue) Normalized minimal implementation Pattern4 (continue) integration into Normalized JoinIR pipeline complete. Key changes: - P4 minimal fixture: skip i==2 pattern, single carrier (acc) - ShapeGuard: Pattern4ContinueMinimal detector (structure-based) - StepScheduleBox: ContinueCheck step (eval order: HeaderCond → ContinueCheck → Updates → Tail) - normalize_pattern4_continue_minimal(): Delegates to P2 (95% infrastructure reuse) - Tests: 4 integration tests (normalization/runner/VM Bridge comparison×2) Design validation: - P4 (continue) = reverse control flow of P2 (break) - Same loop_step(env, k_exit) skeleton - Same EnvLayout/ConditionEnv/CarrierInfo infrastructure - Only difference: evaluation order and control flow direction Architecture proof: - Normalized JoinIR successfully handles P1/P2/P3/P4 uniformly - Infrastructure reuse rate: 95%+ as designed Tests: 939/939 PASS (+1 from baseline 938, target exceeded!) Files modified: 10 files (~305 lines added, pure additive) - pattern4_continue_min.program.json (NEW +126 lines) - P4 fixture - fixtures.rs (+31 lines) - P4 fixture loader - shape_guard.rs (+60 lines) - Shape detection - step_schedule.rs (+18 lines) - Schedule + test - normalized.rs (+35 lines) - Normalization function - loop_with_break_minimal.rs (+4 lines) - ContinueCheck handler - bridge.rs (+5 lines) - VM bridge routing - ast_lowerer/mod.rs (+2 lines) - Function registration - normalized_joinir_min.rs (+84 lines) - Integration tests - CURRENT_TASK.md (+13 lines) - Phase 48-A completion Next steps: - Phase 48-B: Extended P4 (multi-carrier, complex continue) - Phase 48-C: Canonical promotion (always use Normalized for P4)
2025-12-12 06:31:13 +09:00
pub(crate) fn pattern4_continue_schedule() -> Vec<Pattern2StepKind> {
vec![
Pattern2StepKind::HeaderCond, // loop(i < n)
Pattern2StepKind::ContinueCheck, // if (i == 2) continue (skip processing)
Pattern2StepKind::Updates, // count = count + 1 (processing)
Pattern2StepKind::Tail, // i = i + 1
]
}
#[cfg(test)]
mod tests {
use super::*;
use crate::mir::join_ir::lowering::carrier_info::{CarrierRole, CarrierVar};
use crate::mir::ValueId;
fn carrier(loop_local: bool) -> CarrierVar {
let init = if loop_local {
CarrierInit::LoopLocalZero
} else {
CarrierInit::FromHost
};
CarrierVar::with_role_and_init("c".to_string(), ValueId(1), CarrierRole::LoopState, init)
}
fn carrier_info(carriers: Vec<CarrierVar>) -> CarrierInfo {
CarrierInfo {
loop_var_name: "i".to_string(),
loop_var_id: ValueId(0),
carriers,
trim_helper: None,
promoted_loopbodylocals: vec![],
#[cfg(feature = "normalized_dev")]
promoted_bindings: std::collections::BTreeMap::new(),
}
}
#[test]
fn default_schedule_break_before_body_init() {
let facts = Pattern2ScheduleFactsBox::gather(None, &carrier_info(vec![]), false, false, false);
let decision = decide_pattern2_schedule(&facts);
let schedule = build_pattern2_schedule_from_decision(&decision);
assert_eq!(
schedule.steps(),
&[
Pattern2StepKind::HeaderCond,
Pattern2StepKind::BreakCheck,
Pattern2StepKind::BodyInit,
Pattern2StepKind::Updates,
Pattern2StepKind::Tail
]
);
assert_eq!(schedule.reason(), "default schedule");
}
#[test]
fn body_local_moves_init_before_break() {
let mut body_env = LoopBodyLocalEnv::new();
body_env.insert("tmp".to_string(), ValueId(5));
let facts = Pattern2ScheduleFactsBox::gather(
Some(&body_env),
&carrier_info(vec![carrier(false)]),
false,
false,
false,
);
let decision = decide_pattern2_schedule(&facts);
let schedule = build_pattern2_schedule_from_decision(&decision);
assert_eq!(
schedule.steps(),
&[
Pattern2StepKind::HeaderCond,
Pattern2StepKind::BodyInit,
Pattern2StepKind::BreakCheck,
Pattern2StepKind::Updates,
Pattern2StepKind::Tail
]
);
assert_eq!(schedule.reason(), "body-local variables require init before break");
}
#[test]
fn loop_local_carrier_triggers_body_first() {
let facts =
Pattern2ScheduleFactsBox::gather(None, &carrier_info(vec![carrier(true)]), false, false, false);
let decision = decide_pattern2_schedule(&facts);
let schedule = build_pattern2_schedule_from_decision(&decision);
assert_eq!(
schedule.steps(),
&[
Pattern2StepKind::HeaderCond,
Pattern2StepKind::BodyInit,
Pattern2StepKind::BreakCheck,
Pattern2StepKind::Updates,
Pattern2StepKind::Tail
]
);
assert_eq!(schedule.reason(), "loop-local carrier requires init before break");
}
/// Phase 93 P0: ConditionOnly recipe triggers body-init before break
#[test]
fn condition_only_recipe_triggers_body_first() {
// Empty body_local_env but has condition_only_recipe
let facts = Pattern2ScheduleFactsBox::gather(None, &carrier_info(vec![]), true, false, false);
let decision = decide_pattern2_schedule(&facts);
let schedule = build_pattern2_schedule_from_decision(&decision);
assert_eq!(
schedule.steps(),
&[
Pattern2StepKind::HeaderCond,
Pattern2StepKind::BodyInit,
Pattern2StepKind::BreakCheck,
Pattern2StepKind::Updates,
Pattern2StepKind::Tail
]
);
assert_eq!(schedule.reason(), "ConditionOnly requires body-init before break");
}
feat(joinir): Phase 47-A-IMPL - P3 Normalized infrastructure Implement Pattern3 (if-sum) Normalized infrastructure, extending existing P2 StepSchedule and ShapeGuard systems. Key changes: 1. StepSchedule generalization (P2 → P2/P3): - Renamed: pattern2_step_schedule.rs → step_schedule.rs - Extended StepKind enum with P3 variants: - IfCond (if condition in body) - ThenUpdates (carrier updates in then branch) - ElseUpdates (carrier updates in else branch) - Added pattern3_if_sum_schedule() function - Added unit test: test_pattern3_if_sum_schedule() - Updated module references (mod.rs, loop_with_break_minimal.rs) 2. ShapeGuard extension: - Added Pattern3IfSumMinimal variant to NormalizedDevShape - Added is_pattern3_if_sum_minimal() detector (placeholder) - Updated shape detector table - Extended capability_for_shape() mapping 3. Bridge integration: - bridge.rs: Added P3 shape handling in normalize_for_shape() - normalized.rs: Added P3 roundtrip match (uses P2 temporarily) 4. P2/P3 separation: - loop_with_break_minimal.rs: Added panic for P3 steps in P2 lowering - Clear boundary enforcement (P2 lowerer rejects P3 steps) 5. Documentation: - CURRENT_TASK.md: Phase 47-A-IMPL status - phase47-norm-p3-design.md: Implementation status section Benefits: - Reuses 90% of P2 infrastructure (ConditionEnv, CarrierInfo, ExitLine) - Clean P2/P3 separation via StepKind - Pure additive changes (no P2 behavioral changes) - Ready for Phase 47-A-LOWERING (full P3 Normalized implementation) Tests: 938/938 PASS (+1 from step_schedule unit test) - All existing P1/P2 tests pass (no regressions) - P3 test uses Structured path temporarily (proper lowering in next phase) Next phase: Implement full P3 Normalized→MIR(direct) lowering
2025-12-12 05:23:18 +09:00
#[test]
fn allowed_body_local_deps_trigger_body_first_even_if_env_empty() {
let facts = Pattern2ScheduleFactsBox::gather(None, &carrier_info(vec![]), false, false, true);
let decision = decide_pattern2_schedule(&facts);
let schedule = build_pattern2_schedule_from_decision(&decision);
assert_eq!(
schedule.steps(),
&[
Pattern2StepKind::HeaderCond,
Pattern2StepKind::BodyInit,
Pattern2StepKind::BreakCheck,
Pattern2StepKind::Updates,
Pattern2StepKind::Tail
]
);
assert_eq!(schedule.reason(), "body-local variables require init before break");
}
feat(joinir): Phase 47-A-IMPL - P3 Normalized infrastructure Implement Pattern3 (if-sum) Normalized infrastructure, extending existing P2 StepSchedule and ShapeGuard systems. Key changes: 1. StepSchedule generalization (P2 → P2/P3): - Renamed: pattern2_step_schedule.rs → step_schedule.rs - Extended StepKind enum with P3 variants: - IfCond (if condition in body) - ThenUpdates (carrier updates in then branch) - ElseUpdates (carrier updates in else branch) - Added pattern3_if_sum_schedule() function - Added unit test: test_pattern3_if_sum_schedule() - Updated module references (mod.rs, loop_with_break_minimal.rs) 2. ShapeGuard extension: - Added Pattern3IfSumMinimal variant to NormalizedDevShape - Added is_pattern3_if_sum_minimal() detector (placeholder) - Updated shape detector table - Extended capability_for_shape() mapping 3. Bridge integration: - bridge.rs: Added P3 shape handling in normalize_for_shape() - normalized.rs: Added P3 roundtrip match (uses P2 temporarily) 4. P2/P3 separation: - loop_with_break_minimal.rs: Added panic for P3 steps in P2 lowering - Clear boundary enforcement (P2 lowerer rejects P3 steps) 5. Documentation: - CURRENT_TASK.md: Phase 47-A-IMPL status - phase47-norm-p3-design.md: Implementation status section Benefits: - Reuses 90% of P2 infrastructure (ConditionEnv, CarrierInfo, ExitLine) - Clean P2/P3 separation via StepKind - Pure additive changes (no P2 behavioral changes) - Ready for Phase 47-A-LOWERING (full P3 Normalized implementation) Tests: 938/938 PASS (+1 from step_schedule unit test) - All existing P1/P2 tests pass (no regressions) - P3 test uses Structured path temporarily (proper lowering in next phase) Next phase: Implement full P3 Normalized→MIR(direct) lowering
2025-12-12 05:23:18 +09:00
#[test]
fn test_pattern3_if_sum_schedule() {
let schedule = pattern3_if_sum_schedule();
assert_eq!(schedule.len(), 4);
assert_eq!(schedule[0], Pattern2StepKind::HeaderCond);
assert_eq!(schedule[1], Pattern2StepKind::IfCond);
assert_eq!(schedule[2], Pattern2StepKind::ThenUpdates);
assert_eq!(schedule[3], Pattern2StepKind::Tail);
}
feat(joinir): Phase 48-A - P4 (continue) Normalized minimal implementation Pattern4 (continue) integration into Normalized JoinIR pipeline complete. Key changes: - P4 minimal fixture: skip i==2 pattern, single carrier (acc) - ShapeGuard: Pattern4ContinueMinimal detector (structure-based) - StepScheduleBox: ContinueCheck step (eval order: HeaderCond → ContinueCheck → Updates → Tail) - normalize_pattern4_continue_minimal(): Delegates to P2 (95% infrastructure reuse) - Tests: 4 integration tests (normalization/runner/VM Bridge comparison×2) Design validation: - P4 (continue) = reverse control flow of P2 (break) - Same loop_step(env, k_exit) skeleton - Same EnvLayout/ConditionEnv/CarrierInfo infrastructure - Only difference: evaluation order and control flow direction Architecture proof: - Normalized JoinIR successfully handles P1/P2/P3/P4 uniformly - Infrastructure reuse rate: 95%+ as designed Tests: 939/939 PASS (+1 from baseline 938, target exceeded!) Files modified: 10 files (~305 lines added, pure additive) - pattern4_continue_min.program.json (NEW +126 lines) - P4 fixture - fixtures.rs (+31 lines) - P4 fixture loader - shape_guard.rs (+60 lines) - Shape detection - step_schedule.rs (+18 lines) - Schedule + test - normalized.rs (+35 lines) - Normalization function - loop_with_break_minimal.rs (+4 lines) - ContinueCheck handler - bridge.rs (+5 lines) - VM bridge routing - ast_lowerer/mod.rs (+2 lines) - Function registration - normalized_joinir_min.rs (+84 lines) - Integration tests - CURRENT_TASK.md (+13 lines) - Phase 48-A completion Next steps: - Phase 48-B: Extended P4 (multi-carrier, complex continue) - Phase 48-C: Canonical promotion (always use Normalized for P4)
2025-12-12 06:31:13 +09:00
#[test]
fn test_pattern4_continue_schedule() {
let schedule = pattern4_continue_schedule();
assert_eq!(schedule.len(), 4);
assert_eq!(schedule[0], Pattern2StepKind::HeaderCond);
assert_eq!(schedule[1], Pattern2StepKind::ContinueCheck);
assert_eq!(schedule[2], Pattern2StepKind::Updates);
assert_eq!(schedule[3], Pattern2StepKind::Tail);
}
}