Files
hakorune/docs/development/current/main/phase33-16-INDEX.md
nyash-codex a7dbc15878 feat(joinir): Phase 240-EX - Pattern2 header condition ExprLowerer integration
Implementation:
- Add make_pattern2_scope_manager() helper for DRY
- Header conditions use ExprLowerer for supported patterns
- Legacy fallback for unsupported patterns
- Fail-Fast on supported patterns that fail

Tests:
- 4 new tests (all pass)
- test_expr_lowerer_supports_simple_header_condition_i_less_literal
- test_expr_lowerer_supports_header_condition_var_less_var
- test_expr_lowerer_header_condition_generates_expected_instructions
- test_pattern2_header_condition_via_exprlowerer

Also: Archive old phase documentation (34k lines removed)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 00:33:04 +09:00

8.7 KiB
Raw Blame History

Status: Active
Scope: Phase 33-16Loop Header PHI SSOTに関する現役目次。歴史詳細は archive 側を参照。

Phase 33-16: Loop Header PHI SSOT - Documentation Index

Last Updated: 2025-12-07
Status: Complete implementation design ready

Quick Navigation

For Implementation

Start here: phase33-16-visual-guide.md

  • Architecture flow diagram (all 7 phases)
  • Code change map with exact line numbers
  • 7 complete code changes (copy-paste ready)
  • Testing commands

For Understanding

Read first: phase33-16-qa.md

  • Answer to all 5 core questions
  • Exact code snippets with explanations
  • "What you DON'T need" guidance
  • Complete flow summary

For Context

Detailed planning: phase33-16-implementation-plan.md

  • Executive summary
  • Problem analysis
  • 6 concrete implementation steps
  • Testing strategy
  • Risk analysis and mitigation
  • Future enhancements

Quick Summary

Reference: PHASE_33_16_SUMMARY.md

  • TL;DR answers
  • Architecture evolution
  • Implementation scope
  • Key architectural insight
  • Testing roadmap

Original Design

Background: phase33-16-loop-header-phi-design.md

  • Original design document
  • Problem statement
  • Solution overview

Your 5 Questions - Direct Answers

Q1: Where exactly should LoopHeaderPhiBuilder::build() be called?

Location: src/mir/builder/control_flow/joinir/merge/mod.rs, line 107 When: Between Phase 3 (remap_values) and Phase 4 (instruction_rewriter) Why: Phase 3.5 allocates PHI dsts before instruction_rewriter needs them Details: phase33-16-qa.md#q1

Q2: How do I get the header_block_id (loop_step's entry block after remapping)?

Code: remapper.get_block(entry_func_name, entry_func.entry_block)? Key: Entry block is the loop header for Pattern 2 Details: phase33-16-qa.md#q2

Q3: How do I get the loop variable's initial value (host-side)?

Code: remapper.get_value(ValueId(0))? Key: ValueId(0) is always the loop parameter in JoinIR space Details: phase33-16-qa.md#q3

Q4: Where should instruction_rewriter record latch_incoming?

Location: src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs, ~line 300 When: In tail call section, after parameter bindings Code: loop_header_phi_info.set_latch_incoming(loop_var_name, target_block, latch_value) Details: phase33-16-qa.md#q4

Q5: Should the Phase 33-15 skip logic be removed or modified?

Answer: Modify, NOT remove Strategy: Use header PHI dst when available, fallback to parameter Details: phase33-16-qa.md#q5


Implementation at a Glance

Files to Modify

  • src/mir/builder/control_flow/joinir/merge/mod.rs (2 locations: Phase 3.5, Phase 4.5)
  • src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs (5 locations: signature, latch tracking, exit logic)

Changes Summary

Phase What Where Type
3.5 Build header PHIs merge/mod.rs New
4 Update signature instruction_rewriter.rs Signature
4 Track latch instruction_rewriter.rs New code
4 Use PHI for exit instruction_rewriter.rs Modified
4 Use PHI for carriers instruction_rewriter.rs Modified
4.5 Finalize PHIs merge/mod.rs New

Scope

  • Lines added: ~100
  • Lines modified: ~100
  • Lines removed: 0 (backward compatible)
  • New files: 0 (uses existing LoopHeaderPhiBuilder)

Architecture Diagram

Phase 3: remap_values()
  ↓ (ValueIds remapped: 0→100, 0→101, etc.)
Phase 3.5: LoopHeaderPhiBuilder::build() ⭐ NEW
  └── Allocate phi_dst(101), entry_incoming(init_value)
  └── Pass loop_header_phi_info to Phase 4
Phase 4: instruction_rewriter::merge_and_rewrite()
  ├── When tail call: set_latch_incoming()
  └── When Return: use phi_dst (not parameter)
Phase 4.5: LoopHeaderPhiBuilder::finalize() ⭐ NEW
  └── Emit PHIs into header block
Phase 5: exit_phi_builder::build_exit_phi()
  └── Return carrier_phis with header PHI dsts
Phase 6: ExitLineOrchestrator::execute()
  └── Update variable_map with carrier_phis

Testing Checklist

Before implementation:

  • Review phase33-16-qa.md (answers to your questions)
  • Review phase33-16-visual-guide.md (code locations)
  • Baseline compile: cargo build --release

During implementation:

  • Implement Phase 3.5 → compile
  • Update signature → compile
  • Add latch tracking → compile
  • Replace exit_phi_inputs → compile
  • Replace carrier_inputs → compile
  • Add Phase 4.5 → compile
  • Update docs → compile

After implementation:

  • NYASH_JOINIR_DEBUG=1 ./target/release/nyash --dump-mir test.hako | grep "Phase 33-16"
  • Verify header block has PHI instructions at start
  • Verify exit values reference header PHI dsts
  • Test: joinir_min_loop.hako produces correct MIR
  • Test: Loop variable values correct at exit

Complete Guides (in order of use)

  1. phase33-16-qa.md (11 KB)

    • Start here for understanding
    • All 5 questions answered
    • Code examples ready to copy-paste
  2. phase33-16-visual-guide.md (22 KB)

    • Use during implementation
    • Architecture diagrams
    • Complete code changes with line numbers
    • Copy-paste ready code
  3. phase33-16-implementation-plan.md (18 KB)

    • For detailed planning
    • Risk analysis
    • Testing strategy
    • Future enhancements
  4. PHASE_33_16_SUMMARY.md (8.2 KB)

    • Quick reference
    • TL;DR answers
    • Key insights
    • Next steps

Reference Documents

  1. phase33-16-loop-header-phi-design.md (9.0 KB)
    • Original design document
    • Historical context

Key Concepts

Loop Header PHI as SSOT (Single Source of Truth)

The core idea: Instead of using undefined loop parameters, use PHI nodes at the loop header to track the "current value" of loop variables.

Why it works:

  • PHI nodes ARE SSA-defined at the header block
  • PHI dsts can safely be referenced in exit values
  • Eliminates SSA-undef errors from undefined parameters

Architecture:

  • Phase 3.5: Pre-allocate PHI dsts (before instruction processing)
  • Phase 4: Set latch incoming during instruction processing
  • Phase 4.5: Finalize PHIs with all incoming edges
  • Phase 6: Use PHI dsts in exit line reconnection

Two-Phase PHI Construction

Phase 3.5: build() - Allocate PHI dsts

let phi_dst = builder.next_value_id();  // Allocate
entry_incoming = (entry_block, init_value);  // Set entry
latch_incoming = None;  // Will be set in Phase 4

Phase 4.5: finalize() - Emit PHI instructions

PHI {
  dst: phi_dst,  // Already allocated
  inputs: [
    (entry_block, init_value),  // From Phase 3.5
    (header_block, latch_value),  // From Phase 4
  ]
}

Known Limitations & Future Work

Phase 33-16 (Current)

Minimal scope: Loop variable only, no other carriers Pattern 2 primary focus (break statements) Backward compatible with Phase 33-15

Phase 33-16+ (Future)

  • Extract multiple carriers from exit_bindings
  • Handle Pattern 3+ with multiple PHIs
  • Pattern-specific header block identification
  • Optimize constant carriers

Support & Debugging

If implementation breaks:

  1. Compilation error: Check if loop_header_phi_info is properly passed as mutable reference
  2. SSA-undef error: Check if finalize() is called and all latch_incoming are set
  3. Wrong values: Check if latch_incoming is set from correct tail call args
  4. No header PHI: Enable NYASH_JOINIR_DEBUG=1 and check "Phase 33-16" output

Debug commands:

# Check debug output
NYASH_JOINIR_DEBUG=1 ./target/release/nyash --dump-mir test.hako 2>&1 | grep "Phase 33-16"

# Inspect MIR
./target/release/nyash --emit-mir-json mir.json test.hako
jq '.functions[0].blocks[0].instructions[0:3]' mir.json

Next Phase: Phase 34+

After Phase 33-16 is complete:

  1. Pattern 4 (continue statement) implementation
  2. Trim patterns with complex carriers
  3. Loop-as-expression full integration
  4. Performance optimizations

Ready to implement? Start with phase33-16-qa.md!