2025-12-05 16:05:32 +09:00
# Phase 189: Select Instruction MIR Bridge - ChatGPT Architectural Inquiry
**Date**: 2025-12-05
**Status**: Blocking Issue Identified
**Assigned to**: ChatGPT (Architecture & Design Guidance)
**Related Phase**: Phase 188-Impl-3 (Pattern 3 implementation complete except for MIR bridge)
---
## Executive Summary
Phase 188-Impl-3 (Loop with If-Else PHI) has successfully implemented:
- ✅ Pattern 3 JoinIR lowering infrastructure (loop_with_if_phi_minimal.rs)
- ✅ Pattern 3 routing in MIR builder (control_flow.rs)
- ✅ Select instruction definition in JoinIR
- ✅ JoinIR runtime execution for Select
- ✅ JSON serialization for Select
**Remaining Blocker**: Pattern 3 tests cannot execute because **Select instruction conversion from JoinIR to MIR is not implemented** .
The Select instruction (JoinIR's ternary operator: `cond ? then_val : else_val` ) cannot be directly represented in MIR's current instruction set. We need a clean architectural approach to convert it to MIR-compatible control flow.
---
## Current Situation
### What Works (Pattern 1 & 2)
- Pattern 1 (Simple While Loop): ✅ Fully working (loop_min_while.hako)
- Pattern 2 (Loop with Conditional Break): ✅ Fully working (joinir_min_loop.hako)
- Both use only instructions already implemented in MIR bridge
### What Doesn't Work (Pattern 3)
- Pattern 3 (Loop with If-Else PHI): 🔄 Infrastructure complete, execution blocked
- Test case: apps/tests/loop_if_phi.hako
- Expected: Prints "sum=9" (sum of odd numbers 1-5)
- Actual: Fails at MIR bridge conversion with Select instruction
### Root Cause: Missing Select → MIR Conversion
```rust
// JoinIR lowering generates this (works fine):
let sum_new = alloc_value();
loop_step_func.body.push(JoinInst::Compute(MirLikeInst::Select {
dst: sum_new,
cond: if_cond,
then_val: sum_then,
else_val: sum_else,
}));
// MIR bridge conversion fails here:
// src/mir/join_ir_vm_bridge/convert.rs line ~XXX
MirLikeInst::Select { .. } => {
return Err("Select instruction not yet implemented".into());
// ❌ This is where we get stuck
}
```
### Why Select Can't Be Direct in MIR
MIR instruction set (14 instructions) doesn't have a direct ternary/select instruction:
- **Arithmetic**: Const, UnaryOp, BinOp, Compare, TypeOp
- **Memory**: Load, Store
- **Control**: Branch (goto two targets), Jump (goto one target), Return
- **Other**: Phi, NewBox, BoxCall
**Problem**: Select needs to produce a value *and* involve control flow, which MIR separates:
- Control flow → Branch/Jump instructions that create multiple basic blocks
- Value production → Phi nodes at merge points
---
## Technical Challenge: Select → MIR Conversion
### Pattern of the Conversion
A JoinIR Select must be converted to:
1. **Branch block** with the condition → splits into then_block and else_block
2. **Then block** → computes `then_val`
3. **Else block** → computes `else_val`
4. **Merge block** → Phi instruction that merges the two values
### Example: JoinIR vs MIR Representation
**JoinIR (what we have)**:
```rust
let if_cond = ... // compute condition
let sum_then = sum + i // then branch
let sum_else = sum + 0 // else branch
let sum_new = Select { // ternary select
cond: if_cond,
then_val: sum_then,
else_val: sum_else,
}
// sum_new is ready to use
```
**MIR (what we need to generate)**:
```
block_before:
if_cond = Compare(...)
Branch if_cond → block_then, block_else
block_then:
sum_then = BinOp(Add, sum, i)
Jump → block_merge [sum_then]
block_else:
sum_else = BinOp(Add, sum, 0)
Jump → block_merge [sum_else]
block_merge:
sum_new = Phi([sum_then, sum_else]) // merges two values
// sum_new ready to use
```
---
## Questions for ChatGPT
### 1. **Clean Conversion Strategy**
How should we cleanly structure the Select → MIR conversion in the codebase?
**Considerations**:
- Should this be a separate transformation function or inline in the converter?
- What's the best way to handle the block generation and control flow linking?
- Should we use existing utilities (e.g., block management functions) or create new ones?
**Reference**: Look at how existing Select-like constructs are handled:
- If/Then/Else lowering in `src/mir/builder/if_builder.rs` (lines ~200-350)
- Phi generation in `src/mir/join_ir/lowering/if_select.rs`
- How Branch/Phi are currently being connected
### 2. **Block Creation and Management**
The conversion needs to create new MIR blocks. How should this interact with existing block management?
**Questions**:
- Should new blocks be pre-allocated (like LoopForm does)?
- Should the conversion happen immediately or deferred?
- How do we ensure proper linking between blocks (edges, dominance)?
- Do we need metadata tracking for Select block origins?
### 3. **Value ID Continuity**
JoinIR uses local ValueIds (0, 1, 2, ...), which get remapped to host ValueIds. How do we handle the intermediate values?
**Context**:
- JoinModule is converted to MirModule via `convert_join_module_to_mir_with_meta()`
- ValueIds are already remapped at this stage
- Then blocks are merged via `merge_joinir_mir_blocks()`
**Question**: Should the Select expansion happen:
- (A) In `convert_join_module_to_mir_with_meta()` (early in the JoinModule→MirModule stage)?
- (B) In the MIR bridge converter (current location)?
- (C) In `merge_joinir_mir_blocks()` (late, after remapping)?
### 4. **Code Organization**
Where should the Select conversion logic live?
**Options**:
- Option A: New file `src/mir/join_ir_vm_bridge/select_expansion.rs`
- Pros: Single responsibility, easy to test, clear naming
- Cons: Small file, might split related code
- Option B: Expand `src/mir/join_ir_vm_bridge/convert.rs`
- Pros: Centralized conversion logic
- Cons: File gets larger, mixed concerns
- Option C: Create in JoinIR lowering layer (`src/mir/join_ir/lowering/select_expansion.rs` )
- Pros: Closer to where Select is created
- Cons: Mixing JoinIR and MIR concerns
**What's the architectural pattern used elsewhere in the codebase?**
### 5. **Performance and Optimization Implications**
Select expansion creates extra blocks and Phi nodes. Any concerns?
**Questions**:
- Will the VM interpreter handle this correctly?
- Does the LLVM backend optimize this back to conditional moves?
- Should we add a Select-fast-path for simple cases (where Select result isn't used in loops)?
- How do we measure the quality of generated MIR?
### 6. **Testing Strategy**
How should we validate the Select expansion?
**Suggested Approach**:
- Existing test: apps/tests/loop_if_phi.hako (integration test)
- New unit test: Test Select expansion in isolation
- MIR output inspection: Compare before/after
- Round-trip test: JoinIR → MIR → VM execution
**Your input**: What's the minimal test to validate correctness?
### 7. **Future Extensibility**
Pattern 3 uses Select for single variable mutation. What about more complex patterns?
**Consider**:
- Pattern 4+: Multiple variables mutating in if/else?
- IfMerge instruction (which we have but don't use)?
- Should IfMerge replace Select as the canonical form?
- How does this relate to Phase 33's IfMerge lowering work?
---
## Existing References in Codebase
### Similar Transformations
1. **If-Select lowering** (`src/mir/join_ir/lowering/if_select.rs` )
- Converts if/else with PHI to JoinIR Select instruction
- ~180 lines, well-structured
- **Insight**: This is the *opposite* direction (MIR→JoinIR Select)
2. **If builder** (`src/mir/builder/if_builder.rs` )
- Creates MIR blocks for if/then/else
- Lines 200-350 show block creation and Phi handling
- **Insight**: Shows how to properly structure MIR control flow
3. **Loop builder** (`src/mir/builder/loop_builder.rs` )
- Generates loop control flow with Phi nodes
- Handles block linking and edge management
- **Insight**: Established patterns for block management
4. **LoopForm** (`src/mir/loop_pattern_detection.rs` + `src/mir/mir_loopform.rs` )
- Entire subsystem for loop pattern detection
- Pre-allocates and links blocks
- **Insight**: Large-scale block transformation pattern
### Related Files
- `src/mir/join_ir_vm_bridge/convert.rs` (current location of Select error)
- `src/mir/join_ir/lowering/inline_boundary.rs` (ValueId mapping)
- `src/mir/join_ir/lowering/loop_patterns.rs` (routing logic)
---
## Proposed Implementation Phases
### Phase 189-A: Design & Validation (ChatGPT Input)
- Architectural decision on conversion location (early vs late in pipeline)
- Code organization approach
- Test strategy definition
### Phase 189-B: Core Implementation
- Implement Select → Branch + Then + Else + Phi conversion
- Unit tests for conversion correctness
- Integration test with loop_if_phi.hako
### Phase 189-C: Optimization & Polish
- Performance validation
- MIR output quality analysis
- Documentation and comments
---
## Success Criteria
✅ **Minimal** : Pattern 3 test (loop_if_phi.hako) produces `sum=9`
✅ **Better** : All MIR patterns (1-3) work correctly
✅ **Best** : Design is extensible for future patterns (4+)
---
## Timeline Context
- **Phase 188-Impl-1**: Pattern 1 ✅ Complete (loop_min_while.hako)
- **Phase 188-Impl-2**: Pattern 2 ✅ Complete (joinir_min_loop.hako)
- **Phase 188-Impl-3**: Pattern 3 🔄 Lowering complete, MIR bridge pending
- **Phase 189**: Select expansion (THIS INQUIRY)
- **Phase 190+**: Additional patterns, optimizations, cleanup
---
## Key Files for Reference
```
docs/development/current/main/phase188-select-implementation-spec.md ← Spec
docs/private/roadmap2/phases/phase-188-joinir-loop-pattern-expansion/
├── design.md ← Full 1648-line design document
└── pattern3-implementation-spec.md ← Pattern 3 detailed spec
src/mir/join_ir/lowering/
├── loop_with_if_phi_minimal.rs ← Pattern 3 lowering (381 lines)
├── if_select.rs ← Similar conversion (opposite dir)
└── inline_boundary.rs ← ValueId mapping
src/mir/join_ir_vm_bridge/convert.rs ← Current error location (line ~XXX)
src/mir/builder/
├── if_builder.rs ← Example: if/else block creation
└── loop_builder.rs ← Example: loop block management
apps/tests/loop_if_phi.hako ← Pattern 3 test (blocked)
```
---
## Appendix: Test Case Details
### Pattern 3 Test: loop_if_phi.hako
```nyash
static box Main {
main(args) {
local console = new ConsoleBox()
local i = 1
local sum = 0
loop(i < = 5) {
if (i % 2 == 1) { sum = sum + i } else { sum = sum + 0 }
i = i + 1
}
console.println("sum=" + sum)
return 0
}
}
```
**Execution trace**:
- i=1: 1%2==1 → sum=0+1=1
- i=2: 2%2==0 → sum=1+0=1
- i=3: 3%2==1 → sum=1+3=4
- i=4: 4%2==0 → sum=4+0=4
- i=5: 5%2==1 → sum=4+5=9
- i=6: 6< =5 is false → exit, print "sum=9"
**Expected output**: `sum=9\n`
---
## ChatGPT Requested Deliverables
1. **Architectural Recommendation** (Section 1-4)
- Clean conversion strategy
- Code organization approach
- Block management pattern
- ValueId handling strategy
2. **Design Document** (reference material provided)
- Template for Phase 189-A design writeup
- Implementation checklist
3. **Code Pattern Examples** (if helpful)
- Reference snippets from similar transformations
- Pseudocode for Select expansion algorithm
4. **Phase 189 Kickoff Plan**
- Implementation order
- Testing approach
- Success metrics
---
**Status**: Awaiting ChatGPT input on architectural approach before proceeding to Phase 189-B implementation.
🤖 **Created by** : Claude Code
📅 **Date** : 2025-12-05
🎯 **Target** : Phase 189 - Select Instruction MIR Bridge Implementation
2025-12-11 00:33:04 +09:00
Status: Historical