clobber global loads across functions
This commit is contained in:
parent
24b9f9e78b
commit
9cf7933251
|
@ -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
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
19
lang/tests/son_tests_global_aliasing_overptimization.txt
Normal file
19
lang/tests/son_tests_global_aliasing_overptimization.txt
Normal 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(())
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue