fixing compiler pulling function destinations out of the loops
This commit is contained in:
parent
a299bad75b
commit
29367d8f8b
|
@ -612,6 +612,30 @@ main := fn(): uint {
|
||||||
|
|
||||||
### Purely Testing Examples
|
### Purely Testing Examples
|
||||||
|
|
||||||
|
#### null_check_in_the_loop
|
||||||
|
```hb
|
||||||
|
A := struct {
|
||||||
|
x_change: u8,
|
||||||
|
y_change: u8,
|
||||||
|
left: u8,
|
||||||
|
middle: u8,
|
||||||
|
right: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
return_fn := fn(): ?A {
|
||||||
|
return A.(0, 0, 0, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
main := fn(): int {
|
||||||
|
loop {
|
||||||
|
ret := return_fn()
|
||||||
|
if ret != null {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
#### stack_provenance
|
#### stack_provenance
|
||||||
```hb
|
```hb
|
||||||
main := fn(): uint {
|
main := fn(): uint {
|
||||||
|
|
|
@ -225,13 +225,13 @@ impl Nodes {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut deepest = VOID;
|
let mut deepest = self[node].inputs[0];
|
||||||
for i in 0..self[node].inputs.len() {
|
for &inp in self[node].inputs[1..].iter() {
|
||||||
let inp = self[node].inputs[i];
|
|
||||||
if self.idepth(inp) > self.idepth(deepest) {
|
if self.idepth(inp) > self.idepth(deepest) {
|
||||||
if matches!(self[inp].kind, Kind::Call { .. }) {
|
if matches!(self[inp].kind, Kind::Call { .. }) {
|
||||||
deepest = inp;
|
deepest = inp;
|
||||||
} else {
|
} else {
|
||||||
|
debug_assert!(!self.is_cfg(inp));
|
||||||
deepest = self.idom(inp);
|
deepest = self.idom(inp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -256,14 +256,15 @@ impl Nodes {
|
||||||
self[deepest].outputs.push(node);
|
self[deepest].outputs.push(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_rpo(&mut self, node: Nid, rpo: &mut Vec<Nid>, visited: &mut BitSet) {
|
fn collect_rpo(&self, node: Nid, rpo: &mut Vec<Nid>, visited: &mut BitSet) {
|
||||||
if !self.is_cfg(node) || !visited.set(node) {
|
if !self.is_cfg(node) || !visited.set(node) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for i in 0..self[node].outputs.len() {
|
for &n in self[node].outputs.iter() {
|
||||||
self.collect_rpo(self[node].outputs[i], rpo, visited);
|
self.collect_rpo(n, rpo, visited);
|
||||||
}
|
}
|
||||||
|
|
||||||
rpo.push(node);
|
rpo.push(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1251,6 +1252,8 @@ impl Nodes {
|
||||||
return Some(NEVER);
|
return Some(NEVER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::dbg!(&self[self[target].inputs[1]]);
|
||||||
|
|
||||||
if self[target].inputs[1] == NEVER {
|
if self[target].inputs[1] == NEVER {
|
||||||
self.lock(target);
|
self.lock(target);
|
||||||
for o in self[target].outputs.clone() {
|
for o in self[target].outputs.clone() {
|
||||||
|
@ -2390,6 +2393,11 @@ impl<'a> Codegen<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let (index, _) = self.ci.nodes.aclass_index(region);
|
let (index, _) = self.ci.nodes.aclass_index(region);
|
||||||
|
if self.ci.nodes[value].kind == Kind::Load {
|
||||||
|
let (lindex, _) = self.ci.nodes.aclass_index(self.ci.nodes[value].inputs[1]);
|
||||||
|
let clobber = self.ci.scope.aclasses[lindex].clobber.get();
|
||||||
|
self.ci.scope.aclasses[index].clobber.set(clobber, &mut self.ci.nodes);
|
||||||
|
}
|
||||||
let aclass = &mut self.ci.scope.aclasses[index];
|
let aclass = &mut self.ci.scope.aclasses[index];
|
||||||
self.ci.nodes.load_loop_aclass(index, aclass, &mut self.ci.loops);
|
self.ci.nodes.load_loop_aclass(index, aclass, &mut self.ci.loops);
|
||||||
let vc = Vc::from([aclass.clobber.get(), value, region, aclass.last_store.get()]);
|
let vc = Vc::from([aclass.clobber.get(), value, region, aclass.last_store.get()]);
|
||||||
|
@ -2416,7 +2424,7 @@ impl<'a> Codegen<'a> {
|
||||||
let (index, _) = self.ci.nodes.aclass_index(region);
|
let (index, _) = self.ci.nodes.aclass_index(region);
|
||||||
let aclass = &mut self.ci.scope.aclasses[index];
|
let aclass = &mut self.ci.scope.aclasses[index];
|
||||||
self.ci.nodes.load_loop_aclass(index, aclass, &mut self.ci.loops);
|
self.ci.nodes.load_loop_aclass(index, aclass, &mut self.ci.loops);
|
||||||
let vc = [aclass.clobber.get(), region, aclass.last_store.get()];
|
let vc = [std::dbg!(aclass.clobber.get()), region, aclass.last_store.get()];
|
||||||
self.ci.nodes.new_node(ty, Kind::Load, vc)
|
self.ci.nodes.new_node(ty, Kind::Load, vc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2567,15 +2575,10 @@ impl<'a> Codegen<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ci.ctrl.set(
|
let ret = self.ci.nodes.new_node_nop(ty::Id::VOID, Kind::Return, inps);
|
||||||
self.ci.nodes.new_node_nop(ty::Id::VOID, Kind::Return, inps),
|
self.ci.ctrl.set(NEVER, &mut self.ci.nodes);
|
||||||
&mut self.ci.nodes,
|
self.ci.nodes[ret].pos = pos;
|
||||||
);
|
self.ci.nodes.bind(ret, NEVER);
|
||||||
|
|
||||||
self.ci.nodes[self.ci.ctrl.get()].pos = pos;
|
|
||||||
|
|
||||||
self.ci.nodes[NEVER].inputs.push(self.ci.ctrl.get());
|
|
||||||
self.ci.nodes[self.ci.ctrl.get()].outputs.push(NEVER);
|
|
||||||
} else if let Some((pv, ctrl, scope)) = &mut self.ci.inline_ret {
|
} else if let Some((pv, ctrl, scope)) = &mut self.ci.inline_ret {
|
||||||
ctrl.set(
|
ctrl.set(
|
||||||
self.ci
|
self.ci
|
||||||
|
@ -3164,6 +3167,7 @@ impl<'a> Codegen<'a> {
|
||||||
Loc::Reg => None,
|
Loc::Reg => None,
|
||||||
Loc::Stack => {
|
Loc::Stack => {
|
||||||
let stck = self.new_stack(func.pos(), sig.ret);
|
let stck = self.new_stack(func.pos(), sig.ret);
|
||||||
|
clobbered_aliases.set(self.ci.nodes.aclass_index(stck).0 as _);
|
||||||
inps.push(stck);
|
inps.push(stck);
|
||||||
Some(Value::ptr(stck).ty(sig.ret))
|
Some(Value::ptr(stck).ty(sig.ret))
|
||||||
}
|
}
|
||||||
|
@ -4638,6 +4642,7 @@ mod tests {
|
||||||
fb_driver;
|
fb_driver;
|
||||||
|
|
||||||
// Purely Testing Examples;
|
// Purely Testing Examples;
|
||||||
|
null_check_in_the_loop;
|
||||||
stack_provenance;
|
stack_provenance;
|
||||||
advanced_floating_point_arithmetic;
|
advanced_floating_point_arithmetic;
|
||||||
nullable_structure;
|
nullable_structure;
|
||||||
|
|
34
lang/tests/son_tests_null_check_in_the_loop.txt
Normal file
34
lang/tests/son_tests_null_check_in_the_loop.txt
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
main:
|
||||||
|
ADDI64 r254, r254, -38d
|
||||||
|
ST r31, r254, 6a, 32h
|
||||||
|
LI8 r32, 0b
|
||||||
|
ADDI64 r33, r254, 0d
|
||||||
|
2: JAL r31, r0, :return_fn
|
||||||
|
ST r1, r254, 0a, 6h
|
||||||
|
LD r34, r254, 0a, 1h
|
||||||
|
ANDI r34, r34, 255d
|
||||||
|
ANDI r32, r32, 255d
|
||||||
|
JEQ r34, r32, :0
|
||||||
|
LI64 r1, 1d
|
||||||
|
JMP :1
|
||||||
|
0: JMP :2
|
||||||
|
1: LD r31, r254, 6a, 32h
|
||||||
|
ADDI64 r254, r254, 38d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
return_fn:
|
||||||
|
ADDI64 r254, r254, -6d
|
||||||
|
LI8 r4, 1b
|
||||||
|
ADDI64 r3, r254, 0d
|
||||||
|
ST r4, r254, 0a, 1h
|
||||||
|
LI8 r4, 0b
|
||||||
|
ST r4, r254, 1a, 1h
|
||||||
|
ST r4, r254, 2a, 1h
|
||||||
|
ST r4, r254, 3a, 1h
|
||||||
|
ST r4, r254, 4a, 1h
|
||||||
|
ST r4, r254, 5a, 1h
|
||||||
|
LD r1, r3, 0a, 6h
|
||||||
|
ADDI64 r254, r254, 6d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 302
|
||||||
|
ret: 1
|
||||||
|
status: Ok(())
|
Loading…
Reference in a new issue