refactor(joinir): Phase 287 P0.2 - Extract value_remapper

Extract remap_values() to value_remapper.rs (46 lines). This is a pure
helper function that allocates new ValueIds while avoiding conflicts
with reserved PHI dst ValueIds.

Changes:
- NEW: merge/value_remapper.rs (Phase 3 helper)
- MOD: merge/mod.rs: 1,315 → ~1,269 lines (-46 lines)
- Delegation: value_remapper::remap_values() called from orchestrator

Verification:
- Build: 0 errors
- Pattern6: RC:9 
- Smoke: 154/154 PASS (verified via quick profile)

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-27 10:14:27 +09:00
parent 433e1d45c0
commit 95fef8696d
2 changed files with 66 additions and 53 deletions

View File

@ -30,6 +30,7 @@ mod phi_block_remapper; // Phase 94: Phi block-id remap box
mod tail_call_classifier;
mod tail_call_lowering_policy; // Phase 131 Task 2: k_exit exit edge normalization
mod value_collector;
mod value_remapper; // Phase 287 P0.2: ValueId remapping helper
#[cfg(test)]
mod tests; // Phase 132-R0 Task 3: Continuation contract tests
@ -582,7 +583,8 @@ pub(in crate::mir::builder) fn merge_joinir_mir_blocks(
);
// Phase 3: Remap ValueIds (with reserved PHI dsts protection)
remap_values(
// Phase 287 P0.2: Delegated to value_remapper module
value_remapper::remap_values(
builder,
&used_values,
&mut remapper,
@ -1309,56 +1311,5 @@ pub(in crate::mir::builder) fn merge_joinir_mir_blocks(
}
}
/// Phase 3: Allocate new ValueIds for all collected values
///
/// Phase 201-A: Accept reserved ValueIds that must not be reused.
/// These are PHI dst ValueIds that will be created by LoopHeaderPhiBuilder.
/// We must skip these IDs to prevent carrier value corruption.
fn remap_values(
builder: &mut crate::mir::builder::MirBuilder,
used_values: &std::collections::BTreeSet<ValueId>,
remapper: &mut crate::mir::builder::joinir_id_remapper::JoinIrIdRemapper,
reserved_ids: &std::collections::HashSet<ValueId>,
debug: bool,
) -> Result<(), String> {
let trace = trace::trace();
trace.stderr_if(
&format!(
"[cf_loop/joinir] Phase 3: Remapping {} ValueIds (reserved: {})",
used_values.len(),
reserved_ids.len()
),
debug,
);
for old_value in used_values {
// Phase 201-A: Allocate new ValueId, skipping reserved PHI dsts
let new_value = loop {
let candidate = builder.next_value_id();
if !reserved_ids.contains(&candidate) {
break candidate;
}
// Skip reserved ID - will try next one
trace.stderr_if(
&format!(
"[cf_loop/joinir] Phase 201-A: Skipping reserved PHI dst {:?}",
candidate
),
debug,
);
};
remapper.set_value(*old_value, new_value);
trace.stderr_if(
&format!(
"[cf_loop/joinir] Value remap: {:?}{:?}",
old_value, new_value
),
debug,
);
}
Ok(())
}
// Phase 287 P0.1: Verification functions moved to debug_assertions.rs
// Phase 287 P0.2: remap_values moved to value_remapper.rs

View File

@ -0,0 +1,62 @@
//! Phase 287 P0.2: Value ID remapping (pure helper)
//!
//! Allocates new ValueIds for all JoinIR values, avoiding conflicts with:
//! - Host function's existing ValueIds
//! - Reserved PHI dst ValueIds (allocated by LoopHeaderPhiBuilder)
//!
//! This is Phase 3 of the merge pipeline.
use crate::mir::ValueId;
use std::collections::{BTreeSet, HashSet};
/// Phase 3: Allocate new ValueIds for all collected values
///
/// Phase 201-A: Accept reserved ValueIds that must not be reused.
/// These are PHI dst ValueIds that will be created by LoopHeaderPhiBuilder.
/// We must skip these IDs to prevent carrier value corruption.
pub(super) fn remap_values(
builder: &mut crate::mir::builder::MirBuilder,
used_values: &BTreeSet<ValueId>,
remapper: &mut crate::mir::builder::joinir_id_remapper::JoinIrIdRemapper,
reserved_ids: &HashSet<ValueId>,
debug: bool,
) -> Result<(), String> {
let trace = super::trace::trace();
trace.stderr_if(
&format!(
"[cf_loop/joinir] Phase 3: Remapping {} ValueIds (reserved: {})",
used_values.len(),
reserved_ids.len()
),
debug,
);
for old_value in used_values {
// Phase 201-A: Allocate new ValueId, skipping reserved PHI dsts
let new_value = loop {
let candidate = builder.next_value_id();
if !reserved_ids.contains(&candidate) {
break candidate;
}
// Skip reserved ID - will try next one
trace.stderr_if(
&format!(
"[cf_loop/joinir] Phase 201-A: Skipping reserved PHI dst {:?}",
candidate
),
debug,
);
};
remapper.set_value(*old_value, new_value);
trace.stderr_if(
&format!(
"[cf_loop/joinir] Value remap: {:?}{:?}",
old_value, new_value
),
debug,
);
}
Ok(())
}