Span trace utilities and runner source hint

This commit is contained in:
nyash-codex
2025-11-24 14:17:02 +09:00
parent 3154903121
commit 466e636af6
106 changed files with 4597 additions and 958 deletions

View File

@ -1,6 +1,7 @@
use crate::ast::Span;
use crate::mir::optimizer::MirOptimizer;
use crate::mir::optimizer_stats::OptimizationStats;
use crate::mir::{BarrierOp, MirModule, TypeOpKind, ValueId, WeakRefOp};
use crate::mir::{BarrierOp, MirModule, SpannedInstruction, TypeOpKind, ValueId, WeakRefOp};
fn idemp_enabled() -> bool {
std::env::var("NYASH_MIR_DEV_IDEMP").ok().as_deref() == Some("1")
@ -433,9 +434,10 @@ pub fn normalize_ref_field_access(
None => continue,
};
for (_bb, block) in &mut function.blocks {
let mut out: Vec<I> = Vec::with_capacity(block.instructions.len() + 2);
let old = std::mem::take(&mut block.instructions);
for inst in old.into_iter() {
let old_spanned: Vec<SpannedInstruction> = block.drain_spanned_instructions();
let mut out: Vec<I> = Vec::with_capacity(old_spanned.len() + 2);
let mut out_spans: Vec<Span> = Vec::with_capacity(old_spanned.len() + 2);
for SpannedInstruction { inst, span } in old_spanned.into_iter() {
match inst {
I::RefGet {
dst,
@ -448,6 +450,7 @@ pub fn normalize_ref_field_access(
dst: new_id,
value: crate::mir::ConstValue::String(field),
});
out_spans.push(span);
out.push(I::BoxCall {
dst: Some(dst),
box_val: reference,
@ -456,6 +459,7 @@ pub fn normalize_ref_field_access(
args: vec![new_id],
effects: crate::mir::EffectMask::READ,
});
out_spans.push(span);
stats.intrinsic_optimizations += 1;
}
I::RefSet {
@ -469,10 +473,12 @@ pub fn normalize_ref_field_access(
dst: new_id,
value: crate::mir::ConstValue::String(field),
});
out_spans.push(span);
out.push(I::Barrier {
op: BarrierOp::Write,
ptr: reference,
});
out_spans.push(span);
out.push(I::BoxCall {
dst: None,
box_val: reference,
@ -481,14 +487,20 @@ pub fn normalize_ref_field_access(
args: vec![new_id, value],
effects: crate::mir::EffectMask::WRITE,
});
out_spans.push(span);
stats.intrinsic_optimizations += 1;
}
other => out.push(other),
other => {
out.push(other);
out_spans.push(span);
}
}
}
block.instructions = out;
block.instruction_spans = out_spans;
if let Some(term) = block.terminator.take() {
let term_span = block.terminator_span.take().unwrap_or_else(Span::unknown);
block.terminator = Some(match term {
I::RefGet {
dst,
@ -501,6 +513,7 @@ pub fn normalize_ref_field_access(
dst: new_id,
value: crate::mir::ConstValue::String(field),
});
block.instruction_spans.push(term_span);
I::BoxCall {
dst: Some(dst),
box_val: reference,
@ -521,10 +534,12 @@ pub fn normalize_ref_field_access(
dst: new_id,
value: crate::mir::ConstValue::String(field),
});
block.instruction_spans.push(term_span);
block.instructions.push(I::Barrier {
op: BarrierOp::Write,
ptr: reference,
});
block.instruction_spans.push(term_span);
I::BoxCall {
dst: None,
box_val: reference,
@ -536,6 +551,9 @@ pub fn normalize_ref_field_access(
}
other => other,
});
if block.terminator_span.is_none() {
block.terminator_span = Some(term_span);
}
}
}
if idemp_enabled() {