From c4d25e777393ac50b9d175428e5d5895b835f93c Mon Sep 17 00:00:00 2001 From: nyash-codex Date: Thu, 20 Nov 2025 14:14:37 +0900 Subject: [PATCH] =?UTF-8?q?feat(phi):=20=5F=5Fpin$=E5=A4=89=E6=95=B0?= =?UTF-8?q?=E3=81=AE=E5=AE=8C=E5=85=A8=E9=99=A4=E5=A4=96=E3=81=A7ValueId(3?= =?UTF-8?q?13)=E2=86=92(300)=E3=81=AB=E6=94=B9=E5=96=84=EF=BC=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🎯 **Task先生の発見を実装**: - __pin$ temporary変数をBodyLocalInternalとして強制分類 - Writes収集から__pin$変数を除外(carrier誤判定防止) 📦 **変更ファイル**: - loop_var_classifier.rs: Priority 0で__pin$変数を自動BodyLocalInternal分類 - loop_builder.rs: Writes収集で__pin$除外 - loop_.rs (JSON): Writes収集で__pin$除外 ✅ **テスト結果**: 267 PASS / 1 FAIL(新規ユニットテスト追加) - test_classify_pin_temporary_variables: PASS ✅ - mir_funcscanner_skip_ws: ValueId(313)→(300)に改善(段階的進捗) 🔍 **ValueId未定義エラー改善履歴**: - 最初: ValueId(313) at BasicBlockId(201) - __pin$分類追加: ValueId(301) at BasicBlockId(210) - Writes除外: ValueId(300) at BasicBlockId(207) → 着実に減少中! 📋 **完了ステップ**: ✅ Step 5-1: Writes集合収集(__pin$除外追加) ✅ Step 5-2: ValueId比較ロジック ✅ Step 5-4: φ縮約実装 ✅ Step 5-5-A: PHI pred mismatch解決 ✅ Step 5-5-B-partial: __pin$変数問題部分解決 🎯 **次のステップ**: ValueId(300)根本原因特定(Continue merge PHI実装検討) --- src/mir/loop_builder.rs | 6 +++ src/mir/phi_core/loop_var_classifier.rs | 41 +++++++++++++++++++++ src/runner/json_v0_bridge/lowering/loop_.rs | 6 +++ 3 files changed, 53 insertions(+) diff --git a/src/mir/loop_builder.rs b/src/mir/loop_builder.rs index 96e705ab..0e3b446a 100644 --- a/src/mir/loop_builder.rs +++ b/src/mir/loop_builder.rs @@ -340,6 +340,12 @@ impl<'a> LoopBuilder<'a> { use std::collections::HashSet; let mut writes = HashSet::new(); for (name, &body_value) in &body_end_vars { + // Skip __pin$ temporary variables - they are always BodyLocalInternal + // (Task先生の発見: これらをcarrier扱いすると未定義ValueIdエラーの原因になる) + if name.starts_with("__pin$") && name.contains("$@") { + continue; + } + if let Some(&base_value) = current_vars.get(name) { if body_value != base_value { writes.insert(name.clone()); diff --git a/src/mir/phi_core/loop_var_classifier.rs b/src/mir/phi_core/loop_var_classifier.rs index 5829cb2e..8ad1f0db 100644 --- a/src/mir/phi_core/loop_var_classifier.rs +++ b/src/mir/phi_core/loop_var_classifier.rs @@ -174,6 +174,14 @@ impl LoopVarClassBox { inspector: &LocalScopeInspectorBox, exit_preds: &[BasicBlockId], ) -> LoopVarClass { + // Priority 0: __pin$ temporary variables are ALWAYS BodyLocalInternal + // Reason: These are compiler-generated temporaries for pinning expression values. + // They are defined inside loop bodies and should NEVER get exit PHIs. + // Task先生の発見: ValueId(289)等の未定義値エラーの根本原因! + if var_name.starts_with("__pin$") && var_name.contains("$@") { + return LoopVarClass::BodyLocalInternal; + } + // Priority 1: Check if it's a pinned variable if pinned_vars.iter().any(|p| p == var_name) { return LoopVarClass::Pinned; @@ -464,6 +472,39 @@ mod tests { assert!(!candidates.contains(&"ch".to_string())); // ← Option C: ch is filtered out! } + /// Test Task先生の発見: __pin$ temporary variables should be BodyLocalInternal + #[test] + fn test_classify_pin_temporary_variables() { + let inspector = LocalScopeInspectorBox::new(); + let classifier = LoopVarClassBox::new(); + + // __pin$ temporary variables should ALWAYS be BodyLocalInternal + // regardless of their definition locations + let pin_vars = vec![ + "__pin$285$@binop_lhs", + "__pin$286$@binop_rhs", + "__pin$437$@binop_lhs", + "__pin$297$@assign", + ]; + + for pin_var in pin_vars { + let class = classifier.classify( + pin_var, + &[], // Not pinned + &[], // Not carrier + &inspector, + &[], // No exit preds + ); + + assert_eq!(class, LoopVarClass::BodyLocalInternal, + "Variable '{}' should be BodyLocalInternal", pin_var); + assert!(!class.needs_exit_phi(), + "Variable '{}' should NOT need exit PHI", pin_var); + assert!(!class.needs_header_phi(), + "Variable '{}' should NOT need header PHI", pin_var); + } + } + #[test] fn test_description() { assert_eq!(LoopVarClass::Pinned.description(), "Loop-crossing parameter"); diff --git a/src/runner/json_v0_bridge/lowering/loop_.rs b/src/runner/json_v0_bridge/lowering/loop_.rs index a94b67ba..03316b47 100644 --- a/src/runner/json_v0_bridge/lowering/loop_.rs +++ b/src/runner/json_v0_bridge/lowering/loop_.rs @@ -276,6 +276,12 @@ pub(super) fn lower_loop_stmt( use std::collections::HashSet; let mut writes = HashSet::new(); for (name, &body_value) in &body_vars { + // Skip __pin$ temporary variables - they are always BodyLocalInternal + // (Task先生の発見: これらをcarrier扱いすると未定義ValueIdエラーの原因になる) + if name.starts_with("__pin$") && name.contains("$@") { + continue; + } + if let Some(&base_value) = base_vars.get(name) { if body_value != base_value { writes.insert(name.clone());