some cleanump and ironing out bugs in new regalloc

This commit is contained in:
Jakub Doka 2024-11-15 12:04:05 +01:00
parent 81cf39b602
commit bb625a9e19
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
5 changed files with 39 additions and 43 deletions

View file

@ -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)

View file

@ -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())),
);
}
}

View file

@ -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<u64> {
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),
))
}

View file

@ -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);
});

View file

@ -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);
}