refactor(joinir): Phase 286C-2.1 Step 1 - Create 3-stage function stubs

- Create scan_blocks() stub (Stage 1: Read-only analysis)
- Create plan_rewrites() stub (Stage 2: Pure transformation)
- Create apply_rewrites() stub (Stage 3: Builder mutation)
- Add strategic markers for future extraction (STAGE 1/2/3)
- Document future orchestrator structure

Function Signatures:
- scan_blocks(&MirFunction, &JoinInlineBoundary, &RewriteContext) -> Result<RewritePlan, String>
- plan_rewrites(RewritePlan, &mut RewriteContext) -> Result<RewrittenBlocks, String>
- apply_rewrites(&mut MirBuilder, RewrittenBlocks) -> Result<(), String>

Benefits:
- Borrow checker safety: Sequential calling pattern (no overlapping borrows)
- Clear extraction targets: TODO markers identify logic to move
- Build stability: Stubs compile successfully, no functionality changes yet
- Foundation for incremental refactoring: Steps 2-5 can now proceed safely

Strategic Markers:
- Line 205: STAGE 1 marker (scan logic)
- Line 282: STAGE 2 marker (plan logic)
- Line 1355: STAGE 3 marker (apply logic)
- Line 1514: Future orchestrator structure

Status:
- Scaffolding:  Complete (stubs in place)
- Extraction:  Next step (move logic from merge_and_rewrite to stubs)

Build: cargo build --release 

🤖 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-25 03:19:06 +09:00
parent 1a8a70cc99
commit f2458280c1

View File

@ -87,6 +87,73 @@ use super::rewriter::terminator::{apply_remapped_terminator, remap_branch, remap
// The module is ready at super::rewriter::exit_collection but full integration
// requires careful refactoring due to logging context and flow control.
// Phase 286C-2.1: Import scaffolding data structures for 3-stage pipeline
use super::rewriter::scan_box::{RewritePlan, TailCallRewrite, ReturnConversion, PhiAdjustment, ParameterBinding};
use super::rewriter::plan_box::RewrittenBlocks;
/// Stage 1: Scan - Read-only analysis to identify what needs rewriting
///
/// Scans all blocks and instructions to identify:
/// - Tail calls to convert
/// - Returns to convert to exit jumps
/// - PHI adjustments needed
/// - Parameter bindings to generate
///
/// This is a READ-ONLY operation - no mutations, just analysis.
fn scan_blocks(
mir_module: &MirModule,
remapper: &JoinIrIdRemapper,
value_to_func_name: &BTreeMap<ValueId, String>,
ctx: &RewriteContext,
debug: bool,
) -> Result<RewritePlan, String> {
// TODO: Extract scan logic from merge_and_rewrite
// For now, return empty plan
Ok(RewritePlan {
tail_calls: Vec::new(),
return_conversions: Vec::new(),
phi_adjustments: Vec::new(),
parameter_bindings: Vec::new(),
})
}
/// Stage 2: Plan - Transform plan into concrete rewritten blocks
///
/// Generates new BasicBlocks based on the scan plan:
/// - Creates parameter binding instructions
/// - Builds PHI input mappings
/// - Prepares block ID remapping tables
///
/// Updates RewriteContext but does NOT touch MirBuilder.
fn plan_rewrites(
plan: RewritePlan,
ctx: &mut RewriteContext,
) -> Result<RewrittenBlocks, String> {
// TODO: Extract plan logic from merge_and_rewrite
// For now, return empty blocks
Ok(RewrittenBlocks {
new_blocks: Vec::new(),
block_replacements: BTreeMap::new(),
phi_inputs: Vec::new(),
carrier_inputs: BTreeMap::new(),
})
}
/// Stage 3: Apply - Apply rewritten blocks to MirBuilder
///
/// Mutates the builder:
/// - Adds new blocks
/// - Replaces modified blocks
/// - Updates function metadata
fn apply_rewrites(
builder: &mut crate::mir::builder::MirBuilder,
blocks: RewrittenBlocks,
) -> Result<(), String> {
// TODO: Extract apply logic from merge_and_rewrite
// For now, do nothing (blocks will be added by existing logic)
Ok(())
}
/// Phase 4: Merge ALL functions and rewrite instructions
///
/// Returns:
@ -119,6 +186,14 @@ pub(super) fn merge_and_rewrite(
exit_block_id: BasicBlockId,
debug: bool,
) -> Result<MergeResult, String> {
// Phase 286C-2.1: TODO - This will become an orchestrator calling the 3 stages:
// 1. scan_blocks() - Read-only analysis
// 2. plan_rewrites() - Generate rewritten blocks
// 3. apply_rewrites() - Mutate builder
//
// For now, keep existing monolithic logic intact to ensure no behavior changes.
// Future steps will extract logic incrementally into the 3 functions.
let trace = trace::trace();
let verbose = debug || crate::config::env::joinir_dev_enabled();
macro_rules! log {
@ -127,6 +202,14 @@ pub(super) fn merge_and_rewrite(
};
}
// ===== STAGE 1: SCAN (Read-only analysis) =====
// TODO Phase 286C-2.1: Extract to scan_blocks()
// This section should:
// - Build function_entry_map
// - Build skipped_entry_redirects
// - Identify tail calls, returns, PHI adjustments
// - Return RewritePlan describing what to do
// Phase 256 P1.7: continuation_func_ids is now BTreeSet<String> (function names)
// No need to convert with join_func_name() - use directly
let continuation_candidates: BTreeSet<String> = boundary
@ -196,6 +279,15 @@ pub(super) fn merge_and_rewrite(
// The issue was that pre-pass used stale remapper values before Phase 33-21 updates.
// Instead, we now generate Copies for non-carrier params in the main block processing loop.
// ===== STAGE 2: PLAN (Generate rewritten blocks) =====
// TODO Phase 286C-2.1: Extract to plan_rewrites()
// This section should:
// - Process each function and block
// - Generate Copy instructions for parameter bindings
// - Build new BasicBlocks with remapped instructions
// - Prepare PHI inputs and carrier inputs
// - Return RewrittenBlocks ready to apply
// DETERMINISM FIX: Sort functions by name to ensure consistent iteration order
if debug {
log!(
@ -1260,6 +1352,13 @@ pub(super) fn merge_and_rewrite(
new_block.instruction_spans.truncate(inst_count);
}
// ===== STAGE 3: APPLY (Mutate builder) =====
// TODO Phase 286C-2.1: Extract to apply_rewrites()
// This section should:
// - Add new_block to builder
// - Update function metadata
// - Apply span synchronization
// Add block to current function
if let Some(ref mut current_func) = builder.scope_ctx.current_function {
// Phase 256 P1.10 DEBUG: Log block content before adding (for blocks with multiple instructions)
@ -1412,6 +1511,20 @@ pub(super) fn merge_and_rewrite(
}
}
// Phase 286C-2.1: Future orchestrator structure (Step 2 onwards):
//
// // Stage 1: Scan - Read-only analysis
// let plan = scan_blocks(mir_module, remapper, value_to_func_name, &ctx, debug)?;
//
// // Stage 2: Plan - Generate rewritten blocks
// let blocks = plan_rewrites(plan, &mut ctx)?;
//
// // Stage 3: Apply - Mutate builder
// apply_rewrites(builder, blocks)?;
//
// // Build final merge result
// Ok(MergeResult { ... })
Ok(MergeResult {
exit_block_id: ctx.exit_block_id,
exit_phi_inputs: ctx.exit_phi_inputs,