docs/ci: selfhost bootstrap/exe-first workflows; add ny-llvmc scaffolding + JSON v0 schema validation; plan: unify to Nyash ABI v2 (no backwards compat)
This commit is contained in:
@ -105,7 +105,7 @@ impl MirOptimizer {
|
||||
|
||||
// Pass 7 (optional): Core-13 pure normalization
|
||||
if crate::config::env::mir_core13_pure() {
|
||||
stats.merge(self.normalize_pure_core13(module));
|
||||
stats.merge(crate::mir::optimizer_passes::normalize_core13_pure::normalize_pure_core13(self, module));
|
||||
}
|
||||
|
||||
if self.debug {
|
||||
@ -147,200 +147,7 @@ impl MirOptimizer {
|
||||
/// Neg x => BinOp(Sub, Const 0, x)
|
||||
/// Not x => Compare(Eq, x, Const false)
|
||||
/// BitNot x => BinOp(BitXor, x, Const(-1))
|
||||
fn normalize_pure_core13(&mut self, module: &mut MirModule) -> OptimizationStats {
|
||||
use super::instruction::ConstValue;
|
||||
use super::{BinaryOp, CompareOp, MirInstruction as I};
|
||||
let mut stats = OptimizationStats::new();
|
||||
for (_fname, function) in &mut module.functions {
|
||||
for (_bb, block) in &mut function.blocks {
|
||||
let mut out: Vec<I> = Vec::with_capacity(block.instructions.len() + 8);
|
||||
let old = std::mem::take(&mut block.instructions);
|
||||
for inst in old.into_iter() {
|
||||
match inst {
|
||||
I::Load { dst, ptr } => {
|
||||
out.push(I::ExternCall {
|
||||
dst: Some(dst),
|
||||
iface_name: "env.local".to_string(),
|
||||
method_name: "get".to_string(),
|
||||
args: vec![ptr],
|
||||
effects: super::EffectMask::READ,
|
||||
});
|
||||
stats.intrinsic_optimizations += 1;
|
||||
}
|
||||
I::Store { value, ptr } => {
|
||||
out.push(I::ExternCall {
|
||||
dst: None,
|
||||
iface_name: "env.local".to_string(),
|
||||
method_name: "set".to_string(),
|
||||
args: vec![ptr, value],
|
||||
effects: super::EffectMask::WRITE,
|
||||
});
|
||||
stats.intrinsic_optimizations += 1;
|
||||
}
|
||||
I::NewBox {
|
||||
dst,
|
||||
box_type,
|
||||
mut args,
|
||||
} => {
|
||||
// prepend type name as Const String
|
||||
let ty_id = super::ValueId::new(function.next_value_id);
|
||||
function.next_value_id += 1;
|
||||
out.push(I::Const {
|
||||
dst: ty_id,
|
||||
value: ConstValue::String(box_type),
|
||||
});
|
||||
let mut call_args = Vec::with_capacity(1 + args.len());
|
||||
call_args.push(ty_id);
|
||||
call_args.append(&mut args);
|
||||
out.push(I::ExternCall {
|
||||
dst: Some(dst),
|
||||
iface_name: "env.box".to_string(),
|
||||
method_name: "new".to_string(),
|
||||
args: call_args,
|
||||
effects: super::EffectMask::PURE, // constructor is logically alloc; conservatively PURE here
|
||||
});
|
||||
stats.intrinsic_optimizations += 1;
|
||||
}
|
||||
I::UnaryOp { dst, op, operand } => {
|
||||
match op {
|
||||
super::UnaryOp::Neg => {
|
||||
let zero = super::ValueId::new(function.next_value_id);
|
||||
function.next_value_id += 1;
|
||||
out.push(I::Const {
|
||||
dst: zero,
|
||||
value: ConstValue::Integer(0),
|
||||
});
|
||||
out.push(I::BinOp {
|
||||
dst,
|
||||
op: BinaryOp::Sub,
|
||||
lhs: zero,
|
||||
rhs: operand,
|
||||
});
|
||||
}
|
||||
super::UnaryOp::Not => {
|
||||
let f = super::ValueId::new(function.next_value_id);
|
||||
function.next_value_id += 1;
|
||||
out.push(I::Const {
|
||||
dst: f,
|
||||
value: ConstValue::Bool(false),
|
||||
});
|
||||
out.push(I::Compare {
|
||||
dst,
|
||||
op: CompareOp::Eq,
|
||||
lhs: operand,
|
||||
rhs: f,
|
||||
});
|
||||
}
|
||||
super::UnaryOp::BitNot => {
|
||||
let all1 = super::ValueId::new(function.next_value_id);
|
||||
function.next_value_id += 1;
|
||||
out.push(I::Const {
|
||||
dst: all1,
|
||||
value: ConstValue::Integer(-1),
|
||||
});
|
||||
out.push(I::BinOp {
|
||||
dst,
|
||||
op: BinaryOp::BitXor,
|
||||
lhs: operand,
|
||||
rhs: all1,
|
||||
});
|
||||
}
|
||||
}
|
||||
stats.intrinsic_optimizations += 1;
|
||||
}
|
||||
other => out.push(other),
|
||||
}
|
||||
}
|
||||
block.instructions = out;
|
||||
if let Some(term) = block.terminator.take() {
|
||||
block.terminator = Some(match term {
|
||||
I::Load { dst, ptr } => I::ExternCall {
|
||||
dst: Some(dst),
|
||||
iface_name: "env.local".to_string(),
|
||||
method_name: "get".to_string(),
|
||||
args: vec![ptr],
|
||||
effects: super::EffectMask::READ,
|
||||
},
|
||||
I::Store { value, ptr } => I::ExternCall {
|
||||
dst: None,
|
||||
iface_name: "env.local".to_string(),
|
||||
method_name: "set".to_string(),
|
||||
args: vec![ptr, value],
|
||||
effects: super::EffectMask::WRITE,
|
||||
},
|
||||
I::NewBox {
|
||||
dst,
|
||||
box_type,
|
||||
mut args,
|
||||
} => {
|
||||
let ty_id = super::ValueId::new(function.next_value_id);
|
||||
function.next_value_id += 1;
|
||||
block.instructions.push(I::Const {
|
||||
dst: ty_id,
|
||||
value: ConstValue::String(box_type),
|
||||
});
|
||||
let mut call_args = Vec::with_capacity(1 + args.len());
|
||||
call_args.push(ty_id);
|
||||
call_args.append(&mut args);
|
||||
I::ExternCall {
|
||||
dst: Some(dst),
|
||||
iface_name: "env.box".to_string(),
|
||||
method_name: "new".to_string(),
|
||||
args: call_args,
|
||||
effects: super::EffectMask::PURE,
|
||||
}
|
||||
}
|
||||
I::UnaryOp { dst, op, operand } => match op {
|
||||
super::UnaryOp::Neg => {
|
||||
let zero = super::ValueId::new(function.next_value_id);
|
||||
function.next_value_id += 1;
|
||||
block.instructions.push(I::Const {
|
||||
dst: zero,
|
||||
value: ConstValue::Integer(0),
|
||||
});
|
||||
I::BinOp {
|
||||
dst,
|
||||
op: BinaryOp::Sub,
|
||||
lhs: zero,
|
||||
rhs: operand,
|
||||
}
|
||||
}
|
||||
super::UnaryOp::Not => {
|
||||
let f = super::ValueId::new(function.next_value_id);
|
||||
function.next_value_id += 1;
|
||||
block.instructions.push(I::Const {
|
||||
dst: f,
|
||||
value: ConstValue::Bool(false),
|
||||
});
|
||||
I::Compare {
|
||||
dst,
|
||||
op: CompareOp::Eq,
|
||||
lhs: operand,
|
||||
rhs: f,
|
||||
}
|
||||
}
|
||||
super::UnaryOp::BitNot => {
|
||||
let all1 = super::ValueId::new(function.next_value_id);
|
||||
function.next_value_id += 1;
|
||||
block.instructions.push(I::Const {
|
||||
dst: all1,
|
||||
value: ConstValue::Integer(-1),
|
||||
});
|
||||
I::BinOp {
|
||||
dst,
|
||||
op: BinaryOp::BitXor,
|
||||
lhs: operand,
|
||||
rhs: all1,
|
||||
}
|
||||
}
|
||||
},
|
||||
other => other,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
stats
|
||||
}
|
||||
// normalize_pure_core13 moved to optimizer_passes::normalize_core13_pure
|
||||
|
||||
/// Eliminate dead code in a single function
|
||||
fn eliminate_dead_code_in_function(&mut self, function: &mut MirFunction) -> usize {
|
||||
|
||||
Reference in New Issue
Block a user