chore(joinir): Phase 203-A remove dead code after JoinValueSpace unification

Remove obsolete v1 API and unused imports after Phase 201-202 JoinValueSpace unification.

Changes:
- Remove v1 API build_for_break_condition() (70 lines)
  - Converted 3 unit tests to v2 API (build_for_break_condition_v2)
  - Updated module documentation to reflect v2 as standard
- Remove 2 unused imports (JoinValueSpace, ValueId)
  - inline_boundary_builder.rs: Remove unused JoinValueSpace import
  - loop_with_if_phi_minimal.rs: Remove unused ValueId import
- Document stub function (lower_loop_with_break_to_joinir)
  - Add Phase 203-A documentation clarifying stub status
  - Explain why stub exists and migration options
  - Kept stub as it's called by router (line 148 in loop_pattern_router.rs)

Stats:
- 4 files changed
- 75 net lines removed (117 deletions, 42 insertions)
- All tests passing (821 passed)
- Build clean with no errors

Related:
- Phase 201: JoinValueSpace unified ValueId allocation
- Phase 202: Pattern 2 conversion to v2 API

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-12-09 19:33:38 +09:00
parent ae741d97b4
commit de9fe3bf85
4 changed files with 42 additions and 117 deletions

View File

@ -15,12 +15,14 @@
//! # Usage
//!
//! ```rust
//! // Standard break condition analysis
//! let (env, bindings) = ConditionEnvBuilder::build_for_break_condition(
//! // Standard break condition analysis (Phase 201+)
//! let mut space = JoinValueSpace::new();
//! let (env, bindings, loop_var_join_id) = ConditionEnvBuilder::build_for_break_condition_v2(
//! break_condition,
//! &loop_var_name,
//! &variable_map,
//! loop_var_id,
//! &mut space,
//! )?;
//! ```
@ -36,78 +38,6 @@ use std::collections::BTreeMap;
pub struct ConditionEnvBuilder;
impl ConditionEnvBuilder {
/// Build ConditionEnv and ConditionBindings from break condition
///
/// This extracts all variables used in the break condition (excluding the loop parameter)
/// and creates:
/// 1. ConditionEnv: Maps variable names to JoinIR-local ValueIds
/// 2. ConditionBindings: Records HOST ValueId ↔ JoinIR ValueId mappings for merge
///
/// # Arguments
///
/// * `break_condition` - AST node for the break condition
/// * `loop_var_name` - Loop parameter name (excluded from condition-only variables)
/// * `variable_map` - HOST function's variable_map (for looking up HOST ValueIds)
/// * `loop_var_id` - HOST ValueId for the loop parameter
///
/// # Returns
///
/// Tuple of:
/// - ConditionEnv: Variable name → JoinIR ValueId mapping
/// - Vec<ConditionBinding>: HOST↔JoinIR value mappings for merge
///
/// # Errors
///
/// Returns error if a condition variable is not found in variable_map
pub fn build_for_break_condition(
break_condition: &ASTNode,
loop_var_name: &str,
variable_map: &BTreeMap<String, ValueId>,
_loop_var_id: ValueId,
) -> Result<(ConditionEnv, Vec<ConditionBinding>), String> {
// Extract all variables used in the condition (excluding loop parameter)
let condition_var_names = extract_condition_variables(
break_condition,
&[loop_var_name.to_string()],
);
let mut env = ConditionEnv::new();
let mut bindings = Vec::new();
// Add loop parameter to env (ValueId(0) in JoinIR space)
// The loop parameter is NOT a condition binding (it's a join_input instead)
env.insert(loop_var_name.to_string(), ValueId(0));
// Create a local allocator for JoinIR-local ValueIds for condition-only variables
let mut join_value_counter = 1u32; // Start from 1 (0 is reserved for loop param)
// For each condition variable, allocate JoinIR-local ValueId and build binding
for var_name in &condition_var_names {
let host_id = variable_map
.get(var_name)
.copied()
.ok_or_else(|| {
format!(
"Condition variable '{}' not found in variable_map. \
Loop condition references undefined variable.",
var_name
)
})?;
let join_id = ValueId(join_value_counter);
join_value_counter += 1;
env.insert(var_name.clone(), join_id);
bindings.push(ConditionBinding {
name: var_name.clone(),
host_value: host_id,
join_value: join_id,
});
}
Ok((env, bindings))
}
/// Build ConditionEnv with loop parameter only
///
/// Used when there are no additional condition-only variables,
@ -339,17 +269,22 @@ mod tests {
let mut variable_map = BTreeMap::new();
variable_map.insert("i".to_string(), ValueId(100));
let (env, bindings) = ConditionEnvBuilder::build_for_break_condition(
let mut space = JoinValueSpace::new();
let (env, bindings, loop_var_join_id) = ConditionEnvBuilder::build_for_break_condition_v2(
&condition,
"i",
&variable_map,
ValueId(100),
&mut space,
)
.unwrap();
// Should have loop parameter in env
assert!(env.get("i").is_some());
// Loop var should be in param region (100+)
assert!(loop_var_join_id.0 >= 100);
// Should have no condition-only bindings
assert_eq!(bindings.len(), 0);
}
@ -374,16 +309,19 @@ mod tests {
variable_map.insert("i".to_string(), ValueId(100));
variable_map.insert("max".to_string(), ValueId(200));
let (env, bindings) = ConditionEnvBuilder::build_for_break_condition(
let mut space = JoinValueSpace::new();
let (env, bindings, loop_var_join_id) = ConditionEnvBuilder::build_for_break_condition_v2(
&condition,
"i",
&variable_map,
ValueId(100),
&mut space,
)
.unwrap();
// Should have loop parameter in env
assert!(env.get("i").is_some());
assert!(loop_var_join_id.0 >= 100);
// Should have "max" in env with JoinIR-local ValueId
assert!(env.get("max").is_some());
@ -392,7 +330,8 @@ mod tests {
assert_eq!(bindings.len(), 1);
assert_eq!(bindings[0].name, "max");
assert_eq!(bindings[0].host_value, ValueId(200));
assert!(bindings[0].join_value.0 > 0); // JoinIR-local ID
// Phase 201: Condition-only variables are allocated from Param region (100+), not Local region
assert!(bindings[0].join_value.0 >= 100); // Should be in param region (100+)
}
#[test]
@ -415,11 +354,13 @@ mod tests {
variable_map.insert("i".to_string(), ValueId(100));
// "undefined_var" is NOT in variable_map
let result = ConditionEnvBuilder::build_for_break_condition(
let mut space = JoinValueSpace::new();
let result = ConditionEnvBuilder::build_for_break_condition_v2(
&condition,
"i",
&variable_map,
ValueId(100),
&mut space,
);
// Should return error

View File

@ -27,7 +27,6 @@
use crate::mir::ValueId;
use super::inline_boundary::{JoinInlineBoundary, LoopExitBinding};
use super::condition_to_joinir::ConditionBinding;
use super::join_value_space::JoinValueSpace;
/// Role of a parameter in JoinIR lowering (Phase 200-A)
///

View File

@ -86,44 +86,30 @@ pub fn lower_loop_with_break_to_joinir(
_loop_form: &LoopForm,
_lowerer: &mut LoopToJoinLowerer,
) -> Option<JoinInst> {
// Phase 188-Impl-2: Delegate to minimal lowerer
// TODO: Extract LoopScopeShape from loop_form for generic implementation
use crate::mir::join_ir::lowering::loop_scope_shape::LoopScopeShape;
use crate::mir::BasicBlockId;
use std::collections::{BTreeMap, BTreeSet};
// For now, use a placeholder LoopScopeShape
// TODO: Build actual LoopScopeShape from loop_form
let _placeholder_scope = LoopScopeShape {
header: BasicBlockId(0),
body: BasicBlockId(0),
latch: BasicBlockId(0),
exit: BasicBlockId(0),
pinned: BTreeSet::new(),
carriers: BTreeSet::new(),
body_locals: BTreeSet::new(),
exit_live: BTreeSet::new(),
progress_carrier: None,
variable_definitions: BTreeMap::new(),
};
// Generate JoinIR module
// Phase 169: lower_loop_with_break_minimal now requires condition AST and builder
// This test stub is not used by the actual router, so commenting out for now
// let _join_module = lower_loop_with_break_minimal(placeholder_scope, condition, builder)?;
// Phase 188-Impl-2: Pattern 2 is now integrated in control_flow.rs via cf_loop_pattern2_with_break()
// This function (lower_loop_with_break_to_joinir) is currently not used by the router.
// The actual lowering happens directly in control_flow.rs which calls loop_with_break_minimal.
// Phase 203-A: STUB FUNCTION - Called by router but always returns None
//
// TODO: Either:
// 1. Remove this function and rely only on control_flow.rs integration, OR
// 2. Implement JoinModule → JoinInst conversion here (future phase)
// Status: This function is called by loop_pattern_router.rs:148 but is a NO-OP stub.
// The actual Pattern 2 lowering happens via control_flow.rs.
//
// Why this stub exists:
// - Router expects unified interface: lower_*_to_joinir(loop_form, lowerer)
// - Pattern 2 is tightly integrated with control_flow.rs
// - Removing it would require updating router dispatch logic
//
// Current behavior:
// 1. Router calls this function (line 148 in loop_pattern_router.rs)
// 2. Function logs a message and returns None
// 3. Router falls back to control_flow.rs hardcoded Pattern 2 route
//
// Migration options (future):
// - Option 1: Remove stub and update router to call control_flow.rs directly
// - Option 2: Implement JoinModule → JoinInst conversion here
//
// Related code:
// - Router callsite: loop_pattern_router.rs:148
// - Actual implementation: control_flow::cf_loop_pattern2_with_break()
// - Minimal lowerer: loop_with_break_minimal::lower_loop_with_break_minimal()
eprintln!("[loop_patterns] Pattern 2: Lowering delegated to control_flow.rs");
// Temporary: Return None to trigger fallback
// Pattern 2 currently works via hardcoded route in control_flow.rs
eprintln!("[loop_patterns] Pattern 2: Lowering delegated to control_flow.rs (stub)");
None
}

View File

@ -73,7 +73,6 @@ use crate::mir::join_ir::{
BinOpKind, CompareOp, ConstValue, JoinFuncId, JoinFunction, JoinInst, JoinModule,
MirLikeInst, UnaryOp,
};
use crate::mir::ValueId;
/// Lower Pattern 3 (Loop with If-Else PHI) to JoinIR
///