Files
hakorune/src/mir/join_ir/lowering/if_select.rs

377 lines
13 KiB
Rust
Raw Normal View History

//! Phase 33: If/Else の Select 命令への lowering
//!
//! 最小の if/else副作用なし、単純な値選択を JoinInst::Select に変換する。
//!
//! ## 責務分離Phase 33-9.1
//!
//! **IfSelectLowerer の責務**:
//! - 単純 if/else副作用なし、単一変数を Select 命令に変換する
//!
//! **非責務**:
//! - Loop の PHI には触らないLoop lowering の責務)
use crate::mir::join_ir::JoinInst;
use crate::mir::{BasicBlockId, MirFunction, MirInstruction, ValueId};
feat(joinir): Phase 63-4 infer_type_from_phi degradation design Phase 63-4: infer_type_from_phi を『JoinIR 型ヒント優先+従来ロジックフォールバック』に縮退する仕様を設計(実装は Phase 63-5+) ## Changes ### Documentation Updates - **README.md**: Added complete Phase 63-4 design (63-4.1 through 63-4.5) - 63-4.1: Current state analysis (definition location, callsites, role, JoinIR preparation) - 63-4.2: Degradation spec (type_hint priority + fallback pattern) - 63-4.3: Representative cases and A/B testing strategy (P1/P2/P3) - 63-4.4: Deletion conditions (5 conditions, current: 2/5 = 40%) - 63-4.5: Phase 63-5 handoff (infer_type_from_phi_with_hint() implementation tasks) - **PHI_BOX_INVENTORY.md**: Updated if_phi.rs entry with Phase 63-4 deletion plan - Added: "Phase 63-4完了: infer_type_from_phi の JoinIR type_hint 優先への縮退案を設計(実装は Phase 63-5+)" - **CURRENT_TASK.md**: Added Phase 63-4 section with summary of design work ## Design Highlights ### Degradation Pattern ```rust pub fn infer_type_from_phi_with_hint( function: &MirFunction, ret_val: ValueId, types: &BTreeMap<ValueId, MirType>, type_hint: Option<MirType>, ) -> Option<MirType> { if let Some(hint) = type_hint { return Some(hint); // Route B: JoinIR priority (SSOT) } infer_type_from_phi(function, ret_val, types) // Route A: Fallback } ``` ### Representative Cases - **P1**: IfSelectTest.simple/local (Phase 63-5 target) - **P2**: read_quoted_from (Phase 63-6+ target) - **P3**: MethodCall/Box constructors (Phase 64+ expansion) ### Deletion Conditions (2/5 achieved) 1. ✅ JoinIR has type_hint field (Phase 63-3) 2. ✅ Type hints populated for representative cases (Phase 63-2) 3. ⏳ Degraded to type_hint priority (Phase 63-5) 4. ⏳ P1 cases determined by type_hint only (Phase 63-5) 5. ⏳ All functions use type hints (Phase 64+) ## Files Changed - docs/private/roadmap2/phases/phase-63-joinir-type-info/README.md - docs/private/roadmap2/phases/phase-30-final-joinir-world/PHI_BOX_INVENTORY.md - CURRENT_TASK.md ## Next Steps Phase 63-5: Implement degradation for P1 cases (IfSelectTest.simple/local) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 17:58:06 +09:00
// Phase 63-2: Type hint inference from MIR
// Phase 61-1: If-in-loop context support
use super::if_phi_context::IfPhiContext;
pub struct IfSelectLowerer {
debug_level: u8,
// Phase 61-1: If-in-loop context (None = Pure If)
#[allow(dead_code)]
context: Option<IfPhiContext>,
}
/// If/Else パターンの分類
#[derive(Debug, Clone, Copy)]
enum IfPatternType {
/// Simple pattern: if cond { return 1 } else { return 2 }
Simple,
/// Local pattern: if cond { x = a } else { x = b }; return x
Local,
}
/// 検出された If/Else パターン情報
#[derive(Debug, Clone)]
struct IfPattern {
pattern_type: IfPatternType,
cond: ValueId,
then_val: ValueId,
else_val: ValueId,
dst: Option<ValueId>,
}
/// Branch 命令の情報
#[derive(Debug, Clone)]
struct IfBranch {
cond: ValueId,
then_block: BasicBlockId,
else_block: BasicBlockId,
}
impl IfSelectLowerer {
pub fn new(debug_level: u8) -> Self {
Self {
debug_level,
context: None, // Phase 61-1: デフォルトは Pure If
}
}
/// Phase 33-8: debug-level backward compat wrapper
#[allow(dead_code)]
pub fn with_debug(debug: bool) -> Self {
Self {
debug_level: if debug { 1 } else { 0 },
context: None, // Phase 61-1: デフォルトは Pure If
}
}
/// Phase 61-1: If-in-loop 用コンストラクタ
///
/// # Arguments
///
/// * `debug_level` - デバッグログレベル (0-3)
/// * `context` - If-in-loop コンテキストcarrier_names 情報を含む)
///
/// # Example
///
/// ```ignore
/// let context = IfPhiContext::for_loop_body(carrier_names);
/// let lowerer = IfSelectLowerer::with_context(debug_level, context);
/// ```
pub fn with_context(debug_level: u8, context: IfPhiContext) -> Self {
Self {
debug_level,
context: Some(context),
}
}
/// if/else が Select に lowering できるかチェック
pub fn can_lower_to_select(&self, func: &MirFunction, if_block_id: BasicBlockId) -> bool {
self.find_if_pattern(func, if_block_id).is_some()
}
/// if/else を Select に変換
pub fn lower_if_to_select(
&self,
func: &MirFunction,
if_block_id: BasicBlockId,
) -> Option<JoinInst> {
let pattern = self.find_if_pattern(func, if_block_id)?;
// Phase 33-8: Level 1 - Basic lowering info
if self.debug_level >= 1 {
eprintln!(
"[IfSelectLowerer] ✅ lowering {:?} pattern to Select",
pattern.pattern_type
);
}
// Phase 33-8: Level 3 - Full pattern details
if self.debug_level >= 3 {
eprintln!("[IfSelectLowerer] cond: {:?}", pattern.cond);
eprintln!("[IfSelectLowerer] then_val: {:?}", pattern.then_val);
eprintln!("[IfSelectLowerer] else_val: {:?}", pattern.else_val);
eprintln!("[IfSelectLowerer] dst: {:?}", pattern.dst);
}
// Select 命令を生成
let dst = pattern.dst.unwrap_or(pattern.then_val);
feat(joinir): Phase 63-4 infer_type_from_phi degradation design Phase 63-4: infer_type_from_phi を『JoinIR 型ヒント優先+従来ロジックフォールバック』に縮退する仕様を設計(実装は Phase 63-5+) ## Changes ### Documentation Updates - **README.md**: Added complete Phase 63-4 design (63-4.1 through 63-4.5) - 63-4.1: Current state analysis (definition location, callsites, role, JoinIR preparation) - 63-4.2: Degradation spec (type_hint priority + fallback pattern) - 63-4.3: Representative cases and A/B testing strategy (P1/P2/P3) - 63-4.4: Deletion conditions (5 conditions, current: 2/5 = 40%) - 63-4.5: Phase 63-5 handoff (infer_type_from_phi_with_hint() implementation tasks) - **PHI_BOX_INVENTORY.md**: Updated if_phi.rs entry with Phase 63-4 deletion plan - Added: "Phase 63-4完了: infer_type_from_phi の JoinIR type_hint 優先への縮退案を設計(実装は Phase 63-5+)" - **CURRENT_TASK.md**: Added Phase 63-4 section with summary of design work ## Design Highlights ### Degradation Pattern ```rust pub fn infer_type_from_phi_with_hint( function: &MirFunction, ret_val: ValueId, types: &BTreeMap<ValueId, MirType>, type_hint: Option<MirType>, ) -> Option<MirType> { if let Some(hint) = type_hint { return Some(hint); // Route B: JoinIR priority (SSOT) } infer_type_from_phi(function, ret_val, types) // Route A: Fallback } ``` ### Representative Cases - **P1**: IfSelectTest.simple/local (Phase 63-5 target) - **P2**: read_quoted_from (Phase 63-6+ target) - **P3**: MethodCall/Box constructors (Phase 64+ expansion) ### Deletion Conditions (2/5 achieved) 1. ✅ JoinIR has type_hint field (Phase 63-3) 2. ✅ Type hints populated for representative cases (Phase 63-2) 3. ⏳ Degraded to type_hint priority (Phase 63-5) 4. ⏳ P1 cases determined by type_hint only (Phase 63-5) 5. ⏳ All functions use type hints (Phase 64+) ## Files Changed - docs/private/roadmap2/phases/phase-63-joinir-type-info/README.md - docs/private/roadmap2/phases/phase-30-final-joinir-world/PHI_BOX_INVENTORY.md - CURRENT_TASK.md ## Next Steps Phase 63-5: Implement degradation for P1 cases (IfSelectTest.simple/local) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 17:58:06 +09:00
// Phase 63-2: MIR の Const 命令から型ヒントを推論
let type_hint = infer_type_from_mir_pattern(func, pattern.then_val)
.or_else(|| infer_type_from_mir_pattern(func, pattern.else_val));
Some(JoinInst::Select {
dst,
cond: pattern.cond,
then_val: pattern.then_val,
else_val: pattern.else_val,
feat(joinir): Phase 63-4 infer_type_from_phi degradation design Phase 63-4: infer_type_from_phi を『JoinIR 型ヒント優先+従来ロジックフォールバック』に縮退する仕様を設計(実装は Phase 63-5+) ## Changes ### Documentation Updates - **README.md**: Added complete Phase 63-4 design (63-4.1 through 63-4.5) - 63-4.1: Current state analysis (definition location, callsites, role, JoinIR preparation) - 63-4.2: Degradation spec (type_hint priority + fallback pattern) - 63-4.3: Representative cases and A/B testing strategy (P1/P2/P3) - 63-4.4: Deletion conditions (5 conditions, current: 2/5 = 40%) - 63-4.5: Phase 63-5 handoff (infer_type_from_phi_with_hint() implementation tasks) - **PHI_BOX_INVENTORY.md**: Updated if_phi.rs entry with Phase 63-4 deletion plan - Added: "Phase 63-4完了: infer_type_from_phi の JoinIR type_hint 優先への縮退案を設計(実装は Phase 63-5+)" - **CURRENT_TASK.md**: Added Phase 63-4 section with summary of design work ## Design Highlights ### Degradation Pattern ```rust pub fn infer_type_from_phi_with_hint( function: &MirFunction, ret_val: ValueId, types: &BTreeMap<ValueId, MirType>, type_hint: Option<MirType>, ) -> Option<MirType> { if let Some(hint) = type_hint { return Some(hint); // Route B: JoinIR priority (SSOT) } infer_type_from_phi(function, ret_val, types) // Route A: Fallback } ``` ### Representative Cases - **P1**: IfSelectTest.simple/local (Phase 63-5 target) - **P2**: read_quoted_from (Phase 63-6+ target) - **P3**: MethodCall/Box constructors (Phase 64+ expansion) ### Deletion Conditions (2/5 achieved) 1. ✅ JoinIR has type_hint field (Phase 63-3) 2. ✅ Type hints populated for representative cases (Phase 63-2) 3. ⏳ Degraded to type_hint priority (Phase 63-5) 4. ⏳ P1 cases determined by type_hint only (Phase 63-5) 5. ⏳ All functions use type hints (Phase 64+) ## Files Changed - docs/private/roadmap2/phases/phase-63-joinir-type-info/README.md - docs/private/roadmap2/phases/phase-30-final-joinir-world/PHI_BOX_INVENTORY.md - CURRENT_TASK.md ## Next Steps Phase 63-5: Implement degradation for P1 cases (IfSelectTest.simple/local) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 17:58:06 +09:00
type_hint, // Phase 63-2: Const 命令から推論した型Integer/Bool/String など)
})
}
/// MIR 関数から if/else パターンを探す
fn find_if_pattern(&self, func: &MirFunction, block_id: BasicBlockId) -> Option<IfPattern> {
// 1. Block が Branch 命令で終わっているか確認
let block = func.blocks.get(&block_id)?;
let branch = match block.terminator.as_ref()? {
MirInstruction::Branch {
condition,
then_bb,
else_bb,
} => IfBranch {
cond: *condition,
then_block: *then_bb,
else_block: *else_bb,
},
_ => return None,
};
// 2. then/else ブロックの構造を確認
let then_block = func.blocks.get(&branch.then_block)?;
let else_block = func.blocks.get(&branch.else_block)?;
feat(joinir): Phase 34-6 MethodCall 構造と本物の substring 意味論 **Phase 34-6 実装完了**: MethodCall 構造を JoinIR に追加し、本物の substring 呼び出しを通すことに成功。 ## 主要変更 ### 1. MethodCall 構造追加 (34-6.1) - `src/mir/join_ir/mod.rs`: JoinInst::MethodCall バリアント (+8 lines) - 構造: `{ dst, receiver, method, args }` - 設計原則: JoinIR は構造のみ、意味論は MIR レベル ### 2. extract_value 更新 (34-6.2) - `src/mir/join_ir/frontend/ast_lowerer.rs`: Method 処理本物化 (+37 lines) - receiver/args を extract_value で再帰処理 - ダミー Const(0) 削除 → 本物の MethodCall 生成 - cond 処理修正: ValueId(0) ハードコード → extract_value で取得 ### 3. JoinIR→MIR 変換実装 (34-6.3) - `src/mir/join_ir_vm_bridge.rs`: MethodCall → BoxCall 変換 (+12 lines) - `src/mir/join_ir/json.rs`: MethodCall JSON シリアライゼーション (+16 lines) - `src/mir/join_ir_runner.rs`: MethodCall 未対応エラー (+7 lines) ### 4. テスト更新 (34-6.4) - `docs/.../fixtures/json_shape_read_value.program.json`: 本物の substring 構造 - `src/tests/joinir_frontend_if_select.rs`: run_joinir_via_vm 使用 - テスト成功: v="hello", at=3 → "hel" ✅ ## 成果 - ✅ テスト全通過(1 passed; 0 failed) - ✅ 設計原則確立: JoinIR = 構造 SSOT、意味論 = MIR レベル - ✅ Phase 33-10 原則との整合性: Method でも同じ原則適用 **ドキュメント更新**: CURRENT_TASK.md + TASKS.md(Phase 34-6 完了記録) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 17:05:46 +09:00
// Phase 33-10: PHI早期チェックパターンマッチング前
// JoinIRは「PHI生成器」であり「PHI変換器」ではない
// then/elseがJumpで終わる場合、merge blockにPHI命令があるか早期確認
if let Some(merge_block_id) =
self.get_merge_block_if_jump_pattern(&branch, then_block, else_block)
{
feat(joinir): Phase 34-6 MethodCall 構造と本物の substring 意味論 **Phase 34-6 実装完了**: MethodCall 構造を JoinIR に追加し、本物の substring 呼び出しを通すことに成功。 ## 主要変更 ### 1. MethodCall 構造追加 (34-6.1) - `src/mir/join_ir/mod.rs`: JoinInst::MethodCall バリアント (+8 lines) - 構造: `{ dst, receiver, method, args }` - 設計原則: JoinIR は構造のみ、意味論は MIR レベル ### 2. extract_value 更新 (34-6.2) - `src/mir/join_ir/frontend/ast_lowerer.rs`: Method 処理本物化 (+37 lines) - receiver/args を extract_value で再帰処理 - ダミー Const(0) 削除 → 本物の MethodCall 生成 - cond 処理修正: ValueId(0) ハードコード → extract_value で取得 ### 3. JoinIR→MIR 変換実装 (34-6.3) - `src/mir/join_ir_vm_bridge.rs`: MethodCall → BoxCall 変換 (+12 lines) - `src/mir/join_ir/json.rs`: MethodCall JSON シリアライゼーション (+16 lines) - `src/mir/join_ir_runner.rs`: MethodCall 未対応エラー (+7 lines) ### 4. テスト更新 (34-6.4) - `docs/.../fixtures/json_shape_read_value.program.json`: 本物の substring 構造 - `src/tests/joinir_frontend_if_select.rs`: run_joinir_via_vm 使用 - テスト成功: v="hello", at=3 → "hel" ✅ ## 成果 - ✅ テスト全通過(1 passed; 0 failed) - ✅ 設計原則確立: JoinIR = 構造 SSOT、意味論 = MIR レベル - ✅ Phase 33-10 原則との整合性: Method でも同じ原則適用 **ドキュメント更新**: CURRENT_TASK.md + TASKS.md(Phase 34-6 完了記録) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 17:05:46 +09:00
let merge_block = func.blocks.get(&merge_block_id)?;
if merge_block
.instructions
.iter()
.any(|inst| matches!(inst, MirInstruction::Phi { .. }))
{
feat(joinir): Phase 34-6 MethodCall 構造と本物の substring 意味論 **Phase 34-6 実装完了**: MethodCall 構造を JoinIR に追加し、本物の substring 呼び出しを通すことに成功。 ## 主要変更 ### 1. MethodCall 構造追加 (34-6.1) - `src/mir/join_ir/mod.rs`: JoinInst::MethodCall バリアント (+8 lines) - 構造: `{ dst, receiver, method, args }` - 設計原則: JoinIR は構造のみ、意味論は MIR レベル ### 2. extract_value 更新 (34-6.2) - `src/mir/join_ir/frontend/ast_lowerer.rs`: Method 処理本物化 (+37 lines) - receiver/args を extract_value で再帰処理 - ダミー Const(0) 削除 → 本物の MethodCall 生成 - cond 処理修正: ValueId(0) ハードコード → extract_value で取得 ### 3. JoinIR→MIR 変換実装 (34-6.3) - `src/mir/join_ir_vm_bridge.rs`: MethodCall → BoxCall 変換 (+12 lines) - `src/mir/join_ir/json.rs`: MethodCall JSON シリアライゼーション (+16 lines) - `src/mir/join_ir_runner.rs`: MethodCall 未対応エラー (+7 lines) ### 4. テスト更新 (34-6.4) - `docs/.../fixtures/json_shape_read_value.program.json`: 本物の substring 構造 - `src/tests/joinir_frontend_if_select.rs`: run_joinir_via_vm 使用 - テスト成功: v="hello", at=3 → "hel" ✅ ## 成果 - ✅ テスト全通過(1 passed; 0 failed) - ✅ 設計原則確立: JoinIR = 構造 SSOT、意味論 = MIR レベル - ✅ Phase 33-10 原則との整合性: Method でも同じ原則適用 **ドキュメント更新**: CURRENT_TASK.md + TASKS.md(Phase 34-6 完了記録) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 17:05:46 +09:00
if self.debug_level >= 2 {
eprintln!("[IfSelectLowerer] ⏭️ PHI already exists in merge block, skipping");
}
return None;
}
}
// 3. simple パターンのチェック
if let Some(pattern) = self.try_match_simple_pattern(&branch, then_block, else_block) {
// Phase 33-8: Level 2 - Pattern matching details
if self.debug_level >= 2 {
eprintln!("[IfSelectLowerer] ✅ matched simple pattern");
}
return Some(pattern);
}
// 4. local パターンのチェック
if let Some(pattern) = self.try_match_local_pattern(func, &branch, then_block, else_block) {
// Phase 33-8: Level 2 - Pattern matching details
if self.debug_level >= 2 {
eprintln!("[IfSelectLowerer] ✅ matched local pattern");
}
return Some(pattern);
}
// Phase 33-8: Level 2 - Pattern matching details
if self.debug_level >= 2 {
eprintln!("[IfSelectLowerer] ❌ no pattern matched");
}
None
}
/// simple パターン: if cond { return 1 } else { return 2 }
feat(joinir): Phase 34-6 MethodCall 構造と本物の substring 意味論 **Phase 34-6 実装完了**: MethodCall 構造を JoinIR に追加し、本物の substring 呼び出しを通すことに成功。 ## 主要変更 ### 1. MethodCall 構造追加 (34-6.1) - `src/mir/join_ir/mod.rs`: JoinInst::MethodCall バリアント (+8 lines) - 構造: `{ dst, receiver, method, args }` - 設計原則: JoinIR は構造のみ、意味論は MIR レベル ### 2. extract_value 更新 (34-6.2) - `src/mir/join_ir/frontend/ast_lowerer.rs`: Method 処理本物化 (+37 lines) - receiver/args を extract_value で再帰処理 - ダミー Const(0) 削除 → 本物の MethodCall 生成 - cond 処理修正: ValueId(0) ハードコード → extract_value で取得 ### 3. JoinIR→MIR 変換実装 (34-6.3) - `src/mir/join_ir_vm_bridge.rs`: MethodCall → BoxCall 変換 (+12 lines) - `src/mir/join_ir/json.rs`: MethodCall JSON シリアライゼーション (+16 lines) - `src/mir/join_ir_runner.rs`: MethodCall 未対応エラー (+7 lines) ### 4. テスト更新 (34-6.4) - `docs/.../fixtures/json_shape_read_value.program.json`: 本物の substring 構造 - `src/tests/joinir_frontend_if_select.rs`: run_joinir_via_vm 使用 - テスト成功: v="hello", at=3 → "hel" ✅ ## 成果 - ✅ テスト全通過(1 passed; 0 failed) - ✅ 設計原則確立: JoinIR = 構造 SSOT、意味論 = MIR レベル - ✅ Phase 33-10 原則との整合性: Method でも同じ原則適用 **ドキュメント更新**: CURRENT_TASK.md + TASKS.md(Phase 34-6 完了記録) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 17:05:46 +09:00
///
/// Phase 33-9.2: 実用MIR対応 - 副作用なし命令Const/Copyを許容
/// - 旧: Return のみinstructions empty
/// - 新: Const/Copy → Return を許容実MIRパターン
fn try_match_simple_pattern(
&self,
branch: &IfBranch,
then_block: &crate::mir::BasicBlock,
else_block: &crate::mir::BasicBlock,
) -> Option<IfPattern> {
// then ブロックが Return だけか確認
let then_val = match then_block.terminator.as_ref()? {
MirInstruction::Return { value: Some(v) } => *v,
_ => return None,
};
// else ブロックが Return だけか確認
let else_val = match else_block.terminator.as_ref()? {
MirInstruction::Return { value: Some(v) } => *v,
_ => return None,
};
feat(joinir): Phase 34-6 MethodCall 構造と本物の substring 意味論 **Phase 34-6 実装完了**: MethodCall 構造を JoinIR に追加し、本物の substring 呼び出しを通すことに成功。 ## 主要変更 ### 1. MethodCall 構造追加 (34-6.1) - `src/mir/join_ir/mod.rs`: JoinInst::MethodCall バリアント (+8 lines) - 構造: `{ dst, receiver, method, args }` - 設計原則: JoinIR は構造のみ、意味論は MIR レベル ### 2. extract_value 更新 (34-6.2) - `src/mir/join_ir/frontend/ast_lowerer.rs`: Method 処理本物化 (+37 lines) - receiver/args を extract_value で再帰処理 - ダミー Const(0) 削除 → 本物の MethodCall 生成 - cond 処理修正: ValueId(0) ハードコード → extract_value で取得 ### 3. JoinIR→MIR 変換実装 (34-6.3) - `src/mir/join_ir_vm_bridge.rs`: MethodCall → BoxCall 変換 (+12 lines) - `src/mir/join_ir/json.rs`: MethodCall JSON シリアライゼーション (+16 lines) - `src/mir/join_ir_runner.rs`: MethodCall 未対応エラー (+7 lines) ### 4. テスト更新 (34-6.4) - `docs/.../fixtures/json_shape_read_value.program.json`: 本物の substring 構造 - `src/tests/joinir_frontend_if_select.rs`: run_joinir_via_vm 使用 - テスト成功: v="hello", at=3 → "hel" ✅ ## 成果 - ✅ テスト全通過(1 passed; 0 failed) - ✅ 設計原則確立: JoinIR = 構造 SSOT、意味論 = MIR レベル - ✅ Phase 33-10 原則との整合性: Method でも同じ原則適用 **ドキュメント更新**: CURRENT_TASK.md + TASKS.md(Phase 34-6 完了記録) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 17:05:46 +09:00
// Phase 33-9.2: 副作用なし命令Const/Copyのみを許容
// - ユニットテストemptyも通過空配列 → all() = true
// - 実用MIRconst + retも通過
if !self.is_side_effect_free(&then_block.instructions)
|| !self.is_side_effect_free(&else_block.instructions)
{
return None;
}
Some(IfPattern {
pattern_type: IfPatternType::Simple,
cond: branch.cond,
then_val,
else_val,
dst: None,
})
}
feat(joinir): Phase 34-6 MethodCall 構造と本物の substring 意味論 **Phase 34-6 実装完了**: MethodCall 構造を JoinIR に追加し、本物の substring 呼び出しを通すことに成功。 ## 主要変更 ### 1. MethodCall 構造追加 (34-6.1) - `src/mir/join_ir/mod.rs`: JoinInst::MethodCall バリアント (+8 lines) - 構造: `{ dst, receiver, method, args }` - 設計原則: JoinIR は構造のみ、意味論は MIR レベル ### 2. extract_value 更新 (34-6.2) - `src/mir/join_ir/frontend/ast_lowerer.rs`: Method 処理本物化 (+37 lines) - receiver/args を extract_value で再帰処理 - ダミー Const(0) 削除 → 本物の MethodCall 生成 - cond 処理修正: ValueId(0) ハードコード → extract_value で取得 ### 3. JoinIR→MIR 変換実装 (34-6.3) - `src/mir/join_ir_vm_bridge.rs`: MethodCall → BoxCall 変換 (+12 lines) - `src/mir/join_ir/json.rs`: MethodCall JSON シリアライゼーション (+16 lines) - `src/mir/join_ir_runner.rs`: MethodCall 未対応エラー (+7 lines) ### 4. テスト更新 (34-6.4) - `docs/.../fixtures/json_shape_read_value.program.json`: 本物の substring 構造 - `src/tests/joinir_frontend_if_select.rs`: run_joinir_via_vm 使用 - テスト成功: v="hello", at=3 → "hel" ✅ ## 成果 - ✅ テスト全通過(1 passed; 0 failed) - ✅ 設計原則確立: JoinIR = 構造 SSOT、意味論 = MIR レベル - ✅ Phase 33-10 原則との整合性: Method でも同じ原則適用 **ドキュメント更新**: CURRENT_TASK.md + TASKS.md(Phase 34-6 完了記録) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 17:05:46 +09:00
/// Phase 33-9.2: 副作用なし命令判定ヘルパー
///
/// Const/Copy のみを許容分岐・call・書き込み等は除外
fn is_side_effect_free(&self, instructions: &[MirInstruction]) -> bool {
instructions.iter().all(|inst| {
matches!(
inst,
MirInstruction::Const { .. } | MirInstruction::Copy { .. }
)
})
}
/// Phase 33-10: Jump pattern 検出ヘルパー
///
/// then/else 両方が Jump で終わり、同じ merge block に飛んでいる場合、
/// その merge block IDを返す
fn get_merge_block_if_jump_pattern(
&self,
_branch: &IfBranch,
then_block: &crate::mir::BasicBlock,
else_block: &crate::mir::BasicBlock,
) -> Option<BasicBlockId> {
// then が Jump で終わるか確認
let then_target = match then_block.terminator.as_ref()? {
MirInstruction::Jump { target } => *target,
_ => return None,
};
// else が Jump で終わるか確認
let else_target = match else_block.terminator.as_ref()? {
MirInstruction::Jump { target } => *target,
_ => return None,
};
// 両方が同じ merge block に飛んでいるか確認
if then_target == else_target {
Some(then_target)
} else {
None
}
}
/// local パターン: if cond { x = a } else { x = b }; return x
feat(joinir): Phase 34-6 MethodCall 構造と本物の substring 意味論 **Phase 34-6 実装完了**: MethodCall 構造を JoinIR に追加し、本物の substring 呼び出しを通すことに成功。 ## 主要変更 ### 1. MethodCall 構造追加 (34-6.1) - `src/mir/join_ir/mod.rs`: JoinInst::MethodCall バリアント (+8 lines) - 構造: `{ dst, receiver, method, args }` - 設計原則: JoinIR は構造のみ、意味論は MIR レベル ### 2. extract_value 更新 (34-6.2) - `src/mir/join_ir/frontend/ast_lowerer.rs`: Method 処理本物化 (+37 lines) - receiver/args を extract_value で再帰処理 - ダミー Const(0) 削除 → 本物の MethodCall 生成 - cond 処理修正: ValueId(0) ハードコード → extract_value で取得 ### 3. JoinIR→MIR 変換実装 (34-6.3) - `src/mir/join_ir_vm_bridge.rs`: MethodCall → BoxCall 変換 (+12 lines) - `src/mir/join_ir/json.rs`: MethodCall JSON シリアライゼーション (+16 lines) - `src/mir/join_ir_runner.rs`: MethodCall 未対応エラー (+7 lines) ### 4. テスト更新 (34-6.4) - `docs/.../fixtures/json_shape_read_value.program.json`: 本物の substring 構造 - `src/tests/joinir_frontend_if_select.rs`: run_joinir_via_vm 使用 - テスト成功: v="hello", at=3 → "hel" ✅ ## 成果 - ✅ テスト全通過(1 passed; 0 failed) - ✅ 設計原則確立: JoinIR = 構造 SSOT、意味論 = MIR レベル - ✅ Phase 33-10 原則との整合性: Method でも同じ原則適用 **ドキュメント更新**: CURRENT_TASK.md + TASKS.md(Phase 34-6 完了記録) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 17:05:46 +09:00
///
/// Phase 33-10: 実用MIR対応 - Const命令を許容
/// - 旧: Copy命令のみユニットテスト想定
/// - 新: Const/Copy命令を許容実MIR対応、Simple patternと同じ修正
fn try_match_local_pattern(
&self,
func: &MirFunction,
branch: &IfBranch,
then_block: &crate::mir::BasicBlock,
else_block: &crate::mir::BasicBlock,
) -> Option<IfPattern> {
feat(joinir): Phase 34-6 MethodCall 構造と本物の substring 意味論 **Phase 34-6 実装完了**: MethodCall 構造を JoinIR に追加し、本物の substring 呼び出しを通すことに成功。 ## 主要変更 ### 1. MethodCall 構造追加 (34-6.1) - `src/mir/join_ir/mod.rs`: JoinInst::MethodCall バリアント (+8 lines) - 構造: `{ dst, receiver, method, args }` - 設計原則: JoinIR は構造のみ、意味論は MIR レベル ### 2. extract_value 更新 (34-6.2) - `src/mir/join_ir/frontend/ast_lowerer.rs`: Method 処理本物化 (+37 lines) - receiver/args を extract_value で再帰処理 - ダミー Const(0) 削除 → 本物の MethodCall 生成 - cond 処理修正: ValueId(0) ハードコード → extract_value で取得 ### 3. JoinIR→MIR 変換実装 (34-6.3) - `src/mir/join_ir_vm_bridge.rs`: MethodCall → BoxCall 変換 (+12 lines) - `src/mir/join_ir/json.rs`: MethodCall JSON シリアライゼーション (+16 lines) - `src/mir/join_ir_runner.rs`: MethodCall 未対応エラー (+7 lines) ### 4. テスト更新 (34-6.4) - `docs/.../fixtures/json_shape_read_value.program.json`: 本物の substring 構造 - `src/tests/joinir_frontend_if_select.rs`: run_joinir_via_vm 使用 - テスト成功: v="hello", at=3 → "hel" ✅ ## 成果 - ✅ テスト全通過(1 passed; 0 failed) - ✅ 設計原則確立: JoinIR = 構造 SSOT、意味論 = MIR レベル - ✅ Phase 33-10 原則との整合性: Method でも同じ原則適用 **ドキュメント更新**: CURRENT_TASK.md + TASKS.md(Phase 34-6 完了記録) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 17:05:46 +09:00
// Phase 33-10: 副作用なし命令のみを許容
if !self.is_side_effect_free(&then_block.instructions) {
return None;
}
feat(joinir): Phase 34-6 MethodCall 構造と本物の substring 意味論 **Phase 34-6 実装完了**: MethodCall 構造を JoinIR に追加し、本物の substring 呼び出しを通すことに成功。 ## 主要変更 ### 1. MethodCall 構造追加 (34-6.1) - `src/mir/join_ir/mod.rs`: JoinInst::MethodCall バリアント (+8 lines) - 構造: `{ dst, receiver, method, args }` - 設計原則: JoinIR は構造のみ、意味論は MIR レベル ### 2. extract_value 更新 (34-6.2) - `src/mir/join_ir/frontend/ast_lowerer.rs`: Method 処理本物化 (+37 lines) - receiver/args を extract_value で再帰処理 - ダミー Const(0) 削除 → 本物の MethodCall 生成 - cond 処理修正: ValueId(0) ハードコード → extract_value で取得 ### 3. JoinIR→MIR 変換実装 (34-6.3) - `src/mir/join_ir_vm_bridge.rs`: MethodCall → BoxCall 変換 (+12 lines) - `src/mir/join_ir/json.rs`: MethodCall JSON シリアライゼーション (+16 lines) - `src/mir/join_ir_runner.rs`: MethodCall 未対応エラー (+7 lines) ### 4. テスト更新 (34-6.4) - `docs/.../fixtures/json_shape_read_value.program.json`: 本物の substring 構造 - `src/tests/joinir_frontend_if_select.rs`: run_joinir_via_vm 使用 - テスト成功: v="hello", at=3 → "hel" ✅ ## 成果 - ✅ テスト全通過(1 passed; 0 failed) - ✅ 設計原則確立: JoinIR = 構造 SSOT、意味論 = MIR レベル - ✅ Phase 33-10 原則との整合性: Method でも同じ原則適用 **ドキュメント更新**: CURRENT_TASK.md + TASKS.md(Phase 34-6 完了記録) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 17:05:46 +09:00
// then ブロックの最後の値を取得
// Phase 33-10: Const命令も許容実MIR対応
let (dst_then, val_then) = if then_block.instructions.len() == 1 {
match &then_block.instructions[0] {
MirInstruction::Copy { dst, src } => (*dst, *src),
MirInstruction::Const { dst, .. } => (*dst, *dst), // Constの場合、dst自身が値
_ => return None,
}
} else {
return None;
};
// then ブロックが Jump で終わるか確認
let merge_block_id = match then_block.terminator.as_ref()? {
MirInstruction::Jump { target } => *target,
_ => return None,
};
feat(joinir): Phase 34-6 MethodCall 構造と本物の substring 意味論 **Phase 34-6 実装完了**: MethodCall 構造を JoinIR に追加し、本物の substring 呼び出しを通すことに成功。 ## 主要変更 ### 1. MethodCall 構造追加 (34-6.1) - `src/mir/join_ir/mod.rs`: JoinInst::MethodCall バリアント (+8 lines) - 構造: `{ dst, receiver, method, args }` - 設計原則: JoinIR は構造のみ、意味論は MIR レベル ### 2. extract_value 更新 (34-6.2) - `src/mir/join_ir/frontend/ast_lowerer.rs`: Method 処理本物化 (+37 lines) - receiver/args を extract_value で再帰処理 - ダミー Const(0) 削除 → 本物の MethodCall 生成 - cond 処理修正: ValueId(0) ハードコード → extract_value で取得 ### 3. JoinIR→MIR 変換実装 (34-6.3) - `src/mir/join_ir_vm_bridge.rs`: MethodCall → BoxCall 変換 (+12 lines) - `src/mir/join_ir/json.rs`: MethodCall JSON シリアライゼーション (+16 lines) - `src/mir/join_ir_runner.rs`: MethodCall 未対応エラー (+7 lines) ### 4. テスト更新 (34-6.4) - `docs/.../fixtures/json_shape_read_value.program.json`: 本物の substring 構造 - `src/tests/joinir_frontend_if_select.rs`: run_joinir_via_vm 使用 - テスト成功: v="hello", at=3 → "hel" ✅ ## 成果 - ✅ テスト全通過(1 passed; 0 failed) - ✅ 設計原則確立: JoinIR = 構造 SSOT、意味論 = MIR レベル - ✅ Phase 33-10 原則との整合性: Method でも同じ原則適用 **ドキュメント更新**: CURRENT_TASK.md + TASKS.md(Phase 34-6 完了記録) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 17:05:46 +09:00
// Phase 33-10: else ブロックも副作用なし命令のみを許容
if !self.is_side_effect_free(&else_block.instructions) {
return None;
}
feat(joinir): Phase 34-6 MethodCall 構造と本物の substring 意味論 **Phase 34-6 実装完了**: MethodCall 構造を JoinIR に追加し、本物の substring 呼び出しを通すことに成功。 ## 主要変更 ### 1. MethodCall 構造追加 (34-6.1) - `src/mir/join_ir/mod.rs`: JoinInst::MethodCall バリアント (+8 lines) - 構造: `{ dst, receiver, method, args }` - 設計原則: JoinIR は構造のみ、意味論は MIR レベル ### 2. extract_value 更新 (34-6.2) - `src/mir/join_ir/frontend/ast_lowerer.rs`: Method 処理本物化 (+37 lines) - receiver/args を extract_value で再帰処理 - ダミー Const(0) 削除 → 本物の MethodCall 生成 - cond 処理修正: ValueId(0) ハードコード → extract_value で取得 ### 3. JoinIR→MIR 変換実装 (34-6.3) - `src/mir/join_ir_vm_bridge.rs`: MethodCall → BoxCall 変換 (+12 lines) - `src/mir/join_ir/json.rs`: MethodCall JSON シリアライゼーション (+16 lines) - `src/mir/join_ir_runner.rs`: MethodCall 未対応エラー (+7 lines) ### 4. テスト更新 (34-6.4) - `docs/.../fixtures/json_shape_read_value.program.json`: 本物の substring 構造 - `src/tests/joinir_frontend_if_select.rs`: run_joinir_via_vm 使用 - テスト成功: v="hello", at=3 → "hel" ✅ ## 成果 - ✅ テスト全通過(1 passed; 0 failed) - ✅ 設計原則確立: JoinIR = 構造 SSOT、意味論 = MIR レベル - ✅ Phase 33-10 原則との整合性: Method でも同じ原則適用 **ドキュメント更新**: CURRENT_TASK.md + TASKS.md(Phase 34-6 完了記録) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 17:05:46 +09:00
// else ブロックの最後の値を取得
let (dst_else, val_else) = if else_block.instructions.len() == 1 {
match &else_block.instructions[0] {
MirInstruction::Copy { dst, src } => (*dst, *src),
MirInstruction::Const { dst, .. } => (*dst, *dst), // Constの場合、dst自身が値
_ => return None,
}
} else {
return None;
};
// 代入先が同じ変数か確認
if dst_then != dst_else {
return None;
}
// else ブロックも同じ merge ブロックに Jump するか確認
let else_merge = match else_block.terminator.as_ref()? {
MirInstruction::Jump { target } => *target,
_ => return None,
};
if merge_block_id != else_merge {
return None;
}
// merge ブロックが「return dst」だけか確認
let merge_block = func.blocks.get(&merge_block_id)?;
feat(joinir): Phase 34-6 MethodCall 構造と本物の substring 意味論 **Phase 34-6 実装完了**: MethodCall 構造を JoinIR に追加し、本物の substring 呼び出しを通すことに成功。 ## 主要変更 ### 1. MethodCall 構造追加 (34-6.1) - `src/mir/join_ir/mod.rs`: JoinInst::MethodCall バリアント (+8 lines) - 構造: `{ dst, receiver, method, args }` - 設計原則: JoinIR は構造のみ、意味論は MIR レベル ### 2. extract_value 更新 (34-6.2) - `src/mir/join_ir/frontend/ast_lowerer.rs`: Method 処理本物化 (+37 lines) - receiver/args を extract_value で再帰処理 - ダミー Const(0) 削除 → 本物の MethodCall 生成 - cond 処理修正: ValueId(0) ハードコード → extract_value で取得 ### 3. JoinIR→MIR 変換実装 (34-6.3) - `src/mir/join_ir_vm_bridge.rs`: MethodCall → BoxCall 変換 (+12 lines) - `src/mir/join_ir/json.rs`: MethodCall JSON シリアライゼーション (+16 lines) - `src/mir/join_ir_runner.rs`: MethodCall 未対応エラー (+7 lines) ### 4. テスト更新 (34-6.4) - `docs/.../fixtures/json_shape_read_value.program.json`: 本物の substring 構造 - `src/tests/joinir_frontend_if_select.rs`: run_joinir_via_vm 使用 - テスト成功: v="hello", at=3 → "hel" ✅ ## 成果 - ✅ テスト全通過(1 passed; 0 failed) - ✅ 設計原則確立: JoinIR = 構造 SSOT、意味論 = MIR レベル - ✅ Phase 33-10 原則との整合性: Method でも同じ原則適用 **ドキュメント更新**: CURRENT_TASK.md + TASKS.md(Phase 34-6 完了記録) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 17:05:46 +09:00
// Phase 33-10: PHIチェックは find_if_pattern() で早期実行済み
match merge_block.terminator.as_ref()? {
MirInstruction::Return { value: Some(v) } if *v == dst_then => {
// OK
}
_ => return None,
}
if !merge_block.instructions.is_empty() {
return None;
}
Some(IfPattern {
pattern_type: IfPatternType::Local,
cond: branch.cond,
then_val: val_then,
else_val: val_else,
dst: Some(dst_then),
})
}
}
feat(joinir): Phase 63-4 infer_type_from_phi degradation design Phase 63-4: infer_type_from_phi を『JoinIR 型ヒント優先+従来ロジックフォールバック』に縮退する仕様を設計(実装は Phase 63-5+) ## Changes ### Documentation Updates - **README.md**: Added complete Phase 63-4 design (63-4.1 through 63-4.5) - 63-4.1: Current state analysis (definition location, callsites, role, JoinIR preparation) - 63-4.2: Degradation spec (type_hint priority + fallback pattern) - 63-4.3: Representative cases and A/B testing strategy (P1/P2/P3) - 63-4.4: Deletion conditions (5 conditions, current: 2/5 = 40%) - 63-4.5: Phase 63-5 handoff (infer_type_from_phi_with_hint() implementation tasks) - **PHI_BOX_INVENTORY.md**: Updated if_phi.rs entry with Phase 63-4 deletion plan - Added: "Phase 63-4完了: infer_type_from_phi の JoinIR type_hint 優先への縮退案を設計(実装は Phase 63-5+)" - **CURRENT_TASK.md**: Added Phase 63-4 section with summary of design work ## Design Highlights ### Degradation Pattern ```rust pub fn infer_type_from_phi_with_hint( function: &MirFunction, ret_val: ValueId, types: &BTreeMap<ValueId, MirType>, type_hint: Option<MirType>, ) -> Option<MirType> { if let Some(hint) = type_hint { return Some(hint); // Route B: JoinIR priority (SSOT) } infer_type_from_phi(function, ret_val, types) // Route A: Fallback } ``` ### Representative Cases - **P1**: IfSelectTest.simple/local (Phase 63-5 target) - **P2**: read_quoted_from (Phase 63-6+ target) - **P3**: MethodCall/Box constructors (Phase 64+ expansion) ### Deletion Conditions (2/5 achieved) 1. ✅ JoinIR has type_hint field (Phase 63-3) 2. ✅ Type hints populated for representative cases (Phase 63-2) 3. ⏳ Degraded to type_hint priority (Phase 63-5) 4. ⏳ P1 cases determined by type_hint only (Phase 63-5) 5. ⏳ All functions use type hints (Phase 64+) ## Files Changed - docs/private/roadmap2/phases/phase-63-joinir-type-info/README.md - docs/private/roadmap2/phases/phase-30-final-joinir-world/PHI_BOX_INVENTORY.md - CURRENT_TASK.md ## Next Steps Phase 63-5: Implement degradation for P1 cases (IfSelectTest.simple/local) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 17:58:06 +09:00
// Phase 185: infer_type_from_mir_pattern() moved to common.rs
use super::common::infer_type_from_mir_pattern;