From bb625a9e19bacae8fd9a81288783fcf685756c00 Mon Sep 17 00:00:00 2001 From: Jakub Doka Date: Fri, 15 Nov 2024 12:04:05 +0100 Subject: [PATCH] some cleanump and ironing out bugs in new regalloc --- lang/src/lib.rs | 2 +- lang/src/son.rs | 5 +--- lang/src/son/hbvm.rs | 44 ++++++++++++++++------------- lang/src/son/hbvm/my_regalloc.rs | 21 ++++++-------- lang/src/son/hbvm/their_regalloc.rs | 10 +++---- 5 files changed, 39 insertions(+), 43 deletions(-) diff --git a/lang/src/lib.rs b/lang/src/lib.rs index fa5488f6..0840863a 100644 --- a/lang/src/lib.rs +++ b/lang/src/lib.rs @@ -1106,7 +1106,7 @@ trait TypeParser { files: &[parser::Ast], ) -> ty::Id { match *expr { - Expr::Mod { id, .. } => ty::Kind::Module(id).compress(), + Expr::Mod { id, .. } => id.into(), Expr::UnOp { op: TokenKind::Xor, val, .. } => { let base = self.parse_ty(file, val, None, files); self.tys().make_ptr(base) diff --git a/lang/src/son.rs b/lang/src/son.rs index 24d65c08..8f0c38f2 100644 --- a/lang/src/son.rs +++ b/lang/src/son.rs @@ -4064,10 +4064,7 @@ impl<'a> Codegen<'a> { if !self.struct_op(pos, op, is, dst, lhs, rhs) { self.report( pos, - fa!( - "... when appliing '{0} {op} {0}'", - self.ty_display(ty::Kind::Struct(s).compress()) - ), + fa!("... when appliing '{0} {op} {0}'", self.ty_display(s.into())), ); } } diff --git a/lang/src/son/hbvm.rs b/lang/src/son/hbvm.rs index e5266e49..c7dbf766 100644 --- a/lang/src/son/hbvm.rs +++ b/lang/src/son/hbvm.rs @@ -104,7 +104,7 @@ impl Backend for HbvmBackend { self.globals.shadow(types.ins.globals.len()); - self.asm.frontier.push(ty::Kind::Func(from).compress()); + self.asm.frontier.push(from.into()); while let Some(itm) = self.asm.frontier.pop() { match itm.expand() { ty::Kind::Func(func) => { @@ -341,6 +341,14 @@ impl Backend for HbvmBackend { } impl Nodes { + fn cond_op(&self, cnd: Nid) -> CondRet { + let Kind::BinOp { op } = self[cnd].kind else { return None }; + if self[cnd].lock_rc == 0 { + return None; + } + op.cond_op(self[self[cnd].inputs[1]].ty) + } + fn strip_offset(&self, region: Nid, ty: ty::Id, tys: &Types) -> (Nid, Offset) { if matches!(self[region].kind, Kind::BinOp { op: TokenKind::Add | TokenKind::Sub }) && self[region].lock_rc != 0 @@ -493,9 +501,7 @@ impl HbvmBackend { match node.kind { Kind::If => { let &[_, cnd] = node.inputs.as_slice() else { unreachable!() }; - if let Kind::BinOp { op } = nodes[cnd].kind - && let Some((op, swapped)) = op.cond_op(nodes[nodes[cnd].inputs[1]].ty) - { + if let Some((op, swapped)) = nodes.cond_op(cnd) { let &[lhs, rhs] = allocs else { unreachable!() }; let &[_, lh, rh] = nodes[cnd].inputs.as_slice() else { unreachable!() }; @@ -584,7 +590,6 @@ impl HbvmBackend { let &[dst, oper] = allocs else { unreachable!() }; self.emit(op(dst, oper)); } - Kind::BinOp { .. } if node.lock_rc != 0 => {} Kind::BinOp { op } => { let &[.., lh, rh] = node.inputs.as_slice() else { unreachable!() }; @@ -649,7 +654,7 @@ impl HbvmBackend { self.emit(instrs::eca()); } else { self.relocs.push(TypedReloc { - target: ty::Kind::Func(func).compress(), + target: func.into(), reloc: Reloc::new(self.code.len(), 3, 4), }); self.emit(instrs::jal(reg::RET_ADDR, reg::ZERO, 0)); @@ -663,7 +668,7 @@ impl HbvmBackend { } Kind::Global { global } => { let reloc = Reloc::new(self.code.len(), 3, 4); - self.relocs.push(TypedReloc { target: ty::Kind::Global(global).compress(), reloc }); + self.relocs.push(TypedReloc { target: global.into(), reloc }); self.emit(instrs::lra(allocs[0], 0, 0)); } Kind::Stck => { @@ -724,12 +729,14 @@ impl Node { } } +type CondRet = Option<(fn(u8, u8, i16) -> EncodedInstr, bool)>; + impl TokenKind { fn cmp_against(self) -> Option { Some(match self { - TokenKind::Le | TokenKind::Gt => 1, - TokenKind::Ne | TokenKind::Eq => 0, - TokenKind::Ge | TokenKind::Lt => (-1i64) as _, + Self::Le | Self::Gt => 1, + Self::Ne | Self::Eq => 0, + Self::Ge | Self::Lt => (-1i64) as _, _ => return None, }) } @@ -741,22 +748,21 @@ impl TokenKind { let size = ty.simple_size().unwrap(); let ops = match self { - TokenKind::Gt => [instrs::fcmpgt32, instrs::fcmpgt64], - TokenKind::Lt => [instrs::fcmplt32, instrs::fcmplt64], + Self::Gt => [instrs::fcmpgt32, instrs::fcmpgt64], + Self::Lt => [instrs::fcmplt32, instrs::fcmplt64], _ => return None, }; Some(ops[size.ilog2() as usize - 2]) } - #[expect(clippy::type_complexity)] - fn cond_op(self, ty: ty::Id) -> Option<(fn(u8, u8, i16) -> EncodedInstr, bool)> { - if ty.is_float() { - return None; - } + fn cond_op(self, ty: ty::Id) -> CondRet { let signed = ty.is_signed(); Some(( match self { + Self::Eq => instrs::jne, + Self::Ne => instrs::jeq, + _ if ty.is_float() => return None, Self::Le if signed => instrs::jgts, Self::Le => instrs::jgtu, Self::Lt if signed => instrs::jlts, @@ -765,11 +771,9 @@ impl TokenKind { Self::Ge => instrs::jltu, Self::Gt if signed => instrs::jgts, Self::Gt => instrs::jgtu, - Self::Eq => instrs::jne, - Self::Ne => instrs::jeq, _ => return None, }, - matches!(self, Self::Lt | TokenKind::Gt), + matches!(self, Self::Lt | Self::Gt), )) } diff --git a/lang/src/son/hbvm/my_regalloc.rs b/lang/src/son/hbvm/my_regalloc.rs index 8e8882c0..60ed0210 100644 --- a/lang/src/son/hbvm/my_regalloc.rs +++ b/lang/src/son/hbvm/my_regalloc.rs @@ -127,9 +127,7 @@ impl HbvmBackend { match node.kind { Kind::If => { let &[_, cnd] = node.inputs.as_slice() else { unreachable!() }; - if let Kind::BinOp { op } = fuc.nodes[cnd].kind - && op.cond_op(fuc.nodes[fuc.nodes[cnd].inputs[1]].ty).is_some() - { + if fuc.nodes.cond_op(cnd).is_some() { let &[_, lh, rh] = fuc.nodes[cnd].inputs.as_slice() else { unreachable!() }; @@ -475,12 +473,10 @@ impl<'a> Function<'a> { self.emit_node(node.outputs[0]) } Kind::If => { - let &[_, cond] = node.inputs.as_slice() else { unreachable!() }; + let &[_, cnd] = node.inputs.as_slice() else { unreachable!() }; let &[mut then, mut else_] = node.outputs.as_slice() else { unreachable!() }; - if let Kind::BinOp { op } = self.nodes[cond].kind - && let Some((_, swapped)) = op.cond_op(node.ty) - { + if let Some((_, swapped)) = self.nodes.cond_op(cnd) { if swapped { mem::swap(&mut then, &mut else_); } @@ -506,6 +502,11 @@ impl<'a> Function<'a> { } Kind::Entry => { let (ret, mut parama) = self.tys.parama(self.sig.ret); + + if let Some(PLoc::Ref(..)) = ret { + self.add_instr(MEM); + } + let mut typs = self.sig.args.args(); #[expect(clippy::unnecessary_to_owned)] let mut args = self.nodes[VOID].outputs[ARG_START..].to_owned().into_iter(); @@ -518,10 +519,6 @@ impl<'a> Function<'a> { } } - if let Some(PLoc::Ref(..)) = ret { - self.add_instr(MEM); - } - self.nodes.reschedule_block(nid, &mut node.outputs); for o in node.outputs.into_iter().rev() { self.emit_node(o); @@ -649,7 +646,7 @@ impl<'a> Env<'a> { ); range.end = new; - debug_assert!(range.start < range.end, "{:?}", range); + debug_assert!(range.start < range.end, "{:?} {inst} {uinst}", range); bundle.add(range); }); diff --git a/lang/src/son/hbvm/their_regalloc.rs b/lang/src/son/hbvm/their_regalloc.rs index 6483b43c..1df72008 100644 --- a/lang/src/son/hbvm/their_regalloc.rs +++ b/lang/src/son/hbvm/their_regalloc.rs @@ -332,21 +332,19 @@ impl<'a> Function<'a> { Kind::If => { self.backrefs[nid as usize] = self.backrefs[prev as usize]; - let &[_, cond] = node.inputs.as_slice() else { unreachable!() }; + let &[_, cnd] = node.inputs.as_slice() else { unreachable!() }; let &[mut then, mut else_] = node.outputs.as_slice() else { unreachable!() }; - if let Kind::BinOp { op } = self.nodes[cond].kind - && let Some((_, swapped)) = op.cond_op(node.ty) - { + if let Some((_, swapped)) = self.nodes.cond_op(cnd) { if swapped { mem::swap(&mut then, &mut else_); } - let &[_, lhs, rhs] = self.nodes[cond].inputs.as_slice() else { unreachable!() }; + let &[_, lhs, rhs] = self.nodes[cnd].inputs.as_slice() else { unreachable!() }; let ops = vec![self.urg(lhs), self.urg(rhs)]; self.add_instr(nid, ops); } else { mem::swap(&mut then, &mut else_); - let ops = vec![self.urg(cond)]; + let ops = vec![self.urg(cnd)]; self.add_instr(nid, ops); }