2025-09-17 05:56:33 +09:00
|
|
|
use crate::mir::optimizer::MirOptimizer;
|
|
|
|
|
use crate::mir::optimizer_stats::OptimizationStats;
|
2025-09-17 11:45:57 +09:00
|
|
|
use crate::mir::{BarrierOp, MirModule, TypeOpKind, ValueId, WeakRefOp};
|
2025-09-17 05:56:33 +09:00
|
|
|
|
2025-11-13 16:40:58 +09:00
|
|
|
fn idemp_enabled() -> bool {
|
|
|
|
|
std::env::var("NYASH_MIR_DEV_IDEMP").ok().as_deref() == Some("1")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn idemp_key(pass: &str, func_name: &str) -> String {
|
|
|
|
|
format!("{}:{}", pass, func_name)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn idemp_already_done(module: &crate::mir::MirModule, key: &str) -> bool {
|
|
|
|
|
module.metadata.dev_processed_markers.contains(key)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn idemp_mark(module: &mut crate::mir::MirModule, key: String) {
|
|
|
|
|
module.metadata.dev_processed_markers.insert(key);
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-17 05:56:33 +09:00
|
|
|
pub fn force_plugin_invoke(_opt: &mut MirOptimizer, module: &mut MirModule) -> OptimizationStats {
|
|
|
|
|
use crate::mir::MirInstruction as I;
|
|
|
|
|
let mut stats = OptimizationStats::new();
|
2025-11-13 16:40:58 +09:00
|
|
|
let pass_name = "normalize.force_plugin_invoke";
|
|
|
|
|
let func_names: Vec<String> = module.functions.keys().cloned().collect();
|
|
|
|
|
for fname in func_names {
|
|
|
|
|
if idemp_enabled() {
|
|
|
|
|
let key = idemp_key(pass_name, &fname);
|
|
|
|
|
if idemp_already_done(module, &key) { continue; }
|
|
|
|
|
}
|
|
|
|
|
let function = match module.functions.get_mut(&fname) { Some(f) => f, None => continue };
|
2025-09-17 05:56:33 +09:00
|
|
|
for (_bb, block) in &mut function.blocks {
|
|
|
|
|
for inst in &mut block.instructions {
|
2025-09-17 07:43:07 +09:00
|
|
|
if let I::BoxCall {
|
|
|
|
|
dst,
|
|
|
|
|
box_val,
|
|
|
|
|
method,
|
|
|
|
|
args,
|
|
|
|
|
effects,
|
|
|
|
|
..
|
|
|
|
|
} = inst.clone()
|
|
|
|
|
{
|
|
|
|
|
*inst = I::PluginInvoke {
|
|
|
|
|
dst,
|
|
|
|
|
box_val,
|
|
|
|
|
method,
|
|
|
|
|
args,
|
|
|
|
|
effects,
|
|
|
|
|
};
|
2025-09-17 05:56:33 +09:00
|
|
|
stats.intrinsic_optimizations += 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-11-13 16:40:58 +09:00
|
|
|
if idemp_enabled() { let key = idemp_key(pass_name, &fname); idemp_mark(module, key); }
|
2025-09-17 05:56:33 +09:00
|
|
|
}
|
|
|
|
|
stats
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-17 07:43:07 +09:00
|
|
|
pub fn normalize_python_helper_calls(
|
|
|
|
|
_opt: &mut MirOptimizer,
|
|
|
|
|
module: &mut MirModule,
|
|
|
|
|
) -> OptimizationStats {
|
2025-09-17 05:56:33 +09:00
|
|
|
use crate::mir::MirInstruction as I;
|
|
|
|
|
let mut stats = OptimizationStats::new();
|
2025-11-13 16:40:58 +09:00
|
|
|
let pass_name = "normalize.python_helper_calls";
|
|
|
|
|
let func_names: Vec<String> = module.functions.keys().cloned().collect();
|
|
|
|
|
for fname in func_names {
|
|
|
|
|
if idemp_enabled() {
|
|
|
|
|
let key = idemp_key(pass_name, &fname);
|
|
|
|
|
if idemp_already_done(module, &key) { continue; }
|
|
|
|
|
}
|
|
|
|
|
let function = match module.functions.get_mut(&fname) { Some(f) => f, None => continue };
|
2025-09-17 05:56:33 +09:00
|
|
|
for (_bb, block) in &mut function.blocks {
|
|
|
|
|
for inst in &mut block.instructions {
|
2025-09-17 07:43:07 +09:00
|
|
|
if let I::PluginInvoke {
|
|
|
|
|
box_val,
|
|
|
|
|
method,
|
|
|
|
|
args,
|
|
|
|
|
..
|
|
|
|
|
} = inst
|
|
|
|
|
{
|
2025-09-17 05:56:33 +09:00
|
|
|
if method == "getattr" && args.len() >= 2 {
|
|
|
|
|
let new_recv = args[0];
|
|
|
|
|
args.remove(0);
|
|
|
|
|
*box_val = new_recv;
|
|
|
|
|
stats.intrinsic_optimizations += 1;
|
|
|
|
|
} else if method == "call" && !args.is_empty() {
|
|
|
|
|
let new_recv = args[0];
|
|
|
|
|
args.remove(0);
|
|
|
|
|
*box_val = new_recv;
|
|
|
|
|
stats.intrinsic_optimizations += 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-11-13 16:40:58 +09:00
|
|
|
if idemp_enabled() { let key = idemp_key(pass_name, &fname); idemp_mark(module, key); }
|
2025-09-17 05:56:33 +09:00
|
|
|
}
|
|
|
|
|
stats
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-17 07:43:07 +09:00
|
|
|
pub fn normalize_legacy_instructions(
|
|
|
|
|
_opt: &mut MirOptimizer,
|
|
|
|
|
module: &mut MirModule,
|
|
|
|
|
) -> OptimizationStats {
|
2025-09-17 05:56:33 +09:00
|
|
|
use crate::mir::MirInstruction as I;
|
|
|
|
|
let mut stats = OptimizationStats::new();
|
|
|
|
|
let rw_dbg = crate::config::env::rewrite_debug();
|
|
|
|
|
let rw_sp = crate::config::env::rewrite_safepoint();
|
|
|
|
|
let rw_future = crate::config::env::rewrite_future();
|
|
|
|
|
let core13 = crate::config::env::mir_core13();
|
|
|
|
|
let mut array_to_boxcall = crate::config::env::mir_array_boxcall();
|
2025-09-17 07:43:07 +09:00
|
|
|
if core13 {
|
|
|
|
|
array_to_boxcall = true;
|
|
|
|
|
}
|
2025-11-13 16:40:58 +09:00
|
|
|
let pass_name = "normalize.legacy_instructions";
|
|
|
|
|
let func_names: Vec<String> = module.functions.keys().cloned().collect();
|
|
|
|
|
for fname in func_names {
|
|
|
|
|
if idemp_enabled() {
|
|
|
|
|
let key = idemp_key(pass_name, &fname);
|
|
|
|
|
if idemp_already_done(module, &key) { continue; }
|
|
|
|
|
}
|
|
|
|
|
let function = match module.functions.get_mut(&fname) { Some(f) => f, None => continue };
|
2025-09-17 05:56:33 +09:00
|
|
|
for (_bb, block) in &mut function.blocks {
|
|
|
|
|
for inst in &mut block.instructions {
|
|
|
|
|
match inst {
|
|
|
|
|
I::WeakNew { dst, box_val } => {
|
2025-09-17 07:43:07 +09:00
|
|
|
let d = *dst;
|
|
|
|
|
let v = *box_val;
|
|
|
|
|
*inst = I::WeakRef {
|
|
|
|
|
dst: d,
|
|
|
|
|
op: WeakRefOp::New,
|
|
|
|
|
value: v,
|
|
|
|
|
};
|
2025-09-17 05:56:33 +09:00
|
|
|
stats.intrinsic_optimizations += 1;
|
|
|
|
|
}
|
|
|
|
|
I::WeakLoad { dst, weak_ref } => {
|
2025-09-17 07:43:07 +09:00
|
|
|
let d = *dst;
|
|
|
|
|
let v = *weak_ref;
|
|
|
|
|
*inst = I::WeakRef {
|
|
|
|
|
dst: d,
|
|
|
|
|
op: WeakRefOp::Load,
|
|
|
|
|
value: v,
|
|
|
|
|
};
|
2025-09-17 05:56:33 +09:00
|
|
|
stats.intrinsic_optimizations += 1;
|
|
|
|
|
}
|
|
|
|
|
I::BarrierRead { ptr } => {
|
2025-09-17 07:43:07 +09:00
|
|
|
let p = *ptr;
|
|
|
|
|
*inst = I::Barrier {
|
|
|
|
|
op: BarrierOp::Read,
|
|
|
|
|
ptr: p,
|
|
|
|
|
};
|
2025-09-17 05:56:33 +09:00
|
|
|
stats.intrinsic_optimizations += 1;
|
|
|
|
|
}
|
|
|
|
|
I::BarrierWrite { ptr } => {
|
2025-09-17 07:43:07 +09:00
|
|
|
let p = *ptr;
|
|
|
|
|
*inst = I::Barrier {
|
|
|
|
|
op: BarrierOp::Write,
|
|
|
|
|
ptr: p,
|
|
|
|
|
};
|
2025-09-17 05:56:33 +09:00
|
|
|
stats.intrinsic_optimizations += 1;
|
|
|
|
|
}
|
|
|
|
|
I::Print { value, .. } => {
|
|
|
|
|
let v = *value;
|
2025-09-17 07:43:07 +09:00
|
|
|
*inst = I::ExternCall {
|
|
|
|
|
dst: None,
|
|
|
|
|
iface_name: "env.console".to_string(),
|
|
|
|
|
method_name: "log".to_string(),
|
|
|
|
|
args: vec![v],
|
|
|
|
|
effects: crate::mir::EffectMask::PURE.add(crate::mir::Effect::Io),
|
|
|
|
|
};
|
2025-09-17 05:56:33 +09:00
|
|
|
stats.intrinsic_optimizations += 1;
|
|
|
|
|
}
|
|
|
|
|
I::ArrayGet { dst, array, index } if array_to_boxcall => {
|
2025-09-17 07:43:07 +09:00
|
|
|
let d = *dst;
|
|
|
|
|
let a = *array;
|
|
|
|
|
let i = *index;
|
|
|
|
|
let mid =
|
|
|
|
|
crate::mir::slot_registry::resolve_slot_by_type_name("ArrayBox", "get");
|
|
|
|
|
*inst = I::BoxCall {
|
|
|
|
|
dst: Some(d),
|
|
|
|
|
box_val: a,
|
|
|
|
|
method: "get".to_string(),
|
|
|
|
|
method_id: mid,
|
|
|
|
|
args: vec![i],
|
|
|
|
|
effects: crate::mir::EffectMask::READ,
|
|
|
|
|
};
|
2025-09-17 05:56:33 +09:00
|
|
|
stats.intrinsic_optimizations += 1;
|
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
I::ArraySet {
|
|
|
|
|
array,
|
|
|
|
|
index,
|
|
|
|
|
value,
|
|
|
|
|
} if array_to_boxcall => {
|
|
|
|
|
let a = *array;
|
|
|
|
|
let i = *index;
|
|
|
|
|
let v = *value;
|
|
|
|
|
let mid =
|
|
|
|
|
crate::mir::slot_registry::resolve_slot_by_type_name("ArrayBox", "set");
|
|
|
|
|
*inst = I::BoxCall {
|
|
|
|
|
dst: None,
|
|
|
|
|
box_val: a,
|
|
|
|
|
method: "set".to_string(),
|
|
|
|
|
method_id: mid,
|
|
|
|
|
args: vec![i, v],
|
|
|
|
|
effects: crate::mir::EffectMask::WRITE,
|
|
|
|
|
};
|
2025-09-17 05:56:33 +09:00
|
|
|
stats.intrinsic_optimizations += 1;
|
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
I::PluginInvoke {
|
|
|
|
|
dst,
|
|
|
|
|
box_val,
|
|
|
|
|
method,
|
|
|
|
|
args,
|
|
|
|
|
effects,
|
|
|
|
|
} => {
|
|
|
|
|
let d = *dst;
|
|
|
|
|
let recv = *box_val;
|
|
|
|
|
let m = method.clone();
|
|
|
|
|
let as_ = args.clone();
|
|
|
|
|
let eff = *effects;
|
|
|
|
|
*inst = I::BoxCall {
|
|
|
|
|
dst: d,
|
|
|
|
|
box_val: recv,
|
|
|
|
|
method: m,
|
|
|
|
|
method_id: None,
|
|
|
|
|
args: as_,
|
|
|
|
|
effects: eff,
|
|
|
|
|
};
|
2025-09-17 05:56:33 +09:00
|
|
|
stats.intrinsic_optimizations += 1;
|
|
|
|
|
}
|
|
|
|
|
I::Debug { .. } if !rw_dbg => {
|
|
|
|
|
*inst = I::Nop;
|
|
|
|
|
}
|
|
|
|
|
I::Safepoint if !rw_sp => {
|
|
|
|
|
*inst = I::Nop;
|
|
|
|
|
}
|
|
|
|
|
I::FutureNew { dst, value } if rw_future => {
|
2025-09-17 07:43:07 +09:00
|
|
|
let d = *dst;
|
|
|
|
|
let v = *value;
|
|
|
|
|
*inst = I::ExternCall {
|
|
|
|
|
dst: Some(d),
|
|
|
|
|
iface_name: "env.future".to_string(),
|
|
|
|
|
method_name: "new".to_string(),
|
|
|
|
|
args: vec![v],
|
|
|
|
|
effects: crate::mir::EffectMask::PURE.add(crate::mir::Effect::Io),
|
|
|
|
|
};
|
2025-09-17 05:56:33 +09:00
|
|
|
}
|
|
|
|
|
I::FutureSet { future, value } if rw_future => {
|
2025-09-17 07:43:07 +09:00
|
|
|
let f = *future;
|
|
|
|
|
let v = *value;
|
|
|
|
|
*inst = I::ExternCall {
|
|
|
|
|
dst: None,
|
|
|
|
|
iface_name: "env.future".to_string(),
|
|
|
|
|
method_name: "set".to_string(),
|
|
|
|
|
args: vec![f, v],
|
|
|
|
|
effects: crate::mir::EffectMask::PURE.add(crate::mir::Effect::Io),
|
|
|
|
|
};
|
2025-09-17 05:56:33 +09:00
|
|
|
}
|
|
|
|
|
I::Await { dst, future } if rw_future => {
|
2025-09-17 07:43:07 +09:00
|
|
|
let d = *dst;
|
|
|
|
|
let f = *future;
|
|
|
|
|
*inst = I::ExternCall {
|
|
|
|
|
dst: Some(d),
|
|
|
|
|
iface_name: "env.future".to_string(),
|
|
|
|
|
method_name: "await".to_string(),
|
|
|
|
|
args: vec![f],
|
|
|
|
|
effects: crate::mir::EffectMask::PURE.add(crate::mir::Effect::Io),
|
|
|
|
|
};
|
2025-09-17 05:56:33 +09:00
|
|
|
}
|
|
|
|
|
_ => {}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// terminator rewrite (subset migrated as needed)
|
|
|
|
|
if let Some(term) = &mut block.terminator {
|
|
|
|
|
match term {
|
2025-09-17 07:43:07 +09:00
|
|
|
I::TypeCheck {
|
|
|
|
|
dst,
|
|
|
|
|
value,
|
|
|
|
|
expected_type,
|
|
|
|
|
} => {
|
2025-09-22 21:52:39 +09:00
|
|
|
let ty = crate::mir::MirType::Box(expected_type.clone());
|
2025-09-17 07:43:07 +09:00
|
|
|
*term = I::TypeOp {
|
|
|
|
|
dst: *dst,
|
|
|
|
|
op: TypeOpKind::Check,
|
|
|
|
|
value: *value,
|
|
|
|
|
ty,
|
|
|
|
|
};
|
2025-09-17 05:56:33 +09:00
|
|
|
stats.intrinsic_optimizations += 1;
|
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
I::Cast {
|
|
|
|
|
dst,
|
|
|
|
|
value,
|
|
|
|
|
target_type,
|
|
|
|
|
} => {
|
2025-09-17 05:56:33 +09:00
|
|
|
let ty = target_type.clone();
|
2025-09-17 07:43:07 +09:00
|
|
|
*term = I::TypeOp {
|
|
|
|
|
dst: *dst,
|
|
|
|
|
op: TypeOpKind::Cast,
|
|
|
|
|
value: *value,
|
|
|
|
|
ty,
|
|
|
|
|
};
|
2025-09-17 05:56:33 +09:00
|
|
|
stats.intrinsic_optimizations += 1;
|
|
|
|
|
}
|
|
|
|
|
I::WeakNew { dst, box_val } => {
|
2025-09-17 07:43:07 +09:00
|
|
|
let d = *dst;
|
|
|
|
|
let v = *box_val;
|
|
|
|
|
*term = I::WeakRef {
|
|
|
|
|
dst: d,
|
|
|
|
|
op: WeakRefOp::New,
|
|
|
|
|
value: v,
|
|
|
|
|
};
|
2025-09-17 05:56:33 +09:00
|
|
|
stats.intrinsic_optimizations += 1;
|
|
|
|
|
}
|
|
|
|
|
I::WeakLoad { dst, weak_ref } => {
|
2025-09-17 07:43:07 +09:00
|
|
|
let d = *dst;
|
|
|
|
|
let v = *weak_ref;
|
|
|
|
|
*term = I::WeakRef {
|
|
|
|
|
dst: d,
|
|
|
|
|
op: WeakRefOp::Load,
|
|
|
|
|
value: v,
|
|
|
|
|
};
|
2025-09-17 05:56:33 +09:00
|
|
|
stats.intrinsic_optimizations += 1;
|
|
|
|
|
}
|
|
|
|
|
I::BarrierRead { ptr } => {
|
2025-09-17 07:43:07 +09:00
|
|
|
let p = *ptr;
|
|
|
|
|
*term = I::Barrier {
|
|
|
|
|
op: BarrierOp::Read,
|
|
|
|
|
ptr: p,
|
|
|
|
|
};
|
2025-09-17 05:56:33 +09:00
|
|
|
stats.intrinsic_optimizations += 1;
|
|
|
|
|
}
|
|
|
|
|
I::BarrierWrite { ptr } => {
|
2025-09-17 07:43:07 +09:00
|
|
|
let p = *ptr;
|
|
|
|
|
*term = I::Barrier {
|
|
|
|
|
op: BarrierOp::Write,
|
|
|
|
|
ptr: p,
|
|
|
|
|
};
|
2025-09-17 05:56:33 +09:00
|
|
|
stats.intrinsic_optimizations += 1;
|
|
|
|
|
}
|
|
|
|
|
I::Print { value, .. } => {
|
2025-09-17 07:43:07 +09:00
|
|
|
let v = *value;
|
|
|
|
|
*term = I::ExternCall {
|
|
|
|
|
dst: None,
|
|
|
|
|
iface_name: "env.console".to_string(),
|
|
|
|
|
method_name: "log".to_string(),
|
|
|
|
|
args: vec![v],
|
|
|
|
|
effects: crate::mir::EffectMask::PURE,
|
|
|
|
|
};
|
2025-09-17 05:56:33 +09:00
|
|
|
stats.intrinsic_optimizations += 1;
|
|
|
|
|
}
|
|
|
|
|
I::ArrayGet { dst, array, index } if array_to_boxcall => {
|
2025-09-17 07:43:07 +09:00
|
|
|
let d = *dst;
|
|
|
|
|
let a = *array;
|
|
|
|
|
let i = *index;
|
|
|
|
|
*term = I::BoxCall {
|
|
|
|
|
dst: Some(d),
|
|
|
|
|
box_val: a,
|
|
|
|
|
method: "get".to_string(),
|
|
|
|
|
method_id: None,
|
|
|
|
|
args: vec![i],
|
|
|
|
|
effects: crate::mir::EffectMask::READ,
|
|
|
|
|
};
|
2025-09-17 05:56:33 +09:00
|
|
|
stats.intrinsic_optimizations += 1;
|
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
I::ArraySet {
|
|
|
|
|
array,
|
|
|
|
|
index,
|
|
|
|
|
value,
|
|
|
|
|
} if array_to_boxcall => {
|
|
|
|
|
let a = *array;
|
|
|
|
|
let i = *index;
|
|
|
|
|
let v = *value;
|
|
|
|
|
*term = I::BoxCall {
|
|
|
|
|
dst: None,
|
|
|
|
|
box_val: a,
|
|
|
|
|
method: "set".to_string(),
|
|
|
|
|
method_id: None,
|
|
|
|
|
args: vec![i, v],
|
|
|
|
|
effects: crate::mir::EffectMask::WRITE,
|
|
|
|
|
};
|
2025-09-17 05:56:33 +09:00
|
|
|
stats.intrinsic_optimizations += 1;
|
|
|
|
|
}
|
|
|
|
|
_ => {}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-11-13 16:40:58 +09:00
|
|
|
if idemp_enabled() { let key = idemp_key(pass_name, &fname); idemp_mark(module, key); }
|
2025-09-17 05:56:33 +09:00
|
|
|
}
|
|
|
|
|
stats
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-17 07:43:07 +09:00
|
|
|
pub fn normalize_ref_field_access(
|
|
|
|
|
_opt: &mut MirOptimizer,
|
|
|
|
|
module: &mut MirModule,
|
|
|
|
|
) -> OptimizationStats {
|
2025-09-17 05:56:33 +09:00
|
|
|
use crate::mir::MirInstruction as I;
|
|
|
|
|
let mut stats = OptimizationStats::new();
|
2025-11-13 16:40:58 +09:00
|
|
|
let pass_name = "normalize.ref_field_access";
|
|
|
|
|
let func_names: Vec<String> = module.functions.keys().cloned().collect();
|
|
|
|
|
for fname in func_names {
|
|
|
|
|
if idemp_enabled() {
|
|
|
|
|
let key = idemp_key(pass_name, &fname);
|
|
|
|
|
if idemp_already_done(module, &key) { continue; }
|
|
|
|
|
}
|
|
|
|
|
let function = match module.functions.get_mut(&fname) { Some(f) => f, None => continue };
|
2025-09-17 05:56:33 +09:00
|
|
|
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() {
|
|
|
|
|
match inst {
|
2025-09-17 07:43:07 +09:00
|
|
|
I::RefGet {
|
|
|
|
|
dst,
|
|
|
|
|
reference,
|
|
|
|
|
field,
|
|
|
|
|
} => {
|
2025-09-17 05:56:33 +09:00
|
|
|
let new_id = ValueId::new(function.next_value_id);
|
|
|
|
|
function.next_value_id += 1;
|
2025-09-17 07:43:07 +09:00
|
|
|
out.push(I::Const {
|
|
|
|
|
dst: new_id,
|
2025-09-22 21:52:39 +09:00
|
|
|
value: crate::mir::ConstValue::String(field),
|
2025-09-17 07:43:07 +09:00
|
|
|
});
|
|
|
|
|
out.push(I::BoxCall {
|
|
|
|
|
dst: Some(dst),
|
|
|
|
|
box_val: reference,
|
|
|
|
|
method: "getField".to_string(),
|
|
|
|
|
method_id: None,
|
|
|
|
|
args: vec![new_id],
|
|
|
|
|
effects: crate::mir::EffectMask::READ,
|
|
|
|
|
});
|
2025-09-17 05:56:33 +09:00
|
|
|
stats.intrinsic_optimizations += 1;
|
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
I::RefSet {
|
|
|
|
|
reference,
|
|
|
|
|
field,
|
|
|
|
|
value,
|
|
|
|
|
} => {
|
2025-09-17 05:56:33 +09:00
|
|
|
let new_id = ValueId::new(function.next_value_id);
|
|
|
|
|
function.next_value_id += 1;
|
2025-09-17 07:43:07 +09:00
|
|
|
out.push(I::Const {
|
|
|
|
|
dst: new_id,
|
2025-09-22 21:52:39 +09:00
|
|
|
value: crate::mir::ConstValue::String(field),
|
2025-09-17 07:43:07 +09:00
|
|
|
});
|
|
|
|
|
out.push(I::Barrier {
|
|
|
|
|
op: BarrierOp::Write,
|
|
|
|
|
ptr: reference,
|
|
|
|
|
});
|
|
|
|
|
out.push(I::BoxCall {
|
|
|
|
|
dst: None,
|
|
|
|
|
box_val: reference,
|
|
|
|
|
method: "setField".to_string(),
|
|
|
|
|
method_id: None,
|
|
|
|
|
args: vec![new_id, value],
|
|
|
|
|
effects: crate::mir::EffectMask::WRITE,
|
|
|
|
|
});
|
2025-09-17 05:56:33 +09:00
|
|
|
stats.intrinsic_optimizations += 1;
|
|
|
|
|
}
|
|
|
|
|
other => out.push(other),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
block.instructions = out;
|
|
|
|
|
|
|
|
|
|
if let Some(term) = block.terminator.take() {
|
|
|
|
|
block.terminator = Some(match term {
|
2025-09-17 07:43:07 +09:00
|
|
|
I::RefGet {
|
|
|
|
|
dst,
|
|
|
|
|
reference,
|
|
|
|
|
field,
|
|
|
|
|
} => {
|
2025-09-17 05:56:33 +09:00
|
|
|
let new_id = ValueId::new(function.next_value_id);
|
|
|
|
|
function.next_value_id += 1;
|
2025-09-17 07:43:07 +09:00
|
|
|
block.instructions.push(I::Const {
|
|
|
|
|
dst: new_id,
|
2025-09-22 21:52:39 +09:00
|
|
|
value: crate::mir::ConstValue::String(field),
|
2025-09-17 07:43:07 +09:00
|
|
|
});
|
|
|
|
|
I::BoxCall {
|
|
|
|
|
dst: Some(dst),
|
|
|
|
|
box_val: reference,
|
|
|
|
|
method: "getField".to_string(),
|
|
|
|
|
method_id: None,
|
|
|
|
|
args: vec![new_id],
|
|
|
|
|
effects: crate::mir::EffectMask::READ,
|
|
|
|
|
}
|
2025-09-17 05:56:33 +09:00
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
I::RefSet {
|
|
|
|
|
reference,
|
|
|
|
|
field,
|
|
|
|
|
value,
|
|
|
|
|
} => {
|
2025-09-17 05:56:33 +09:00
|
|
|
let new_id = ValueId::new(function.next_value_id);
|
|
|
|
|
function.next_value_id += 1;
|
2025-09-17 07:43:07 +09:00
|
|
|
block.instructions.push(I::Const {
|
|
|
|
|
dst: new_id,
|
2025-09-22 21:52:39 +09:00
|
|
|
value: crate::mir::ConstValue::String(field),
|
2025-09-17 07:43:07 +09:00
|
|
|
});
|
|
|
|
|
block.instructions.push(I::Barrier {
|
|
|
|
|
op: BarrierOp::Write,
|
|
|
|
|
ptr: reference,
|
|
|
|
|
});
|
|
|
|
|
I::BoxCall {
|
|
|
|
|
dst: None,
|
|
|
|
|
box_val: reference,
|
|
|
|
|
method: "setField".to_string(),
|
|
|
|
|
method_id: None,
|
|
|
|
|
args: vec![new_id, value],
|
|
|
|
|
effects: crate::mir::EffectMask::WRITE,
|
|
|
|
|
}
|
2025-09-17 05:56:33 +09:00
|
|
|
}
|
|
|
|
|
other => other,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-11-13 16:40:58 +09:00
|
|
|
if idemp_enabled() { let key = idemp_key(pass_name, &fname); idemp_mark(module, key); }
|
2025-09-17 05:56:33 +09:00
|
|
|
}
|
|
|
|
|
stats
|
|
|
|
|
}
|