removing useless clobbers

This commit is contained in:
Jakub Doka 2024-10-24 12:28:18 +02:00
parent 0c2db878f0
commit 78ebc3292c
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
5 changed files with 81 additions and 55 deletions

View file

@ -252,7 +252,7 @@ mod ty {
parser::{self, Pos}, parser::{self, Pos},
Size, Types, Size, Types,
}, },
core::{num::NonZeroU32, ops::Range}, core::{num::NonZeroU32, ops::Range, usize},
}; };
pub type ArrayLen = u32; pub type ArrayLen = u32;
@ -449,6 +449,15 @@ mod ty {
Kind::Func(_) | Kind::Global(_) | Kind::Module(_) => unreachable!(), Kind::Func(_) | Kind::Global(_) | Kind::Module(_) => unreachable!(),
} }
} }
pub(crate) fn has_pointers(&self, tys: &Types) -> bool {
match self.expand() {
Kind::Struct(s) => tys.struct_fields(s).iter().any(|f| f.ty.has_pointers(tys)),
Kind::Ptr(_) => true,
Kind::Slice(s) => tys.ins.slices[s as usize].len == ArrayLen::MAX,
_ => false,
}
}
} }
#[derive(PartialEq, Eq, Clone, Copy)] #[derive(PartialEq, Eq, Clone, Copy)]

View file

@ -16,7 +16,7 @@ use {
Comptime, Func, Global, HashMap, Offset, OffsetIter, PLoc, Reloc, Sig, SymKey, TypeParser, Comptime, Func, Global, HashMap, Offset, OffsetIter, PLoc, Reloc, Sig, SymKey, TypeParser,
TypedReloc, Types, TypedReloc, Types,
}, },
alloc::{string::String, vec::Vec}, alloc::{borrow::ToOwned, string::String, vec::Vec},
core::{ core::{
assert_matches::debug_assert_matches, assert_matches::debug_assert_matches,
cell::RefCell, cell::RefCell,
@ -27,7 +27,6 @@ use {
hashbrown::hash_map, hashbrown::hash_map,
hbbytecode::DisasmError, hbbytecode::DisasmError,
regalloc2::VReg, regalloc2::VReg,
std::borrow::ToOwned,
}; };
const VOID: Nid = 0; const VOID: Nid = 0;
@ -45,7 +44,7 @@ trait StoreId: Sized {
impl StoreId for Nid { impl StoreId for Nid {
fn to_store(self) -> Option<Self> { fn to_store(self) -> Option<Self> {
(self != ENTRY).then_some(self) (self != MEM).then_some(self)
} }
} }
@ -1134,7 +1133,7 @@ mod var {
use { use {
super::{Kind, Nid, Nodes}, super::{Kind, Nid, Nodes},
crate::{ident::Ident, ty}, crate::{ident::Ident, ty},
std::{panic, vec::Vec}, alloc::vec::Vec,
}; };
// makes sure value inside is laways locked for this instance of variable // makes sure value inside is laways locked for this instance of variable
@ -1158,7 +1157,7 @@ mod var {
pub fn set_value(&mut self, mut new_value: Nid, nodes: &mut Nodes) -> Nid { pub fn set_value(&mut self, mut new_value: Nid, nodes: &mut Nodes) -> Nid {
nodes.unlock(self.value); nodes.unlock(self.value);
std::mem::swap(&mut self.value, &mut new_value); core::mem::swap(&mut self.value, &mut new_value);
nodes.lock(self.value); nodes.lock(self.value);
new_value new_value
} }
@ -1170,7 +1169,7 @@ mod var {
pub fn remove(self, nodes: &mut Nodes) { pub fn remove(self, nodes: &mut Nodes) {
nodes.unlock_remove(self.value); nodes.unlock_remove(self.value);
std::mem::forget(self); core::mem::forget(self);
} }
pub fn set_value_remove(&mut self, new_value: Nid, nodes: &mut Nodes) { pub fn set_value_remove(&mut self, new_value: Nid, nodes: &mut Nodes) {
@ -1184,7 +1183,7 @@ mod var {
} else { } else {
nodes.unlock_remove(self.value); nodes.unlock_remove(self.value);
} }
std::mem::forget(self); core::mem::forget(self);
} }
} }
@ -1219,7 +1218,7 @@ mod var {
pub fn clear(&mut self, nodes: &mut Nodes) { pub fn clear(&mut self, nodes: &mut Nodes) {
self.vars.drain(..).for_each(|n| n.remove(nodes)); self.vars.drain(..).for_each(|n| n.remove(nodes));
self.loads.drain(..).for_each(|l| _ = nodes.unlock_remove(l)); self.loads.drain(..).for_each(|l| _ = nodes.unlock_remove(l));
std::mem::take(&mut self.store).remove(nodes); core::mem::take(&mut self.store).remove(nodes);
} }
} }
} }
@ -1268,15 +1267,17 @@ impl ItemCtx {
self.nodes.lock(end); self.nodes.lock(end);
self.ctrl = self.nodes.new_node(ty::Id::VOID, Kind::Entry, [VOID]); self.ctrl = self.nodes.new_node(ty::Id::VOID, Kind::Entry, [VOID]);
debug_assert_eq!(self.ctrl, ENTRY); debug_assert_eq!(self.ctrl, ENTRY);
self.nodes.lock(self.ctrl);
let mem = self.nodes.new_node(ty::Id::VOID, Kind::Mem, [VOID]); let mem = self.nodes.new_node(ty::Id::VOID, Kind::Mem, [VOID]);
debug_assert_eq!(mem, MEM); debug_assert_eq!(mem, MEM);
self.nodes.lock(mem); self.nodes.lock(mem);
self.scope.store = Variable::new(0, ty::Id::VOID, false, ENTRY, &mut self.nodes); self.scope.store = Variable::new(0, ty::Id::VOID, false, MEM, &mut self.nodes);
} }
fn finalize(&mut self) { fn finalize(&mut self) {
self.scope.clear(&mut self.nodes); self.scope.clear(&mut self.nodes);
self.nodes.unlock(NEVER); self.nodes.unlock(NEVER);
self.nodes.unlock(ENTRY);
self.nodes.unlock(MEM); self.nodes.unlock(MEM);
self.nodes.eliminate_stack_temporaries(); self.nodes.eliminate_stack_temporaries();
} }
@ -1609,7 +1610,7 @@ impl ItemCtx {
self.nodes.graphviz(tys, files); self.nodes.graphviz(tys, files);
debug_assert!(self.code.is_empty()); debug_assert!(self.code.is_empty());
let tail = std::mem::take(&mut self.call_count) == 0; let tail = core::mem::take(&mut self.call_count) == 0;
'_open_function: { '_open_function: {
self.emit(instrs::addi64(reg::STACK_PTR, reg::STACK_PTR, 0)); self.emit(instrs::addi64(reg::STACK_PTR, reg::STACK_PTR, 0));
@ -1620,10 +1621,20 @@ impl ItemCtx {
'_compute_stack: { '_compute_stack: {
let mems = core::mem::take(&mut self.nodes[MEM].outputs); let mems = core::mem::take(&mut self.nodes[MEM].outputs);
for &stck in mems.iter() { for &stck in mems.iter() {
if !matches!(self.nodes[stck].kind, Kind::Stck | Kind::Arg) {
debug_assert_matches!(
self.nodes[stck].kind,
Kind::Phi | Kind::Return | Kind::Load
);
continue;
}
stack_size += tys.size_of(self.nodes[stck].ty); stack_size += tys.size_of(self.nodes[stck].ty);
self.nodes[stck].offset = stack_size; self.nodes[stck].offset = stack_size;
} }
for &stck in mems.iter() { for &stck in mems.iter() {
if !matches!(self.nodes[stck].kind, Kind::Stck | Kind::Arg) {
continue;
}
self.nodes[stck].offset = stack_size - self.nodes[stck].offset; self.nodes[stck].offset = stack_size - self.nodes[stck].offset;
} }
self.nodes[MEM].outputs = mems; self.nodes[MEM].outputs = mems;
@ -1837,7 +1848,7 @@ impl TypeParser for Codegen<'_> {
} }
fn eval_const(&mut self, file: FileId, expr: &Expr, ret: ty::Id) -> u64 { fn eval_const(&mut self, file: FileId, expr: &Expr, ret: ty::Id) -> u64 {
let mut scope = std::mem::take(&mut self.ci.scope.vars); let mut scope = core::mem::take(&mut self.ci.scope.vars);
self.pool.push_ci(file, Some(ret), self.tasks.len(), &mut self.ci); self.pool.push_ci(file, Some(ret), self.tasks.len(), &mut self.ci);
self.ci.scope.vars = scope; self.ci.scope.vars = scope;
@ -1845,7 +1856,7 @@ impl TypeParser for Codegen<'_> {
self.expr(&Expr::Return { pos: expr.pos(), val: Some(expr) }); self.expr(&Expr::Return { pos: expr.pos(), val: Some(expr) });
scope = std::mem::take(&mut self.ci.scope.vars); scope = core::mem::take(&mut self.ci.scope.vars);
self.ci.finalize(); self.ci.finalize();
if self.errors.borrow().len() == prev_err_len { if self.errors.borrow().len() == prev_err_len {
@ -2187,6 +2198,7 @@ impl<'a> Codegen<'a> {
self.assert_ty(pos, &mut value, expected, "return value"); self.assert_ty(pos, &mut value, expected, "return value");
if self.ci.inline_depth == 0 { if self.ci.inline_depth == 0 {
debug_assert_ne!(self.ci.ctrl, VOID);
let mut inps = Vc::from([self.ci.ctrl, value.id]); let mut inps = Vc::from([self.ci.ctrl, value.id]);
self.ci.nodes.load_loop_store(&mut self.ci.scope.store, &mut self.ci.loops); self.ci.nodes.load_loop_store(&mut self.ci.scope.store, &mut self.ci.loops);
if let Some(str) = self.ci.scope.store.value().to_store() { if let Some(str) = self.ci.scope.store.value().to_store() {
@ -2610,10 +2622,12 @@ impl<'a> Codegen<'a> {
let mut tys = sig.args.args(); let mut tys = sig.args.args();
let mut cargs = cargs.iter(); let mut cargs = cargs.iter();
let mut args = args.iter(); let mut args = args.iter();
let mut has_ptr_arg = false;
while let Some(ty) = tys.next(&self.tys) { while let Some(ty) = tys.next(&self.tys) {
let carg = cargs.next().unwrap(); let carg = cargs.next().unwrap();
let arg = args.next().unwrap(); let arg = args.next().unwrap();
let Arg::Value(ty) = ty else { continue }; let Arg::Value(ty) = ty else { continue };
has_ptr_arg |= ty.has_pointers(&self.tys);
let mut value = self.expr_ctx(arg, Ctx::default().with_ty(ty))?; let mut value = self.expr_ctx(arg, Ctx::default().with_ty(ty))?;
debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre); debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre);
@ -2627,20 +2641,22 @@ impl<'a> Codegen<'a> {
self.ci.nodes.unlock(n); self.ci.nodes.unlock(n);
} }
if let Some(str) = self.ci.scope.store.value().to_store() { if has_ptr_arg {
inps.push(str); if let Some(str) = self.ci.scope.store.value().to_store() {
inps.push(str);
}
self.ci.scope.loads.retain(|&load| {
if inps.contains(&load) {
return true;
}
if !self.ci.nodes.unlock_remove(load) {
inps.push(load);
}
false
});
} }
self.ci.scope.loads.retain(|&load| {
if inps.contains(&load) {
return true;
}
if !self.ci.nodes.unlock_remove(load) {
inps.push(load);
}
false
});
let alt_value = match sig.ret.loc(&self.tys) { let alt_value = match sig.ret.loc(&self.tys) {
Loc::Reg => None, Loc::Reg => None,
@ -2655,7 +2671,9 @@ impl<'a> Codegen<'a> {
self.ci.ctrl = self.ci.ctrl =
self.ci.nodes.new_node(sig.ret, Kind::Call { func: fu, args: sig.args }, inps); self.ci.nodes.new_node(sig.ret, Kind::Call { func: fu, args: sig.args }, inps);
self.store_mem(VOID, ty::Id::VOID, VOID); if has_ptr_arg {
self.store_mem(VOID, ty::Id::VOID, VOID);
}
alt_value.or(Some(Value::new(self.ci.ctrl).ty(sig.ret))) alt_value.or(Some(Value::new(self.ci.ctrl).ty(sig.ret)))
} }
@ -2737,7 +2755,7 @@ impl<'a> Codegen<'a> {
} }
let prev_var_base = let prev_var_base =
std::mem::replace(&mut self.ci.inline_var_base, self.ci.scope.vars.len()); core::mem::replace(&mut self.ci.inline_var_base, self.ci.scope.vars.len());
let prev_ret = self.ci.ret.replace(sig.ret); let prev_ret = self.ci.ret.replace(sig.ret);
let prev_inline_ret = self.ci.inline_ret.take(); let prev_inline_ret = self.ci.inline_ret.take();
let prev_file = core::mem::replace(&mut self.ci.file, file); let prev_file = core::mem::replace(&mut self.ci.file, file);
@ -3950,7 +3968,6 @@ impl<'a> Function<'a> {
} }
Kind::Stck Kind::Stck
if node.ty.loc(self.tys) == Loc::Reg && node.outputs.iter().all(|&n| { if node.ty.loc(self.tys) == Loc::Reg && node.outputs.iter().all(|&n| {
matches!(self.nodes[n].kind, Kind::Stre | Kind::Load) matches!(self.nodes[n].kind, Kind::Stre | Kind::Load)
|| matches!(self.nodes[n].kind, Kind::BinOp { op: TokenKind::Add } || matches!(self.nodes[n].kind, Kind::BinOp { op: TokenKind::Add }
if self.nodes.is_const(self.nodes[n].inputs[2]) if self.nodes.is_const(self.nodes[n].inputs[2])
@ -4425,7 +4442,7 @@ mod tests {
different_types; different_types;
struct_return_from_module_function; struct_return_from_module_function;
sort_something_viredly; sort_something_viredly;
//structs_in_registers; structs_in_registers;
comptime_function_from_another_file; comptime_function_from_another_file;
inline_test; inline_test;
inlined_generic_functions; inlined_generic_functions;

View file

@ -23,11 +23,11 @@ main:
JAL r31, r0, :multiple_breaks JAL r31, r0, :multiple_breaks
CP r3, r1 CP r3, r1
LI64 r1, 3d LI64 r1, 3d
LI64 r6, 1d LI64 r7, 1d
JEQ r3, r1, :0 JEQ r3, r1, :0
CP r1, r6 CP r1, r7
JMP :1 JMP :1
0: CP r33, r6 0: CP r33, r7
CP r34, r1 CP r34, r1
LI64 r35, 4d LI64 r35, 4d
CP r2, r35 CP r2, r35

View file

@ -10,28 +10,28 @@ foo:
ADDI64 r254, r254, 16d ADDI64 r254, r254, 16d
JALA r0, r31, 0a JALA r0, r31, 0a
main: main:
ADDI64 r254, r254, -72d ADDI64 r254, r254, -56d
ST r31, r254, 48a, 24h ST r31, r254, 48a, 8h
ADDI64 r2, r254, 32d ADDI64 r2, r254, 32d
JAL r31, r0, :foo JAL r31, r0, :foo
ST r1, r254, 32a, 16h ST r1, r254, 32a, 16h
ADDI64 r8, r254, 16d ADDI64 r8, r254, 16d
LD r32, r254, 32a, 8h
JAL r31, r0, :foo JAL r31, r0, :foo
ST r1, r254, 16a, 16h ST r1, r254, 16a, 16h
ADDI64 r3, r254, 0d ADDI64 r2, r254, 0d
LD r33, r254, 24a, 4h
JAL r31, r0, :foo JAL r31, r0, :foo
ST r1, r254, 0a, 16h ST r1, r254, 0a, 16h
LI64 r9, 7d LI64 r7, 7d
LD r10, r254, 12a, 4h LD r8, r254, 12a, 4h
ANDI r11, r10, 4294967295d ANDI r9, r8, 4294967295d
ANDI r8, r33, 4294967295d LD r5, r254, 24a, 4h
ADD64 r12, r32, r8 ANDI r8, r5, 4294967295d
ADD64 r3, r12, r11 LD r3, r254, 32a, 8h
SUB64 r1, r9, r3 ADD64 r11, r3, r8
LD r31, r254, 48a, 24h ADD64 r3, r11, r9
ADDI64 r254, r254, 72d SUB64 r1, r7, r3
LD r31, r254, 48a, 8h
ADDI64 r254, r254, 56d
JALA r0, r31, 0a JALA r0, r31, 0a
code size: 359 code size: 359
ret: 0 ret: 0

View file

@ -1,26 +1,26 @@
main: main:
ADDI64 r254, r254, -88d ADDI64 r254, r254, -96d
ST r31, r254, 64a, 24h ST r31, r254, 64a, 32h
LI64 r32, 3d LI64 r32, 3d
LI64 r3, 4d LI64 r3, 4d
ADDI64 r33, r254, 0d ADDI64 r33, r254, 0d
ADDI64 r7, r254, 16d ADDI64 r34, r254, 48d
ADDI64 r5, r254, 48d
ST r3, r254, 48a, 8h ST r3, r254, 48a, 8h
ST r32, r254, 56a, 8h ST r32, r254, 56a, 8h
BMC r5, r7, 16h LD r3, r34, 0a, 16h
LD r3, r5, 0a, 16h
JAL r31, r0, :odher_pass JAL r31, r0, :odher_pass
ST r1, r254, 0a, 16h ST r1, r254, 0a, 16h
ADDI64 r11, r254, 16d
ADDI64 r2, r254, 32d ADDI64 r2, r254, 32d
BMC r34, r11, 16h
BMC r33, r2, 16h BMC r33, r2, 16h
LD r7, r254, 40a, 8h LD r7, r254, 40a, 8h
JNE r7, r32, :0 JNE r7, r32, :0
JAL r31, r0, :pass JAL r31, r0, :pass
JMP :1 JMP :1
0: LI64 r1, 0d 0: LI64 r1, 0d
1: LD r31, r254, 64a, 24h 1: LD r31, r254, 64a, 32h
ADDI64 r254, r254, 88d ADDI64 r254, r254, 96d
JALA r0, r31, 0a JALA r0, r31, 0a
odher_pass: odher_pass:
ADDI64 r254, r254, -16d ADDI64 r254, r254, -16d