2025-09-17 05:56:33 +09:00
|
|
|
|
use crate::mir::optimizer::MirOptimizer;
|
2025-09-17 07:43:07 +09:00
|
|
|
|
use crate::mir::optimizer_stats::OptimizationStats;
|
2025-09-17 11:45:57 +09:00
|
|
|
|
use crate::mir::{BasicBlockId, MirInstruction, MirModule, ValueId};
|
2025-09-17 05:56:33 +09:00
|
|
|
|
|
|
|
|
|
|
/// Diagnostic: detect unlowered is/as/isType/asType after Builder
|
2025-09-17 07:43:07 +09:00
|
|
|
|
pub fn diagnose_unlowered_type_ops(
|
|
|
|
|
|
opt: &mut MirOptimizer,
|
|
|
|
|
|
module: &MirModule,
|
|
|
|
|
|
) -> OptimizationStats {
|
2025-09-17 05:56:33 +09:00
|
|
|
|
let mut stats = OptimizationStats::new();
|
|
|
|
|
|
let diag_on = opt.debug_enabled() || crate::config::env::opt_diag();
|
|
|
|
|
|
for (fname, function) in &module.functions {
|
2025-09-17 07:43:07 +09:00
|
|
|
|
let mut def_map: std::collections::HashMap<ValueId, (BasicBlockId, usize)> =
|
|
|
|
|
|
std::collections::HashMap::new();
|
2025-09-17 05:56:33 +09:00
|
|
|
|
for (bb_id, block) in &function.blocks {
|
|
|
|
|
|
for (i, inst) in block.instructions.iter().enumerate() {
|
2025-09-17 07:43:07 +09:00
|
|
|
|
if let Some(dst) = inst.dst_value() {
|
|
|
|
|
|
def_map.insert(dst, (*bb_id, i));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if let Some(term) = &block.terminator {
|
|
|
|
|
|
if let Some(dst) = term.dst_value() {
|
|
|
|
|
|
def_map.insert(dst, (*bb_id, usize::MAX));
|
|
|
|
|
|
}
|
2025-09-17 05:56:33 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
let mut count = 0usize;
|
|
|
|
|
|
for (_bb, block) in &function.blocks {
|
|
|
|
|
|
for inst in &block.instructions {
|
|
|
|
|
|
match inst {
|
2025-09-17 07:43:07 +09:00
|
|
|
|
MirInstruction::BoxCall { method, .. }
|
|
|
|
|
|
if method == "is"
|
|
|
|
|
|
|| method == "as"
|
|
|
|
|
|
|| method == "isType"
|
|
|
|
|
|
|| method == "asType" =>
|
|
|
|
|
|
{
|
|
|
|
|
|
count += 1;
|
|
|
|
|
|
}
|
2025-09-17 05:56:33 +09:00
|
|
|
|
MirInstruction::Call { func, .. } => {
|
|
|
|
|
|
if let Some((bb, idx)) = def_map.get(func).copied() {
|
|
|
|
|
|
if let Some(b) = function.blocks.get(&bb) {
|
|
|
|
|
|
if idx < b.instructions.len() {
|
2025-09-17 07:43:07 +09:00
|
|
|
|
if let MirInstruction::Const {
|
2025-11-21 06:25:17 +09:00
|
|
|
|
value: crate::mir::ConstValue::String(s),
|
2025-09-17 07:43:07 +09:00
|
|
|
|
..
|
|
|
|
|
|
} = &b.instructions[idx]
|
|
|
|
|
|
{
|
|
|
|
|
|
if s == "isType" || s == "asType" {
|
|
|
|
|
|
count += 1;
|
|
|
|
|
|
}
|
2025-09-17 05:56:33 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
_ => {}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if count > 0 {
|
|
|
|
|
|
stats.diagnostics_reported += count;
|
|
|
|
|
|
if diag_on {
|
2025-09-17 07:43:07 +09:00
|
|
|
|
eprintln!(
|
|
|
|
|
|
"[OPT][DIAG] Function '{}' has {} unlowered type-op calls",
|
|
|
|
|
|
fname, count
|
|
|
|
|
|
);
|
2025-09-17 05:56:33 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
stats
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Diagnostic: detect legacy instructions that should be unified
|
|
|
|
|
|
/// Legacy set: TypeCheck/Cast/WeakNew/WeakLoad/BarrierRead/BarrierWrite/ArrayGet/ArraySet/RefGet/RefSet/PluginInvoke
|
2025-09-17 07:43:07 +09:00
|
|
|
|
pub fn diagnose_legacy_instructions(
|
|
|
|
|
|
opt: &mut MirOptimizer,
|
|
|
|
|
|
module: &MirModule,
|
|
|
|
|
|
) -> OptimizationStats {
|
2025-09-17 05:56:33 +09:00
|
|
|
|
let mut stats = OptimizationStats::new();
|
|
|
|
|
|
let diag_on = opt.debug_enabled()
|
|
|
|
|
|
|| crate::config::env::opt_diag()
|
|
|
|
|
|
|| crate::config::env::opt_diag_forbid_legacy();
|
|
|
|
|
|
for (fname, function) in &module.functions {
|
|
|
|
|
|
let mut count = 0usize;
|
|
|
|
|
|
for (_bb, block) in &function.blocks {
|
|
|
|
|
|
for inst in &block.instructions {
|
|
|
|
|
|
match inst {
|
|
|
|
|
|
MirInstruction::TypeCheck { .. }
|
|
|
|
|
|
| MirInstruction::Cast { .. }
|
|
|
|
|
|
| MirInstruction::WeakNew { .. }
|
|
|
|
|
|
| MirInstruction::WeakLoad { .. }
|
|
|
|
|
|
| MirInstruction::BarrierRead { .. }
|
|
|
|
|
|
| MirInstruction::BarrierWrite { .. }
|
|
|
|
|
|
| MirInstruction::ArrayGet { .. }
|
|
|
|
|
|
| MirInstruction::ArraySet { .. }
|
|
|
|
|
|
| MirInstruction::RefGet { .. }
|
|
|
|
|
|
| MirInstruction::RefSet { .. }
|
2025-09-17 07:43:07 +09:00
|
|
|
|
| MirInstruction::PluginInvoke { .. } => {
|
|
|
|
|
|
count += 1;
|
|
|
|
|
|
}
|
2025-09-17 05:56:33 +09:00
|
|
|
|
_ => {}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if let Some(term) = &block.terminator {
|
|
|
|
|
|
match term {
|
|
|
|
|
|
MirInstruction::TypeCheck { .. }
|
|
|
|
|
|
| MirInstruction::Cast { .. }
|
|
|
|
|
|
| MirInstruction::WeakNew { .. }
|
|
|
|
|
|
| MirInstruction::WeakLoad { .. }
|
|
|
|
|
|
| MirInstruction::BarrierRead { .. }
|
|
|
|
|
|
| MirInstruction::BarrierWrite { .. }
|
|
|
|
|
|
| MirInstruction::ArrayGet { .. }
|
|
|
|
|
|
| MirInstruction::ArraySet { .. }
|
|
|
|
|
|
| MirInstruction::RefGet { .. }
|
|
|
|
|
|
| MirInstruction::RefSet { .. }
|
2025-09-17 07:43:07 +09:00
|
|
|
|
| MirInstruction::PluginInvoke { .. } => {
|
|
|
|
|
|
count += 1;
|
|
|
|
|
|
}
|
2025-09-17 05:56:33 +09:00
|
|
|
|
_ => {}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if count > 0 {
|
|
|
|
|
|
stats.diagnostics_reported += count;
|
|
|
|
|
|
if diag_on {
|
|
|
|
|
|
eprintln!(
|
|
|
|
|
|
"[OPT][DIAG] Function '{}' has {} legacy MIR ops: unify to Core‑13 (TypeOp/WeakRef/Barrier/BoxCall)",
|
|
|
|
|
|
fname, count
|
|
|
|
|
|
);
|
|
|
|
|
|
if crate::config::env::opt_diag_forbid_legacy() {
|
2025-09-17 07:43:07 +09:00
|
|
|
|
panic!(
|
|
|
|
|
|
"NYASH_OPT_DIAG_FORBID_LEGACY=1: legacy MIR ops detected in '{}': {}",
|
|
|
|
|
|
fname, count
|
|
|
|
|
|
);
|
2025-09-17 05:56:33 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
stats
|
|
|
|
|
|
}
|