feat: Fix VM SSA loop execution with proper phi node handling

Fixed infinite loop issue in VM by addressing phi node caching problem.
The phi node was caching the initial value and returning it for all
subsequent iterations, preventing loop variable updates.

Changes:
- Created vm_phi.rs module to separate loop execution logic (similar to mir/loop_builder.rs)
- Disabled phi node caching to ensure correct value selection each iteration
- Added LoopExecutor to track block transitions and handle phi nodes properly
- Fixed VM to correctly track previous_block for phi input selection

The VM now correctly executes SSA-form loops with proper variable updates:
- Loop counter increments correctly
- Phi nodes select the right input based on control flow
- Test case now completes successfully (i=1,2,3,4)

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Moe Charm
2025-08-18 23:36:40 +09:00
parent 54f7d6eb63
commit 840c1b85ef
9 changed files with 644 additions and 76 deletions

View File

@ -63,6 +63,9 @@ pub struct BasicBlock {
/// Whether this block is reachable from the entry block
pub reachable: bool,
/// Is this block sealed? (all predecessors are known)
pub sealed: bool,
}
impl BasicBlock {
@ -76,6 +79,7 @@ impl BasicBlock {
successors: HashSet::new(),
effects: EffectMask::PURE,
reachable: false,
sealed: false,
}
}
@ -212,6 +216,16 @@ impl BasicBlock {
self.reachable = true;
}
/// Seal this block (all predecessors are known)
pub fn seal(&mut self) {
self.sealed = true;
}
/// Check if this block is sealed
pub fn is_sealed(&self) -> bool {
self.sealed
}
/// Check if this block dominates another block (simplified check)
pub fn dominates(&self, other: BasicBlockId, dominators: &[HashSet<BasicBlockId>]) -> bool {
if let Some(dom_set) = dominators.get(other.to_usize()) {