feat(apply): Phase 286C-4 Step 3 - Implement apply_rewrites() (~160 lines)
Implemented apply_rewrites() stage to mutate MirBuilder: **Block Addition**: - Add all new blocks to current function - Debug logging for blocks with 4+ instructions **Boundary Injection** (~100 lines): - Call BoundaryInjector::inject_boundary_copies() - Build value_map for join_inputs and condition_bindings - Collect PHI dst IDs from loop_header_phi_info **Context Updates**: - Add phi_inputs to ctx.exit_phi_inputs - Add carrier_inputs to ctx.carrier_inputs **Fix**: - Use `ref args` in tail_call_target destructuring to avoid move error Build passes successfully.
This commit is contained in:
@ -474,7 +474,7 @@ fn plan_rewrites(
|
||||
}
|
||||
|
||||
// Second pass: Insert parameter bindings for tail calls (if any)
|
||||
if let Some((target_block, args)) = tail_call_target {
|
||||
if let Some((target_block, ref args)) = tail_call_target {
|
||||
// Find the target function name from the target_block
|
||||
let mut target_func_name: Option<String> = None;
|
||||
for (fname, &entry_block) in &ctx.function_entry_map {
|
||||
@ -908,15 +908,157 @@ fn plan_rewrites(
|
||||
/// Stage 3: Apply - Apply rewritten blocks to MirBuilder
|
||||
///
|
||||
/// Mutates the builder:
|
||||
/// - Adds new blocks
|
||||
/// - Replaces modified blocks
|
||||
/// - Updates function metadata
|
||||
/// - Adds new blocks to current function
|
||||
/// - Injects boundary copies (if boundary provided)
|
||||
/// - Updates RewriteContext with carrier/phi inputs
|
||||
///
|
||||
/// # Phase 286C-4 Step 3
|
||||
///
|
||||
/// This function extracts ~180 lines from merge_and_rewrite():
|
||||
/// - Block addition (lines 1738-1751)
|
||||
/// - Boundary injection (lines 1755-1857)
|
||||
/// - Context updates (carrier_inputs, exit_phi_inputs)
|
||||
fn apply_rewrites(
|
||||
builder: &mut crate::mir::builder::MirBuilder,
|
||||
blocks: RewrittenBlocks,
|
||||
boundary: Option<&crate::mir::join_ir::lowering::inline_boundary::JoinInlineBoundary>,
|
||||
remapper: &crate::mir::builder::joinir_id_remapper::JoinIrIdRemapper,
|
||||
loop_header_phi_info: &crate::mir::builder::control_flow::joinir::merge::loop_header_phi_info::LoopHeaderPhiInfo,
|
||||
mir_module: &crate::mir::MirModule,
|
||||
ctx: &mut RewriteContext,
|
||||
debug: bool,
|
||||
) -> Result<(), String> {
|
||||
// TODO: Extract apply logic from merge_and_rewrite
|
||||
// For now, do nothing (blocks will be added by existing logic)
|
||||
let trace = trace::trace();
|
||||
let verbose = debug || crate::config::env::joinir_dev_enabled();
|
||||
macro_rules! log {
|
||||
($enabled:expr, $($arg:tt)*) => {
|
||||
trace.stderr_if(&format!($($arg)*), $enabled);
|
||||
};
|
||||
}
|
||||
|
||||
// Add new blocks to current function
|
||||
if let Some(ref mut current_func) = builder.scope_ctx.current_function {
|
||||
for new_block in blocks.new_blocks {
|
||||
if debug && new_block.instructions.len() >= 4 {
|
||||
log!(
|
||||
true,
|
||||
"[apply_rewrites] Adding block {:?} with {} instructions",
|
||||
new_block.id, new_block.instructions.len()
|
||||
);
|
||||
for (idx, inst) in new_block.instructions.iter().enumerate() {
|
||||
log!(true, "[apply_rewrites] [{}] {:?}", idx, inst);
|
||||
}
|
||||
}
|
||||
current_func.add_block(new_block);
|
||||
}
|
||||
}
|
||||
|
||||
// Inject boundary copies (if boundary provided)
|
||||
if let Some(boundary) = boundary {
|
||||
use crate::mir::builder::joinir_inline_boundary_injector::BoundaryInjector;
|
||||
use crate::mir::join_ir::lowering::canonical_names as cn;
|
||||
|
||||
// Get entry function's entry block
|
||||
let (entry_func_name, entry_func) = {
|
||||
if let Some(main) = mir_module.functions.get(cn::MAIN) {
|
||||
if main.params == boundary.join_inputs {
|
||||
(cn::MAIN, main)
|
||||
} else {
|
||||
mir_module
|
||||
.functions
|
||||
.iter()
|
||||
.find(|(_, func)| func.params == boundary.join_inputs)
|
||||
.or_else(|| mir_module.functions.iter().next())
|
||||
.map(|(name, func)| (name.as_str(), func))
|
||||
.ok_or("JoinIR module has no functions")?
|
||||
}
|
||||
} else {
|
||||
mir_module
|
||||
.functions
|
||||
.iter()
|
||||
.find(|(_, func)| func.params == boundary.join_inputs)
|
||||
.or_else(|| mir_module.functions.iter().next())
|
||||
.map(|(name, func)| (name.as_str(), func))
|
||||
.ok_or("JoinIR module has no functions")?
|
||||
}
|
||||
};
|
||||
|
||||
let entry_block_remapped = remapper
|
||||
.get_block(entry_func_name, entry_func.entry_block)
|
||||
.ok_or_else(|| format!("Entry block not found for {}", entry_func_name))?;
|
||||
|
||||
log!(
|
||||
verbose,
|
||||
"[apply_rewrites] Boundary entry: func='{}' entry_block={:?} remapped={:?}",
|
||||
entry_func_name, entry_func.entry_block, entry_block_remapped
|
||||
);
|
||||
|
||||
// Build value map for BoundaryInjector
|
||||
let mut value_map_for_injector = std::collections::BTreeMap::new();
|
||||
|
||||
// Add join_inputs to value_map
|
||||
for join_in in &boundary.join_inputs {
|
||||
if let Some(remapped) = remapper.get_value(*join_in) {
|
||||
value_map_for_injector.insert(*join_in, remapped);
|
||||
}
|
||||
}
|
||||
|
||||
// Add condition_bindings to value_map
|
||||
for binding in &boundary.condition_bindings {
|
||||
if let Some(remapped) = remapper.get_value(binding.join_value) {
|
||||
value_map_for_injector.insert(binding.join_value, remapped);
|
||||
log!(
|
||||
verbose,
|
||||
"[apply_rewrites] Condition binding '{}': JoinIR {:?} → remapped {:?}",
|
||||
binding.name, binding.join_value, remapped
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Collect PHI dst IDs from loop_header_phi_info
|
||||
let phi_dst_ids: std::collections::HashSet<crate::mir::ValueId> = loop_header_phi_info
|
||||
.carrier_phis
|
||||
.values()
|
||||
.map(|entry| entry.phi_dst)
|
||||
.collect();
|
||||
|
||||
// Inject boundary copies
|
||||
if let Some(ref mut current_func) = builder.scope_ctx.current_function {
|
||||
let _reallocations = BoundaryInjector::inject_boundary_copies(
|
||||
current_func,
|
||||
entry_block_remapped,
|
||||
boundary,
|
||||
&value_map_for_injector,
|
||||
&phi_dst_ids,
|
||||
debug,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
// Update context with phi_inputs and carrier_inputs from blocks
|
||||
for (block_id, value_id) in blocks.phi_inputs {
|
||||
ctx.add_exit_phi_input(block_id, value_id);
|
||||
}
|
||||
|
||||
for (carrier_name, inputs) in blocks.carrier_inputs {
|
||||
for (block_id, value_id) in inputs {
|
||||
ctx.add_carrier_input(carrier_name.clone(), block_id, value_id);
|
||||
}
|
||||
}
|
||||
|
||||
if debug {
|
||||
log!(
|
||||
true,
|
||||
"[apply_rewrites] Applied {} blocks, {} phi_inputs, {} carriers",
|
||||
builder.scope_ctx.current_function
|
||||
.as_ref()
|
||||
.map(|f| f.blocks.len())
|
||||
.unwrap_or(0),
|
||||
ctx.exit_phi_inputs.len(),
|
||||
ctx.carrier_inputs.len()
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user