chore: Phase 25.1 完了 - LoopForm v2/Stage1 CLI/環境変数削減 + Phase 26-D からの変更
Phase 25.1 完了成果: - ✅ LoopForm v2 テスト・ドキュメント・コメント完備 - 4ケース(A/B/C/D)完全テストカバレッジ - 最小再現ケース作成(SSAバグ調査用) - SSOT文書作成(loopform_ssot.md) - 全ソースに [LoopForm] コメントタグ追加 - ✅ Stage-1 CLI デバッグ環境構築 - stage1_cli.hako 実装 - stage1_bridge.rs ブリッジ実装 - デバッグツール作成(stage1_debug.sh/stage1_minimal.sh) - アーキテクチャ改善提案文書 - ✅ 環境変数削減計画策定 - 25変数の完全調査・分類 - 6段階削減ロードマップ(25→5、80%削減) - 即時削除可能変数特定(NYASH_CONFIG/NYASH_DEBUG) Phase 26-D からの累積変更: - PHI実装改善(ExitPhiBuilder/HeaderPhiBuilder等) - MIRビルダーリファクタリング - 型伝播・最適化パス改善 - その他約300ファイルの累積変更 🎯 技術的成果: - SSAバグ根本原因特定(条件分岐内loop変数変更) - Region+next_iパターン適用完了(UsingCollectorBox等) - LoopFormパターン文書化・テスト化完了 - セルフホスティング基盤強化 Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: ChatGPT <noreply@openai.com> Co-Authored-By: Task Assistant <task@anthropic.com>
This commit is contained in:
@ -7,14 +7,13 @@
|
||||
use super::{MirFunction, MirModule};
|
||||
use crate::debug::log as dlog;
|
||||
use crate::mir::verification_types::VerificationError;
|
||||
mod cfg;
|
||||
mod dom;
|
||||
mod awaits;
|
||||
mod barrier;
|
||||
mod cfg;
|
||||
mod dom;
|
||||
mod legacy;
|
||||
mod utils;
|
||||
mod ssa;
|
||||
|
||||
mod utils;
|
||||
|
||||
/// MIR verifier for SSA form and semantic correctness
|
||||
pub struct MirVerifier {
|
||||
@ -43,10 +42,7 @@ impl MirVerifier {
|
||||
// 併せて、同じトグルで「任意の関数」に対する UndefinedValue も
|
||||
// 簡易ログとして出力し、どの関数で支配関係が崩れているかを
|
||||
// 追いやすくしている(箱理論の観測レイヤー強化)。
|
||||
if std::env::var("NYASH_BREAKFINDER_SSA_TRACE")
|
||||
.ok()
|
||||
.as_deref() == Some("1")
|
||||
{
|
||||
if std::env::var("NYASH_BREAKFINDER_SSA_TRACE").ok().as_deref() == Some("1") {
|
||||
// 1) BreakFinderBox / LoopSSA 向けの詳細ログ
|
||||
if function.signature.name.starts_with("BreakFinderBox.")
|
||||
|| function.signature.name.starts_with("LoopSSA.")
|
||||
@ -97,8 +93,7 @@ impl MirVerifier {
|
||||
instruction_index
|
||||
);
|
||||
if let Some(bb) = function.blocks.get(block) {
|
||||
let inst_opt =
|
||||
bb.all_instructions().nth(*instruction_index);
|
||||
let inst_opt = bb.all_instructions().nth(*instruction_index);
|
||||
if let Some(inst) = inst_opt {
|
||||
eprintln!("[mir-ssa-debug-inst] inst={:?}", inst);
|
||||
}
|
||||
@ -316,26 +311,31 @@ impl MirVerifier {
|
||||
}
|
||||
|
||||
// Merge block itself must not contain a Copy to the merged value
|
||||
let has_self_copy_in_merge = merge_bb
|
||||
.instructions
|
||||
.iter()
|
||||
.any(|inst| matches!(inst, super::MirInstruction::Copy { dst, .. } if *dst == u));
|
||||
let has_self_copy_in_merge = merge_bb.instructions.iter().any(
|
||||
|inst| matches!(inst, super::MirInstruction::Copy { dst, .. } if *dst == u),
|
||||
);
|
||||
if has_self_copy_in_merge {
|
||||
errors.push(VerificationError::EdgeCopyStrictViolation {
|
||||
block: *merge_bid,
|
||||
value: u,
|
||||
pred_block: None,
|
||||
reason: "merge block contains Copy to merged value; use predecessor copies only".to_string(),
|
||||
reason:
|
||||
"merge block contains Copy to merged value; use predecessor copies only"
|
||||
.to_string(),
|
||||
});
|
||||
}
|
||||
|
||||
// Each predecessor must provide a Copy into the merged destination
|
||||
for pred in &p {
|
||||
let Some(pbb) = function.blocks.get(pred) else { continue; };
|
||||
let has_copy = pbb.instructions.iter().any(|inst| matches!(
|
||||
inst,
|
||||
super::MirInstruction::Copy { dst, .. } if *dst == u
|
||||
));
|
||||
let Some(pbb) = function.blocks.get(pred) else {
|
||||
continue;
|
||||
};
|
||||
let has_copy = pbb.instructions.iter().any(|inst| {
|
||||
matches!(
|
||||
inst,
|
||||
super::MirInstruction::Copy { dst, .. } if *dst == u
|
||||
)
|
||||
});
|
||||
if !has_copy {
|
||||
errors.push(VerificationError::MergeUsesPredecessorValue {
|
||||
value: u,
|
||||
@ -347,12 +347,19 @@ impl MirVerifier {
|
||||
}
|
||||
}
|
||||
|
||||
if errors.is_empty() { Ok(()) } else { Err(errors) }
|
||||
if errors.is_empty() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(errors)
|
||||
}
|
||||
}
|
||||
|
||||
/// Verify that any block ending with Return contains no side-effecting instructions before it.
|
||||
/// Allowed before Return: Const, Copy, Phi, Nop only. Others are considered side-effecting for this policy.
|
||||
fn verify_ret_block_purity(&self, function: &MirFunction) -> Result<(), Vec<VerificationError>> {
|
||||
fn verify_ret_block_purity(
|
||||
&self,
|
||||
function: &MirFunction,
|
||||
) -> Result<(), Vec<VerificationError>> {
|
||||
use super::MirInstruction as I;
|
||||
let mut errors = Vec::new();
|
||||
for (bid, bb) in &function.blocks {
|
||||
@ -373,7 +380,11 @@ impl MirVerifier {
|
||||
}
|
||||
}
|
||||
}
|
||||
if errors.is_empty() { Ok(()) } else { Err(errors) }
|
||||
if errors.is_empty() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(errors)
|
||||
}
|
||||
}
|
||||
|
||||
/// Reject legacy instructions that should be rewritten to Core-15 equivalents
|
||||
@ -436,7 +447,6 @@ impl MirVerifier {
|
||||
pub fn clear_errors(&mut self) {
|
||||
self.errors.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl Default for MirVerifier {
|
||||
@ -445,6 +455,5 @@ impl Default for MirVerifier {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {}
|
||||
|
||||
Reference in New Issue
Block a user