docs: Phase 189 ChatGPT Architectural Inquiry - Select Instruction MIR Bridge
Add comprehensive inquiry document for Select instruction conversion strategy. This document outlines the architectural challenge and requests ChatGPT guidance on: 1. Clean conversion strategy (Select → Branch + Then/Else + Phi) 2. Block creation and management patterns 3. ValueId continuity across conversion boundaries 4. Code organization approach (where should conversion logic live?) 5. Performance and optimization implications 6. Testing strategy for Select expansion 7. Future extensibility for complex patterns ## Context - Phase 188-Impl-3 implementation is COMPLETE ✅ - All JoinIR lowering for Pattern 3 is functional - All infrastructure is in place (routing, boundary mapping, etc.) - BLOCKER: Select instruction cannot be converted to MIR yet The inquiry provides: - Executive summary of current status - Technical challenge explanation with example conversions - 7 detailed questions for architectural guidance - References to existing similar code patterns in codebase - Test case details and success criteria - Proposed Phase 189 implementation phases ## Status - Phase 188-Impl-1 (Pattern 1): ✅ COMPLETE - loop_min_while.hako working - Phase 188-Impl-2 (Pattern 2): ✅ COMPLETE - joinir_min_loop.hako working - Phase 188-Impl-3 (Pattern 3): 🔄 INFRASTRUCTURE COMPLETE - awaiting Phase 189 for MIR bridge - Phase 189: This inquiry document provides foundation for implementation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -0,0 +1,352 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user