diff --git a/lang/README.md b/lang/README.md index 86c3c0c..7c98762 100644 --- a/lang/README.md +++ b/lang/README.md @@ -1003,9 +1003,10 @@ clobber := fn(cb: ^int): void { #### conditional_stores ```hb main := fn(): int { + cnd := cond() mem := &1 - if cond() == 0 { + if cnd == 0 { *mem = 0 } else { *mem = 2 @@ -1016,3 +1017,16 @@ main := fn(): int { cond := fn(): int return 0 ``` + +#### loop_stores +```hb +main := fn(): int { + mem := &10 + + loop if *mem == 0 break else { + *mem -= 1 + } + + return *mem +} +``` diff --git a/lang/src/son.rs b/lang/src/son.rs index 83c7435..8573168 100644 --- a/lang/src/son.rs +++ b/lang/src/son.rs @@ -310,6 +310,7 @@ impl Nodes { if self[target].inputs[2] != VOID && self[target].inputs.len() == 4 && self[self[target].inputs[3]].kind == Kind::Stre + && self[self[target].inputs[3]].lock_rc == 0 && self[self[target].inputs[3]].inputs[2] == self[target].inputs[2] { return Some(self.modify_input( @@ -1505,6 +1506,17 @@ impl Codegen { self.ci.nodes.unlock_remove(scope_var.value.id); } + if bres.store != scope.store { + let (to_store, from_store) = (bres.store.unwrap(), scope.store.unwrap()); + self.ci.nodes.unlock(to_store); + bres.store = Some( + self.ci + .nodes + .new_node(ty::Id::VOID, Kind::Phi, [node, from_store, to_store]), + ); + self.ci.nodes.lock(bres.store.unwrap()); + } + self.ci.nodes.unlock_remove_scope(&scope); self.ci.nodes.unlock_remove_scope(&bres); @@ -1538,7 +1550,11 @@ impl Codegen { } } - let mut else_scope = self.ci.scope.clone(); + let orig_store = self.ci.scope.store; + if let Some(str) = orig_store { + self.ci.nodes.lock(str); + } + let else_scope = self.ci.scope.clone(); self.ci.nodes.lock_scope(&else_scope); self.ci.ctrl = self.ci.nodes.new_node(ty::Id::VOID, Kind::Then, [if_node]); @@ -1552,6 +1568,10 @@ impl Codegen { self.ci.ctrl }; + if let Some(str) = orig_store { + self.ci.nodes.unlock_remove(str); + } + if lcntrl == Nid::MAX && rcntrl == Nid::MAX { self.ci.nodes.unlock_remove_scope(&then_scope); return None; @@ -1567,19 +1587,15 @@ impl Codegen { self.ci.ctrl = self.ci.nodes.new_node(ty::Id::VOID, Kind::Region, [lcntrl, rcntrl]); - else_scope = core::mem::take(&mut self.ci.scope); - Self::merge_scopes( &mut self.ci.nodes, &mut self.ci.loops, self.ci.ctrl, - &mut else_scope, + &mut self.ci.scope, &mut then_scope, true, ); - self.ci.scope = else_scope; - Some(Value::VOID) } ref e => { @@ -2972,5 +2988,6 @@ mod tests { //wide_ret; pointer_opts; conditional_stores; + loop_stores; } } diff --git a/lang/tests/son_tests_conditional_stores.txt b/lang/tests/son_tests_conditional_stores.txt index 9d9b5e4..f551c45 100644 --- a/lang/tests/son_tests_conditional_stores.txt +++ b/lang/tests/son_tests_conditional_stores.txt @@ -2,23 +2,21 @@ cond: LI64 r1, 0d JALA r0, r31, 0a main: - ADDI64 r254, r254, -48d - ST r31, r254, 8a, 40h - LI64 r32, 1d - ADDI64 r33, r254, 0d - ST r32, r254, 0a, 8h + ADDI64 r254, r254, -32d + ST r31, r254, 8a, 24h JAL r31, r0, :cond - LI64 r34, 0d - CP r35, r34 - JNE r1, r35, :0 - CP r34, r35 - CP r1, r34 + LI64 r32, 0d + CP r33, r32 + JNE r1, r33, :0 + CP r32, r33 + CP r1, r32 JMP :1 0: LI64 r1, 2d - 1: ST r1, r254, 0a, 8h - LD r31, r254, 8a, 40h - ADDI64 r254, r254, 48d + 1: ADDI64 r33, r254, 0d + ST r1, r254, 0a, 8h + LD r31, r254, 8a, 24h + ADDI64 r254, r254, 32d JALA r0, r31, 0a -code size: 181 +code size: 158 ret: 0 status: Ok(()) diff --git a/lang/tests/son_tests_loop_stores.txt b/lang/tests/son_tests_loop_stores.txt new file mode 100644 index 0000000..e69de29