diff --git a/lang/src/son.rs b/lang/src/son.rs index b72539dc..1464b48f 100644 --- a/lang/src/son.rs +++ b/lang/src/son.rs @@ -27,6 +27,7 @@ use { }, hashbrown::hash_map, hbbytecode::DisasmError, + std::backtrace, }; const VOID: Nid = 0; @@ -443,6 +444,7 @@ impl Nodes { fn bind(&mut self, from: Nid, to: Nid) { debug_assert_ne!(to, 0); + debug_assert_ne!(self[to].kind, Kind::Phi); self[from].outputs.push(to); self[to].inputs.push(from); } @@ -714,6 +716,12 @@ impl Nodes { return false; } + if self[target].kind == (Kind::BinOp { op: TokenKind::Add }) + && self[target].ty == ty::Id::U8 + { + log::info!("{}", std::backtrace::Backtrace::capture()); + } + for i in 0..self[target].inputs.len() { let inp = self[target].inputs[i]; let index = self[inp].outputs.iter().position(|&p| p == target).unwrap(); @@ -1503,7 +1511,8 @@ impl Nodes { Kind::Load => write!(out, "load: "), Kind::Stre => write!(out, "stre: "), Kind::Mem => write!(out, " mem: "), - Kind::Loops => write!(out, " loops: "), + Kind::Loops => write!(out, "loops: "), + Kind::Join => write!(out, "join: "), }?; if self[node].kind != Kind::Loop && self[node].kind != Kind::Region { @@ -1850,6 +1859,8 @@ pub enum Kind { Load, // [ctrl, value, memory] Stre, + // [ctrl, a, b] + Join, } impl Kind { @@ -2474,11 +2485,15 @@ impl<'a> Codegen<'a> { ); let base_class = self.ci.scope.aclasses[0].last_store.get(); let last_store = self.ci.scope.aclasses[value_index].last_store.get(); - if base_class != MEM && last_store != MEM { - self.ci.nodes.bind(base_class, last_store); - } - if last_store != MEM { - self.ci.scope.aclasses[0].last_store.set(last_store, &mut self.ci.nodes); + match [base_class, last_store] { + [_, MEM] => {} + [MEM, a] => { + self.ci.scope.aclasses[0].last_store.set(a, &mut self.ci.nodes); + } + [a, b] => { + let a = self.ci.nodes.new_node_nop(ty::Id::VOID, Kind::Join, [0, a, b]); + self.ci.scope.aclasses[0].last_store.set(a, &mut self.ci.nodes); + } } } @@ -3649,7 +3664,11 @@ impl<'a> Codegen<'a> { dest_class.last_store.set(scope_class.last_store.get(), &mut self.ci.nodes); } - debug_assert!(!self.ci.nodes[dest_class.last_store.get()].is_lazy_phi(node)); + debug_assert!( + !self.ci.nodes[dest_class.last_store.get()].is_lazy_phi(node), + "{:?}", + self.ci.nodes[dest_class.last_store.get()] + ); } scope.clear(&mut self.ci.nodes); diff --git a/lang/src/son/hbvm/my_regalloc.rs b/lang/src/son/hbvm/my_regalloc.rs index 9a38e1c9..fe8d87cc 100644 --- a/lang/src/son/hbvm/my_regalloc.rs +++ b/lang/src/son/hbvm/my_regalloc.rs @@ -468,6 +468,7 @@ impl HbvmBackend { | Kind::Then | Kind::Else | Kind::Phi + | Kind::Join | Kind::Assert { .. }) => unreachable!("{e:?}"), } } @@ -731,7 +732,7 @@ impl<'a> Function<'a> { | Kind::Load { .. } | Kind::Stre | Kind::Stck => self.add_instr(nid), - Kind::End | Kind::Phi | Kind::Arg | Kind::Mem | Kind::Loops => {} + Kind::End | Kind::Phi | Kind::Arg | Kind::Mem | Kind::Loops | Kind::Join => {} Kind::Assert { .. } => unreachable!(), } } diff --git a/lang/src/son/hbvm/their_regalloc.rs b/lang/src/son/hbvm/their_regalloc.rs index d0f1ca85..a4e36f03 100644 --- a/lang/src/son/hbvm/their_regalloc.rs +++ b/lang/src/son/hbvm/their_regalloc.rs @@ -431,7 +431,8 @@ impl HbvmBackend { | Kind::Then | Kind::Else | Kind::Phi - | Kind::Arg => unreachable!(), + | Kind::Arg + | Kind::Join => unreachable!(), } } } @@ -835,7 +836,7 @@ impl<'a> Function<'a> { self.add_instr(nid, ops); } Kind::Assert { .. } => unreachable!(), - Kind::End | Kind::Phi | Kind::Arg | Kind::Mem | Kind::Loops => {} + Kind::End | Kind::Phi | Kind::Arg | Kind::Mem | Kind::Loops | Kind::Join => {} Kind::Load { .. } => { let mut region = node.inputs[1]; if self.nodes[region].kind == (Kind::BinOp { op: TokenKind::Add })