diff --git a/CLAUDE.md b/CLAUDE.md index f0636144..2cd0dfbc 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -276,15 +276,16 @@ NYASH_DISABLE_PLUGINS=1 ./target/release/nyash program.nyash NYASH_LLVM_USE_HARNESS=1 ./target/release/nyash program.nyash ``` -## 📝 Update (2025-09-22) ⚡ フェーズM実装大幅進展!PHI一本化によるコード大削減達成 -- ✅ **MirBuilder no_phi_mode完全撤廃!** phi.rs、exprs_peek.rs全分岐をPHI命令一本化 -- ✅ **LoopBuilder no_phi_mode完全撤廃!** 3箇所のedge copy分岐をPHI命令一本化 -- ✅ **edge_copy関連コード削除!** insert_edge_copy()メソッド含む数十行削減 -- 🔧 **ビルド成功維持!** フェーズS+フェーズM修正でもエラーなしを確認 -- ⏳ **JSON v0 Bridge保留中**: Phase 15重要コンポーネントのため慎重対応予定 -- 🎯 **次の一歩**: collect_prints動作確認→JSON v0 Bridge対応→フェーズM完了 -- 📊 **戦略文書更新**: break-control-flow-strategy.mdの段階的根治計画に沿って実行 -- 🚀 **効果**: 数百行削減によりPhase 15の80k→20k圧縮目標に大きく貢献 +## 📝 Update (2025-09-23) 🚀 フェーズM+M.2完全達成!PHI統一革命完了 +- ✅ **フェーズM.2完全達成!** JSON v0 Bridge層クリーンアップ完了でPHI完全統一実現 +- ✅ **8箇所のno_phi分岐完全削除!** try_catch(3)、ternary(1)、peek(1)、loop_(2)、expr(1) +- ✅ **strip_phi_functions()削除!** 40行の複雑なPHI→edge-copy後処理撤廃 +- ✅ **config::env::mir_no_phi()大幅簡略化!** 40行→8行、phi-legacy依存完全除去 +- ✅ **未使用コード完全削除!** PHI_ON_GATED_WARNED static、mir_no_phiフィールド等 +- 🔧 **安定性完全確認!** cargo check成功、基本・複雑PHIテスト両方正常動作 +- 📊 **圧縮効果絶大!** フェーズM+M.2で推定500行超削減達成 +- 🎯 **Phase 15準備完了**: MIR層PHI統一により80k→20k行圧縮の主要基盤完成 +- 🚀 **次段階**: collect_prints動作確認→JSON v0 Bridge最終統合→Phase 15完遂 ## 📝 Update (2025-09-22) 🎯 Phase 15 JITアーカイブ完了&デバッグ大進展! - ✅ **JIT/Craneliftアーカイブ完了!** Phase 15集中開発のため全JIT機能を安全にアーカイブ diff --git a/src/config/env.rs b/src/config/env.rs index f85c9a50..069e8389 100644 --- a/src/config/env.rs +++ b/src/config/env.rs @@ -36,7 +36,7 @@ use once_cell::sync::OnceCell; use std::sync::RwLock; static GLOBAL_ENV: OnceCell> = OnceCell::new(); -static PHI_ON_GATED_WARNED: OnceCell<()> = OnceCell::new(); +// フェーズM.2: PHI_ON_GATED_WARNED削除(phi-legacy簡略化により不要) pub fn current() -> NyashEnv { if let Some(lock) = GLOBAL_ENV.get() { @@ -109,47 +109,13 @@ pub fn await_max_ms() -> u64 { } // ---- MIR PHI / PHI-less (edge-copy) mode ---- -/// Enable MIR PHI non-generation. Bridge/Builder emit edge copies instead of PHI. -/// Default: PHI-ON when the build supports it (feature `phi-legacy`), otherwise fall back to PHI-OFF. +/// Enable MIR PHI non-generation for Bridge compatibility mode only. +/// フェーズM.2: MirBuilder/LoopBuilderでPHI統一済み、Bridge層の互換性制御のみ +/// Default: PHI-ON (Phase 15 direction), override with NYASH_MIR_NO_PHI=1 pub fn mir_no_phi() -> bool { - match std::env::var("NYASH_MIR_NO_PHI").ok() { - Some(v) => { - let lv = v.to_ascii_lowercase(); - let requested_no_phi = !(lv == "0" || lv == "false" || lv == "off"); - if requested_no_phi { - return true; - } - // PHI-on requested explicitly - #[cfg(feature = "phi-legacy")] - { - return false; - } - #[cfg(not(feature = "phi-legacy"))] - { - if PHI_ON_GATED_WARNED.set(()).is_ok() { - eprintln!( - "[nyash] PHI-on requested but disabled in this build (missing 'phi-legacy' feature). Falling back to PHI-off." - ); - } - return true; - } - } - None => { - // Default preference: PHI-ON if available - #[cfg(feature = "phi-legacy")] - { - return false; - } - #[cfg(not(feature = "phi-legacy"))] - { - if PHI_ON_GATED_WARNED.set(()).is_ok() { - eprintln!( - "[nyash] Default PHI-on requested but build lacks 'phi-legacy' feature; falling back to PHI-off." - ); - } - return true; - } - } + match std::env::var("NYASH_MIR_NO_PHI").ok().as_deref() { + Some("1") | Some("true") | Some("on") => true, + _ => false, // フェーズM.2: デフォルトPHI-ON統一 } } diff --git a/src/mir/loop_builder.rs b/src/mir/loop_builder.rs index 2c847100..8c60cc91 100644 --- a/src/mir/loop_builder.rs +++ b/src/mir/loop_builder.rs @@ -7,13 +7,12 @@ use super::{BasicBlockId, ConstValue, MirInstruction, ValueId}; use crate::ast::ASTNode; -use std::collections::{HashMap, HashSet}; +use std::collections::HashMap; // Phase 15 段階的根治戦略:制御フローユーティリティ use super::utils::{ is_current_block_terminated, capture_actual_predecessor_and_jump, - collect_phi_incoming_if_reachable, }; /// 不完全なPhi nodeの情報 diff --git a/src/runner/json_v0_bridge/lowering.rs b/src/runner/json_v0_bridge/lowering.rs index d4a6918e..ffa8e642 100644 --- a/src/runner/json_v0_bridge/lowering.rs +++ b/src/runner/json_v0_bridge/lowering.rs @@ -26,7 +26,7 @@ pub(super) struct LoopContext { #[derive(Clone)] pub(super) struct BridgeEnv { pub(super) throw_enabled: bool, - pub(super) mir_no_phi: bool, + // フェーズM.2: mir_no_phiフィールド削除(PHI統一で不要) pub(super) allow_me_dummy: bool, pub(super) me_class: String, pub(super) try_result_mode: bool, @@ -35,13 +35,13 @@ pub(super) struct BridgeEnv { impl BridgeEnv { pub(super) fn load() -> Self { let trm = crate::config::env::try_result_mode(); - let no_phi = crate::config::env::mir_no_phi(); + // フェーズM.2: no_phi変数削除 if crate::config::env::cli_verbose() { - eprintln!("[Bridge] load: try_result_mode={} mir_no_phi={}", trm, no_phi); + eprintln!("[Bridge] load: try_result_mode={}", trm); } Self { throw_enabled: std::env::var("NYASH_BRIDGE_THROW_ENABLE").ok().as_deref() == Some("1"), - mir_no_phi: no_phi, + // フェーズM.2: mir_no_phiフィールド削除 allow_me_dummy: std::env::var("NYASH_BRIDGE_ME_DUMMY").ok().as_deref() == Some("1"), me_class: std::env::var("NYASH_BRIDGE_ME_CLASS").unwrap_or_else(|_| "Main".to_string()), try_result_mode: trm, @@ -61,45 +61,7 @@ fn jump_with_pred(f: &mut MirFunction, cur_bb: BasicBlockId, target: BasicBlockI /// Strip Phi instructions by inserting edge copies on each predecessor. /// This normalizes MIR to PHI-off form for downstream harnesses that synthesize PHIs. -fn strip_phi_functions(f: &mut MirFunction) { - // Collect block ids to avoid borrow issues while mutating - let block_ids: Vec = f.blocks.keys().copied().collect(); - for bbid in block_ids { - // Snapshot phi instructions at the head - let mut phi_entries: Vec<(ValueId, Vec<(BasicBlockId, ValueId)>)> = Vec::new(); - if let Some(bb) = f.blocks.get(&bbid) { - for inst in &bb.instructions { - if let MirInstruction::Phi { dst, inputs } = inst { - phi_entries.push((*dst, inputs.clone())); - } else { - // PHIs must be at the beginning; once we see non-Phi, stop - break; - } - } - } - if phi_entries.is_empty() { - continue; - } - // Insert copies on predecessors - for (dst, inputs) in &phi_entries { - for (pred, val) in inputs { - if let Some(pbb) = f.blocks.get_mut(pred) { - pbb.add_instruction(MirInstruction::Copy { dst: *dst, src: *val }); - } - } - } - // Remove Phi instructions from the merge block - if let Some(bb) = f.blocks.get_mut(&bbid) { - let non_phi: Vec = bb - .instructions - .iter() - .cloned() - .skip_while(|inst| matches!(inst, MirInstruction::Phi { .. })) - .collect(); - bb.instructions = non_phi; - } - } -} +// フェーズM.2: strip_phi_functions()削除 - PHI統一により不要 fn lower_break_stmt(f: &mut MirFunction, cur_bb: BasicBlockId, exit_bb: BasicBlockId) { jump_with_pred(f, cur_bb, exit_bb); @@ -256,10 +218,7 @@ pub(super) fn lower_program(prog: ProgramV0) -> Result { } } f.signature.return_type = MirType::Unknown; - // PHI-off normalization for Bridge output - if env.mir_no_phi { - strip_phi_functions(&mut f); - } + // フェーズM.2: PHI後処理削除 - MirBuilder/LoopBuilderでPHI統一済み module.add_function(f); Ok(module) } diff --git a/src/runner/json_v0_bridge/lowering/expr.rs b/src/runner/json_v0_bridge/lowering/expr.rs index 2d0839b8..d1258e10 100644 --- a/src/runner/json_v0_bridge/lowering/expr.rs +++ b/src/runner/json_v0_bridge/lowering/expr.rs @@ -255,14 +255,8 @@ pub(super) fn lower_expr_with_scope( } } let out = f.next_value_id(); - if env.mir_no_phi { - if let Some(bb) = f.get_block_mut(fall_bb) { - bb.add_instruction(MirInstruction::Copy { dst: out, src: cdst }); - } - if let Some(bb) = f.get_block_mut(rhs_end) { - bb.add_instruction(MirInstruction::Copy { dst: out, src: rval }); - } - } else if let Some(bb) = f.get_block_mut(merge_bb) { + // フェーズM.2: PHI統一処理(no_phi分岐削除) + if let Some(bb) = f.get_block_mut(merge_bb) { let mut inputs: Vec<(BasicBlockId, ValueId)> = vec![(fall_bb, cdst)]; if rhs_end != fall_bb { inputs.push((rhs_end, rval)); diff --git a/src/runner/json_v0_bridge/lowering/loop_.rs b/src/runner/json_v0_bridge/lowering/loop_.rs index d6c88b4a..b5ba4604 100644 --- a/src/runner/json_v0_bridge/lowering/loop_.rs +++ b/src/runner/json_v0_bridge/lowering/loop_.rs @@ -21,18 +21,15 @@ pub(super) fn lower_loop_stmt( bb.add_instruction(MirInstruction::Jump { target: cond_bb }); } } - let no_phi = env.mir_no_phi; + // フェーズM.2: no_phi変数削除 let base_vars = vars.clone(); let orig_names: Vec = base_vars.keys().cloned().collect(); let mut phi_map: HashMap = HashMap::new(); for name in &orig_names { if let Some(&bval) = base_vars.get(name) { let dst = f.next_value_id(); - if no_phi { - if let Some(bb) = f.get_block_mut(cur_bb) { - bb.add_instruction(MirInstruction::Copy { dst, src: bval }); - } - } else if let Some(bb) = f.get_block_mut(cond_bb) { + // フェーズM.2: PHI統一処理(no_phi分岐削除) + if let Some(bb) = f.get_block_mut(cond_bb) { bb.insert_instruction_after_phis(MirInstruction::Phi { dst, inputs: vec![(cur_bb, bval)], @@ -69,18 +66,8 @@ pub(super) fn lower_loop_stmt( Some(MirInstruction::Jump { target, .. }) if *target == cond_bb ); if backedge_to_cond { - if no_phi { - for (name, &phi_dst) in &phi_map { - if let Some(&latch_val) = body_vars.get(name) { - if let Some(bb) = f.get_block_mut(bend) { - bb.add_instruction(MirInstruction::Copy { - dst: phi_dst, - src: latch_val, - }); - } - } - } - } else if let Some(bb) = f.get_block_mut(cond_bb) { + // フェーズM.2: PHI統一処理(no_phi分岐削除) + if let Some(bb) = f.get_block_mut(cond_bb) { for (name, &phi_dst) in &phi_map { if let Some(&latch_val) = body_vars.get(name) { for inst in &mut bb.instructions { diff --git a/src/runner/json_v0_bridge/lowering/peek.rs b/src/runner/json_v0_bridge/lowering/peek.rs index 71ceeec1..05eca213 100644 --- a/src/runner/json_v0_bridge/lowering/peek.rs +++ b/src/runner/json_v0_bridge/lowering/peek.rs @@ -69,13 +69,8 @@ pub(super) fn lower_peek_expr_with_scope( // Merge result let out = f.next_value_id(); - if env.mir_no_phi { - for (pred, val) in phi_inputs { - if let Some(bb) = f.get_block_mut(pred) { - bb.add_instruction(MirInstruction::Copy { dst: out, src: val }); - } - } - } else if let Some(bb) = f.get_block_mut(merge_bb) { + // フェーズM.2: PHI統一処理(no_phi分岐削除) + if let Some(bb) = f.get_block_mut(merge_bb) { let mut inputs = phi_inputs; inputs.sort_by_key(|(bbid, _)| bbid.0); bb.insert_instruction_after_phis(MirInstruction::Phi { dst: out, inputs }); diff --git a/src/runner/json_v0_bridge/lowering/ternary.rs b/src/runner/json_v0_bridge/lowering/ternary.rs index ef6d5bf0..26ee13f6 100644 --- a/src/runner/json_v0_bridge/lowering/ternary.rs +++ b/src/runner/json_v0_bridge/lowering/ternary.rs @@ -44,14 +44,8 @@ pub(super) fn lower_ternary_expr_with_scope( } } let out = f.next_value_id(); - if env.mir_no_phi { - if let Some(bb) = f.get_block_mut(tend) { - bb.add_instruction(MirInstruction::Copy { dst: out, src: tval }); - } - if let Some(bb) = f.get_block_mut(eend) { - bb.add_instruction(MirInstruction::Copy { dst: out, src: eval }); - } - } else if let Some(bb) = f.get_block_mut(merge_bb) { + // フェーズM.2: PHI統一処理(no_phi分岐削除) + if let Some(bb) = f.get_block_mut(merge_bb) { let mut inputs = vec![(tend, tval), (eend, eval)]; inputs.sort_by_key(|(bbid, _)| bbid.0); bb.insert_instruction_after_phis(MirInstruction::Phi { dst: out, inputs }); diff --git a/src/runner/json_v0_bridge/lowering/try_catch.rs b/src/runner/json_v0_bridge/lowering/try_catch.rs index cf3929e1..0c469eeb 100644 --- a/src/runner/json_v0_bridge/lowering/try_catch.rs +++ b/src/runner/json_v0_bridge/lowering/try_catch.rs @@ -70,7 +70,8 @@ pub(super) fn lower_try_stmt( let catch_clause = &catches[0]; let mut catch_vars = base_vars.clone(); if let Some(param) = &catch_clause.param { - if !env.mir_no_phi && !incoming_exc.is_empty() { + // フェーズM.2: PHI統一処理(no_phi条件削除) + if !incoming_exc.is_empty() { let phi_dst = f.next_value_id(); if let Some(bb) = f.get_block_mut(catch_bb) { let mut inputs = incoming_exc.clone(); @@ -281,16 +282,8 @@ pub(super) fn lower_try_stmt( phi_entries.push((dst, inputs)); merged_vars.insert(name.clone(), dst); } - if env.mir_no_phi { - // Emit edge copies on predecessors instead of Phi at merge - for (dst, inputs) in phi_entries { - for (pred, val) in inputs { - if let Some(pbb) = f.get_block_mut(pred) { - pbb.add_instruction(MirInstruction::Copy { dst, src: val }); - } - } - } - } else if let Some(bb) = f.get_block_mut(finally_block) { + // フェーズM.2: PHI統一処理(no_phi分岐削除) + if let Some(bb) = f.get_block_mut(finally_block) { for (dst, inputs) in phi_entries { bb.insert_instruction_after_phis(MirInstruction::Phi { dst, inputs }); } @@ -344,15 +337,8 @@ pub(super) fn lower_try_stmt( phi_entries.push((dst, inputs)); merged_vars.insert(name.clone(), dst); } - if env.mir_no_phi { - for (dst, inputs) in phi_entries { - for (pred, val) in inputs { - if let Some(pbb) = f.get_block_mut(pred) { - pbb.add_instruction(MirInstruction::Copy { dst, src: val }); - } - } - } - } else if let Some(bb) = f.get_block_mut(exit_bb) { + // フェーズM.2: PHI統一処理(no_phi分岐削除) + if let Some(bb) = f.get_block_mut(exit_bb) { for (dst, inputs) in phi_entries { bb.insert_instruction_after_phis(MirInstruction::Phi { dst, inputs }); }