clobber global loads across functions

This commit is contained in:
Jakub Doka 2024-10-29 15:04:07 +01:00
parent 24b9f9e78b
commit 9cf7933251
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
4 changed files with 60 additions and 11 deletions

View file

@ -1166,3 +1166,18 @@ main := fn(): uint {
return *mem return *mem
} }
``` ```
#### global_aliasing_overptimization
```hb
var := 0
main := fn(): uint {
var = 2
clobber()
return var
}
clobber := fn(): void {
var = 0
}
```

View file

@ -33,6 +33,8 @@ const ENTRY: Nid = 2;
const MEM: Nid = 3; const MEM: Nid = 3;
const LOOPS: Nid = 4; const LOOPS: Nid = 4;
const ARG_START: usize = 3; const ARG_START: usize = 3;
const DEFAULT_ACLASS: usize = 0;
const GLOBAL_ACLASS: usize = 1;
pub mod hbvm; pub mod hbvm;
@ -1819,7 +1821,8 @@ impl ItemCtx {
let loops = self.nodes.new_node(ty::Id::VOID, Kind::Loops, [VOID]); let loops = self.nodes.new_node(ty::Id::VOID, Kind::Loops, [VOID]);
debug_assert_eq!(loops, LOOPS); debug_assert_eq!(loops, LOOPS);
self.nodes.lock(loops); self.nodes.lock(loops);
self.scope.aclasses.push(AClass::new(&mut self.nodes)); self.scope.aclasses.push(AClass::new(&mut self.nodes)); // DEFAULT
self.scope.aclasses.push(AClass::new(&mut self.nodes)); // GLOBAL
} }
fn finalize(&mut self, stack: &mut Vec<Nid>, _tys: &Types, _files: &[parser::Ast]) { fn finalize(&mut self, stack: &mut Vec<Nid>, _tys: &Types, _files: &[parser::Ast]) {
@ -2264,6 +2267,7 @@ impl<'a> Codegen<'a> {
ty::Kind::Global(global) => { ty::Kind::Global(global) => {
let gl = &self.tys.ins.globals[global as usize]; let gl = &self.tys.ins.globals[global as usize];
let value = self.ci.nodes.new_node(gl.ty, Kind::Global { global }, [VOID]); let value = self.ci.nodes.new_node(gl.ty, Kind::Global { global }, [VOID]);
self.ci.nodes[value].aclass = GLOBAL_ACLASS;
Some(Value::ptr(value).ty(gl.ty)) Some(Value::ptr(value).ty(gl.ty))
} }
_ => Some(Value::new(Nid::MAX).ty(decl)), _ => Some(Value::new(Nid::MAX).ty(decl)),
@ -2296,6 +2300,7 @@ impl<'a> Codegen<'a> {
} }
}; };
let global = self.ci.nodes.new_node(ty, Kind::Global { global }, [VOID]); let global = self.ci.nodes.new_node(ty, Kind::Global { global }, [VOID]);
self.ci.nodes[global].aclass = GLOBAL_ACLASS;
Some(Value::new(global).ty(ty)) Some(Value::new(global).ty(ty))
} }
Expr::Return { pos, val } => { Expr::Return { pos, val } => {
@ -2365,6 +2370,7 @@ impl<'a> Codegen<'a> {
let gl = &self.tys.ins.globals[global as usize]; let gl = &self.tys.ins.globals[global as usize];
let value = let value =
self.ci.nodes.new_node(gl.ty, Kind::Global { global }, [VOID]); self.ci.nodes.new_node(gl.ty, Kind::Global { global }, [VOID]);
self.ci.nodes[value].aclass = GLOBAL_ACLASS;
Some(Value::ptr(value).ty(gl.ty)) Some(Value::ptr(value).ty(gl.ty))
} }
v => Some(Value::new(Nid::MAX).ty(v.compress())), v => Some(Value::new(Nid::MAX).ty(v.compress())),
@ -2739,7 +2745,7 @@ impl<'a> Codegen<'a> {
let mut inps = Vc::from([NEVER]); let mut inps = Vc::from([NEVER]);
let arg_base = self.tys.tmp.args.len(); let arg_base = self.tys.tmp.args.len();
let mut clobbered_aliases = vec![]; let mut clobbered_aliases = vec![GLOBAL_ACLASS];
for arg in args { for arg in args {
let value = self.expr(arg)?; let value = self.expr(arg)?;
if let Some(base) = self.tys.base_of(value.ty) { if let Some(base) = self.tys.base_of(value.ty) {
@ -2764,6 +2770,7 @@ impl<'a> Codegen<'a> {
for &clobbered in clobbered_aliases.iter() { for &clobbered in clobbered_aliases.iter() {
let aclass = &mut self.ci.scope.aclasses[clobbered]; let aclass = &mut self.ci.scope.aclasses[clobbered];
self.ci.nodes.load_loop_aclass(clobbered, aclass, &mut self.ci.loops);
inps.push(aclass.last_store.get()); inps.push(aclass.last_store.get());
aclass.loads.retain_mut(|load| { aclass.loads.retain_mut(|load| {
if inps.contains(&load.get()) { if inps.contains(&load.get()) {
@ -2794,10 +2801,13 @@ impl<'a> Codegen<'a> {
); );
for &clobbered in clobbered_aliases.iter() { for &clobbered in clobbered_aliases.iter() {
if clobbered == 0 { if clobbered == DEFAULT_ACLASS {
continue; continue;
} }
let aclass = self.ci.scope.aclasses[clobbered].last_store.get(); let aclass = self.ci.scope.aclasses[clobbered].last_store.get();
if aclass == MEM {
continue;
}
self.store_mem(self.ci.nodes[aclass].inputs[2], ty::Id::VOID, VOID); self.store_mem(self.ci.nodes[aclass].inputs[2], ty::Id::VOID, VOID);
} }
@ -2839,7 +2849,7 @@ 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 clobbered_aliases = vec![]; let mut clobbered_aliases = vec![GLOBAL_ACLASS];
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 Some(arg) = args.next() else { break }; let Some(arg) = args.next() else { break };
@ -2868,6 +2878,7 @@ impl<'a> Codegen<'a> {
for &clobbered in clobbered_aliases.iter() { for &clobbered in clobbered_aliases.iter() {
let aclass = &mut self.ci.scope.aclasses[clobbered]; let aclass = &mut self.ci.scope.aclasses[clobbered];
self.ci.nodes.load_loop_aclass(clobbered, aclass, &mut self.ci.loops);
inps.push(aclass.last_store.get()); inps.push(aclass.last_store.get());
aclass.loads.retain_mut(|load| { aclass.loads.retain_mut(|load| {
if inps.contains(&load.get()) { if inps.contains(&load.get()) {
@ -2898,10 +2909,13 @@ impl<'a> Codegen<'a> {
); );
for &clobbered in clobbered_aliases.iter() { for &clobbered in clobbered_aliases.iter() {
if clobbered == 0 { if clobbered == DEFAULT_ACLASS {
continue; continue;
} }
let aclass = self.ci.scope.aclasses[clobbered].last_store.get(); let aclass = self.ci.scope.aclasses[clobbered].last_store.get();
if aclass == MEM {
continue;
}
self.store_mem(self.ci.nodes[aclass].inputs[2], ty::Id::VOID, VOID); self.store_mem(self.ci.nodes[aclass].inputs[2], ty::Id::VOID, VOID);
} }
@ -4085,5 +4099,6 @@ mod tests {
dead_code_in_loop; dead_code_in_loop;
infinite_loop_after_peephole; infinite_loop_after_peephole;
aliasing_overoptimization; aliasing_overoptimization;
global_aliasing_overptimization;
} }
} }

View file

@ -0,0 +1,19 @@
clobber:
LRA r1, r0, :var
LI64 r3, 0d
ST r3, r1, 0a, 8h
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -16d
ST r31, r254, 0a, 16h
LRA r32, r0, :var
LI64 r3, 2d
ST r3, r32, 0a, 8h
JAL r31, r0, :clobber
LD r1, r32, 0a, 8h
LD r31, r254, 0a, 16h
ADDI64 r254, r254, 16d
JALA r0, r31, 0a
code size: 166
ret: 0
status: Ok(())

View file

@ -1,21 +1,21 @@
main: main:
ADDI64 r254, r254, -64d ADDI64 r254, r254, -64d
LI64 r3, 1d LI64 r3, 1d
ADDI64 r2, r254, 48d ADDI64 r2, r254, 32d
ST r3, r254, 48a, 8h ST r3, r254, 32a, 8h
LI64 r6, 2d LI64 r6, 2d
ST r6, r254, 56a, 8h ST r6, r254, 40a, 8h
LI64 r6, -3d LI64 r6, -3d
ADDI64 r5, r254, 0d ADDI64 r5, r254, 0d
ADDI64 r11, r254, 32d ADDI64 r11, r254, 48d
ST r6, r254, 0a, 8h ST r6, r254, 0a, 8h
LI64 r6, -4d LI64 r6, -4d
BMC r2, r11, 16h BMC r2, r11, 16h
ST r6, r254, 8a, 8h ST r6, r254, 8a, 8h
ADDI64 r3, r5, 16d ADDI64 r3, r5, 16d
LD r9, r254, 40a, 8h LD r9, r254, 56a, 8h
LI64 r8, 4d LI64 r8, 4d
LD r10, r254, 32a, 8h LD r10, r254, 48a, 8h
LI64 r11, 3d LI64 r11, 3d
BMC r2, r3, 16h BMC r2, r3, 16h
SUB64 r4, r8, r9 SUB64 r4, r8, r9