diff --git a/lang/src/son.rs b/lang/src/son.rs index 62ed383d..b2dd1b21 100644 --- a/lang/src/son.rs +++ b/lang/src/son.rs @@ -9,7 +9,7 @@ use { idfl::{self}, CtorField, Expr, FileId, Pos, }, - reg, task, + task, ty::{self, Arg, ArrayLen, Loc, Tuple}, vc::{BitSet, Vc}, FTask, Func, Global, Ident, Offset, OffsetIter, Reloc, Sig, StringRef, SymKey, TypeParser, @@ -857,7 +857,7 @@ impl Nodes { } } K::Stre => { - if self[target].inputs[2] != VOID + if self[target].inputs[1] != VOID && self[target].inputs.len() == 4 && self[self[target].inputs[1]].kind != Kind::Load && self[self[target].inputs[3]].kind == Kind::Stre @@ -1312,6 +1312,9 @@ impl Nodes { } } + // self[first_store].lock_rc = u16::MAX - 1; + // self[last_store].lock_rc = u16::MAX - 1; + let prev_store = self[dst].inputs[3]; if prev_store != MEM && first_store != MEM { self.modify_input(first_store, 3, prev_store); @@ -1973,6 +1976,13 @@ impl<'a> Codegen<'a> { .collect(); } + fn new_stack(&mut self, ty: ty::Id) -> Nid { + let stck = self.ci.nodes.new_node_nop(ty, Kind::Stck, [VOID, MEM]); + self.ci.nodes[stck].aclass = self.ci.scope.aclasses.len(); + self.ci.scope.aclasses.push(AClass::new(&mut self.ci.nodes)); + stck + } + fn store_mem(&mut self, region: Nid, ty: ty::Id, value: Nid) -> Nid { if value == NEVER { return NEVER; @@ -2029,7 +2039,11 @@ impl<'a> Codegen<'a> { pub fn aclass_index(&mut self, mut region: Nid) -> usize { loop { region = match self.ci.nodes[region].kind { - Kind::BinOp { op: TokenKind::Add | TokenKind::Sub } | Kind::Phi => { + Kind::BinOp { op: TokenKind::Add | TokenKind::Sub } => { + self.ci.nodes[region].inputs[1] + } + Kind::Phi => { + debug_assert_eq!(self.ci.nodes[region].inputs[2], 0); self.ci.nodes[region].inputs[1] } _ => break self.ci.nodes[region].aclass, @@ -2099,8 +2113,7 @@ impl<'a> Codegen<'a> { inference!(ty, ctx, self, pos, "value", "@as(, idk)"); if matches!(ty.expand(), ty::Kind::Struct(_) | ty::Kind::Slice(_)) { - let stck = self.ci.nodes.new_node(ty, Kind::Stck, [VOID, MEM]); - Some(Value::ptr(stck).ty(ty)) + Some(Value::ptr(self.new_stack(ty)).ty(ty)) } else { self.report( pos, @@ -2127,7 +2140,7 @@ impl<'a> Codegen<'a> { if let Some(index) = self.ci.scope.vars.iter().rposition(|v| v.id == id) => { let var = &mut self.ci.scope.vars[index]; - self.ci.nodes.load_loop_var(index + 1, var, &mut self.ci.loops); + self.ci.nodes.load_loop_var(index, var, &mut self.ci.loops); Some(Value::var(index).ty(var.ty)) } @@ -2290,7 +2303,7 @@ impl<'a> Codegen<'a> { return Some(val); } - let stack = self.ci.nodes.new_node_nop(val.ty, Kind::Stck, [VOID, MEM]); + let stack = self.new_stack(val.ty); self.store_mem(stack, val.ty, val.id); Some(Value::new(stack).ty(self.tys.make_ptr(val.ty))) @@ -2322,7 +2335,7 @@ impl<'a> Codegen<'a> { let mut right = self.expr(right)?; if right.ty.loc(self.tys) == Loc::Stack { - let stck = self.ci.nodes.new_node_nop(right.ty, Kind::Stck, [VOID, MEM]); + let stck = self.new_stack(right.ty); self.store_mem(stck, right.ty, right.id); right.id = stck; right.ptr = true; @@ -2379,7 +2392,7 @@ impl<'a> Codegen<'a> { let mut rhs = rhs?; self.strip_var(&mut rhs); self.assert_ty(pos, &mut rhs, lhs.ty, "struct operand"); - let dst = self.ci.nodes.new_node(lhs.ty, Kind::Stck, [VOID, MEM]); + let dst = self.new_stack(lhs.ty); self.struct_op(left.pos(), op, s, dst, lhs.id, rhs.id); Some(Value::ptr(dst).ty(lhs.ty)) } @@ -2468,7 +2481,7 @@ impl<'a> Codegen<'a> { match ty.loc(self.tys) { Loc::Reg if mem::take(&mut val.ptr) => val.id = self.load_mem(val.id, ty), Loc::Stack if !val.ptr => { - let stack = self.ci.nodes.new_node_nop(ty, Kind::Stck, [VOID, MEM]); + let stack = self.new_stack(ty); self.store_mem(stack, val.ty, val.id); val.id = stack; val.ptr = true; @@ -2525,7 +2538,6 @@ impl<'a> Codegen<'a> { let mut inps = Vc::from([NEVER]); let arg_base = self.tys.tmp.args.len(); - let mut has_ptr_arg = false; let mut clobbered_aliases = vec![]; for arg in args { let value = self.expr(arg)?; @@ -2568,7 +2580,7 @@ impl<'a> Codegen<'a> { let alt_value = match ty.loc(self.tys) { Loc::Reg => None, Loc::Stack => { - let stck = self.ci.nodes.new_node_nop(ty, Kind::Stck, [VOID, MEM]); + let stck = self.new_stack(ty); inps.push(stck); Some(Value::ptr(stck).ty(ty)) } @@ -2580,6 +2592,14 @@ impl<'a> Codegen<'a> { &mut self.ci.nodes, ); + for &clobbered in clobbered_aliases.iter() { + if clobbered == 0 { + continue; + } + let aclass = self.ci.scope.aclasses[clobbered].last_store.get(); + self.store_mem(self.ci.nodes[aclass].inputs[2], ty::Id::VOID, VOID); + } + alt_value.or(Some(Value::new(self.ci.ctrl.get()).ty(ty))) } Expr::Call { func, args, .. } => { @@ -2618,7 +2638,6 @@ impl<'a> Codegen<'a> { let mut tys = sig.args.args(); let mut cargs = cargs.iter(); let mut args = args.iter(); - let mut has_ptr_arg = false; let mut clobbered_aliases = vec![]; while let Some(ty) = tys.next(self.tys) { let carg = cargs.next().unwrap(); @@ -2665,7 +2684,7 @@ impl<'a> Codegen<'a> { let alt_value = match sig.ret.loc(self.tys) { Loc::Reg => None, Loc::Stack => { - let stck = self.ci.nodes.new_node_nop(sig.ret, Kind::Stck, [VOID, MEM]); + let stck = self.new_stack(sig.ret); inps.push(stck); Some(Value::ptr(stck).ty(sig.ret)) } @@ -2677,6 +2696,14 @@ impl<'a> Codegen<'a> { &mut self.ci.nodes, ); + for &clobbered in clobbered_aliases.iter() { + if clobbered == 0 { + continue; + } + let aclass = self.ci.scope.aclasses[clobbered].last_store.get(); + self.store_mem(self.ci.nodes[aclass].inputs[2], ty::Id::VOID, VOID); + } + alt_value.or(Some(Value::new(self.ci.ctrl.get()).ty(sig.ret))) } Expr::Directive { name: "inline", args: [func, args @ ..], .. } => { @@ -2794,7 +2821,7 @@ impl<'a> Codegen<'a> { match sty.expand() { ty::Kind::Struct(s) => { - let mem = self.ci.nodes.new_node(sty, Kind::Stck, [VOID, MEM]); + let mem = self.new_stack(sty); let mut offs = OffsetIter::new(s, self.tys); for field in fields { let Some((ty, offset)) = offs.next_ty(self.tys) else { @@ -2848,7 +2875,7 @@ impl<'a> Codegen<'a> { return Value::NEVER; } - let mem = self.ci.nodes.new_node(aty, Kind::Stck, [VOID, MEM]); + let mem = self.new_stack(aty); for (field, offset) in fields.iter().zip((0u32..).step_by(elem_size as usize)) @@ -2901,7 +2928,7 @@ impl<'a> Codegen<'a> { .into_iter(self.tys) .map(|(f, o)| (f.ty, o)) .collect::>(); - let mem = self.ci.nodes.new_node(sty, Kind::Stck, [VOID, MEM]); + let mem = self.new_stack(sty); for field in fields { let Some(index) = self.tys.find_struct_field(s, field.name) else { self.report( @@ -3514,6 +3541,10 @@ impl<'a> Codegen<'a> { value, &mut self.ci.nodes, )); + if ty.loc(self.tys) == Loc::Stack { + self.ci.nodes[value].aclass = self.ci.scope.aclasses.len(); + self.ci.scope.aclasses.push(AClass::new(&mut self.ci.nodes)); + } } } } diff --git a/lang/src/son/hbvm.rs b/lang/src/son/hbvm.rs index d6932efd..74df48cf 100644 --- a/lang/src/son/hbvm.rs +++ b/lang/src/son/hbvm.rs @@ -423,7 +423,7 @@ impl ItemCtx { self.emit(instrs::ld(atr(allocs[0]), base, offset as _, size as _)); } } - Kind::Stre if node.inputs[2] == VOID => {} + Kind::Stre if node.inputs[1] == VOID => {} Kind::Stre => { let mut region = node.inputs[2]; let mut offset = 0; @@ -987,7 +987,7 @@ impl<'a> Function<'a> { }; self.add_instr(nid, ops); } - Kind::Stre if node.inputs[2] == VOID => self.nodes.lock(nid), + Kind::Stre if node.inputs[1] == VOID => self.nodes.lock(nid), Kind::Stre => { let mut region = node.inputs[2]; if self.nodes[region].kind == (Kind::BinOp { op: TokenKind::Add }) diff --git a/lang/tests/son_tests_string_flip.txt b/lang/tests/son_tests_string_flip.txt index c7efb893..596dfc3e 100644 --- a/lang/tests/son_tests_string_flip.txt +++ b/lang/tests/son_tests_string_flip.txt @@ -1,44 +1,42 @@ main: - ADDI64 r254, r254, -40d - LI64 r6, 4d - LI64 r7, 1d + ADDI64 r254, r254, -32d + LI64 r6, 1d + LI64 r7, 4d LI64 r4, 0d ADDI64 r5, r254, 0d CP r8, r4 - 6: JNE r8, r6, :0 - LI64 r6, 2d - ADDI64 r1, r254, 32d + 6: JNE r8, r7, :0 + LI64 r7, 2d CP r8, r4 - 4: JNE r8, r7, :1 + 4: JNE r8, r6, :1 LD r1, r254, 0a, 8h JMP :2 - 1: MUL64 r11, r8, r6 - ADD64 r8, r8, r7 - SUB64 r9, r6, r8 - MUL64 r9, r9, r6 + 1: MUL64 r10, r8, r7 + ADD64 r8, r8, r6 + SUB64 r3, r7, r8 + MUL64 r9, r3, r7 CP r2, r4 - 5: JNE r2, r6, :3 + 5: JNE r2, r7, :3 JMP :4 - 3: ADD64 r3, r2, r7 - ADD64 r10, r11, r2 - MULI64 r10, r10, 8d - ADD64 r2, r9, r2 - ADD64 r10, r5, r10 - MULI64 r12, r2, 8d + 3: ADD64 r1, r2, r6 + ADD64 r11, r10, r2 + ADD64 r12, r9, r2 + MULI64 r2, r11, 8d + MULI64 r12, r12, 8d + ADD64 r11, r5, r2 ADD64 r12, r5, r12 - BMC r10, r1, 8h - BMC r12, r10, 8h - BMC r1, r12, 8h - CP r2, r3 + BMC r12, r11, 8h + BMC r11, r12, 8h + CP r2, r1 JMP :5 - 0: ADD64 r1, r8, r7 - MULI64 r12, r8, 8d - ADD64 r9, r5, r12 + 0: ADD64 r11, r8, r6 + MULI64 r10, r8, 8d + ADD64 r9, r5, r10 ST r8, r9, 0a, 8h - CP r8, r1 + CP r8, r11 JMP :6 - 2: ADDI64 r254, r254, 40d + 2: ADDI64 r254, r254, 32d JALA r0, r31, 0a -code size: 271 +code size: 255 ret: 2 status: Ok(()) diff --git a/lang/tests/son_tests_struct_operators.txt b/lang/tests/son_tests_struct_operators.txt index 236d7522..6e549a6d 100644 --- a/lang/tests/son_tests_struct_operators.txt +++ b/lang/tests/son_tests_struct_operators.txt @@ -1,113 +1,99 @@ main: - ADDI64 r254, r254, -168d + ADDI64 r254, r254, -152d LI8 r1, 0b + LI8 r3, 1b ST r1, r254, 148a, 1h + ST r3, r254, 144a, 1h ST r1, r254, 149a, 1h + ST r3, r254, 145a, 1h ST r1, r254, 150a, 1h + ST r3, r254, 146a, 1h ST r1, r254, 151a, 1h - LI8 r7, 1b - ST r7, r254, 144a, 1h - ST r7, r254, 145a, 1h - ST r7, r254, 146a, 1h - ST r7, r254, 147a, 1h - LD r2, r254, 144a, 1h - LD r3, r254, 148a, 1h - ADD8 r5, r2, r3 + ST r3, r254, 147a, 1h + LD r1, r254, 148a, 1h + LD r4, r254, 144a, 1h + ADD8 r5, r4, r1 + LD r8, r254, 145a, 1h + LD r9, r254, 149a, 1h ST r5, r254, 148a, 1h - LD r9, r254, 145a, 1h - LD r10, r254, 149a, 1h - ADD8 r12, r10, r9 - ST r12, r254, 149a, 1h + ADD8 r12, r9, r8 LD r4, r254, 146a, 1h LD r5, r254, 150a, 1h + ST r12, r254, 149a, 1h ADD8 r7, r5, r4 ST r7, r254, 150a, 1h - LD r11, r254, 147a, 1h - LD r12, r254, 151a, 1h - ADD8 r2, r12, r11 - ST r2, r254, 151a, 1h - LD r6, r254, 149a, 1h - LD r7, r254, 150a, 1h - ADD8 r9, r7, r6 - LD r11, r254, 148a, 1h - ADD8 r1, r11, r9 - LI8 r3, 4b - ADD8 r6, r1, r2 - ANDI r6, r6, 255d - ANDI r3, r3, 255d - JEQ r6, r3, :0 + ST r3, r254, 151a, 1h + LD r12, r254, 149a, 1h + LD r1, r254, 150a, 1h + ADD8 r4, r1, r12 + LD r5, r254, 148a, 1h + ADD8 r7, r5, r4 + LI8 r9, 4b + ADD8 r1, r7, r3 + ANDI r1, r1, 255d + ANDI r9, r9, 255d + JEQ r1, r9, :0 LI64 r1, 1008d JMP :1 - 0: LI64 r10, 1d - ADDI64 r1, r254, 80d - ST r10, r254, 80a, 8h - LI64 r2, 2d - ST r2, r254, 88a, 8h - LI64 r6, 3d - ST r6, r254, 32a, 8h - LI64 r9, 4d - ST r9, r254, 40a, 8h - LD r3, r254, 32a, 8h - LD r4, r254, 80a, 8h - ADDI64 r2, r254, 0d - ADD64 r6, r3, r4 - ST r6, r254, 0a, 8h - LD r10, r254, 40a, 8h - LD r11, r254, 88a, 8h - ADD64 r3, r10, r11 - ST r3, r254, 8a, 8h - LD r5, r254, 80a, 8h - LD r6, r254, 32a, 8h - SUB64 r8, r6, r5 - ST r8, r254, 16a, 8h - LD r12, r254, 88a, 8h - LD r3, r254, 40a, 8h - SUB64 r3, r3, r12 - ST r3, r254, 24a, 8h - ADDI64 r6, r254, 112d - BMC r2, r6, 32h - LI64 r9, 0d - ST r9, r254, 96a, 8h - ST r9, r254, 104a, 8h - LD r2, r254, 32a, 8h - LD r3, r254, 96a, 8h - ADDI64 r9, r254, 48d - SUB64 r6, r3, r2 - ST r6, r254, 48a, 8h - LD r10, r254, 40a, 8h - LD r11, r254, 104a, 8h - SUB64 r2, r11, r10 - ST r2, r254, 56a, 8h - ADDI64 r11, r9, 16d - BMC r1, r11, 16h - LD r8, r254, 112a, 8h - LD r9, r254, 48a, 8h - ADD64 r11, r9, r8 - ST r11, r254, 48a, 8h - LD r3, r254, 120a, 8h - LD r4, r254, 56a, 8h - ADD64 r6, r3, r4 - ST r6, r254, 56a, 8h - LD r11, r254, 128a, 8h - LD r12, r254, 64a, 8h - ADD64 r2, r11, r12 + 0: LI64 r6, 1d + ADDI64 r5, r254, 112d + ST r6, r254, 112a, 8h + LI64 r9, 2d + ST r9, r254, 120a, 8h + LI64 r2, 3d + ADDI64 r1, r254, 96d ST r2, r254, 64a, 8h - LD r6, r254, 136a, 8h - LD r7, r254, 72a, 8h - ADD64 r9, r6, r7 - ST r9, r254, 72a, 8h + LI64 r6, 4d + LI64 r2, 0d + BMC r5, r1, 16h + ST r6, r254, 72a, 8h + ST r2, r254, 80a, 8h + LD r11, r254, 96a, 8h LD r1, r254, 64a, 8h - LD r2, r254, 48a, 8h - ADD64 r4, r1, r2 - ST r4, r254, 152a, 8h - LD r8, r254, 72a, 8h - LD r9, r254, 56a, 8h - ADD64 r11, r8, r9 - ST r11, r254, 160a, 8h - LD r2, r254, 152a, 8h - ADD64 r1, r2, r11 - 1: ADDI64 r254, r254, 168d + ST r2, r254, 88a, 8h + ADD64 r4, r1, r11 + LD r7, r254, 104a, 8h + LD r2, r254, 80a, 8h + ST r4, r254, 32a, 8h + ADD64 r12, r7, r6 + SUB64 r3, r2, r1 + ADDI64 r8, r254, 0d + ST r12, r254, 40a, 8h + SUB64 r2, r1, r11 + ST r3, r254, 0a, 8h + LI64 r9, -4d + ST r2, r254, 48a, 8h + SUB64 r7, r6, r7 + ST r9, r254, 8a, 8h + ADDI64 r8, r8, 16d + ST r7, r254, 56a, 8h + BMC r5, r8, 16h + LD r6, r254, 32a, 8h + LD r8, r254, 0a, 8h + ADD64 r9, r8, r6 + LD r11, r254, 8a, 8h + LD r1, r254, 40a, 8h + ST r9, r254, 0a, 8h + ADD64 r4, r1, r11 + LD r8, r254, 16a, 8h + LD r9, r254, 48a, 8h + ST r4, r254, 8a, 8h + ADD64 r12, r9, r8 + LD r2, r254, 24a, 8h + ST r12, r254, 16a, 8h + ADD64 r12, r2, r7 + ST r12, r254, 24a, 8h + LD r7, r254, 0a, 8h + LD r9, r254, 16a, 8h + ADD64 r11, r9, r7 + LD r1, r254, 8a, 8h + ST r11, r254, 128a, 8h + ADD64 r6, r1, r12 + ST r6, r254, 136a, 8h + LD r7, r254, 128a, 8h + ADD64 r1, r7, r6 + 1: ADDI64 r254, r254, 152d JALA r0, r31, 0a -code size: 1145 +code size: 980 ret: 10 status: Ok(()) diff --git a/lang/tests/son_tests_structs.txt b/lang/tests/son_tests_structs.txt index cf07d776..87d2a201 100644 --- a/lang/tests/son_tests_structs.txt +++ b/lang/tests/son_tests_structs.txt @@ -6,13 +6,13 @@ main: ST r2, r254, 32a, 8h LI64 r33, 3d ST r33, r254, 40a, 8h - ADDI64 r34, r254, 16d + ADDI64 r34, r254, 0d LD r3, r32, 0a, 16h JAL r31, r0, :odher_pass - ST r1, r254, 16a, 16h - ADDI64 r11, r254, 0d + ST r1, r254, 0a, 16h + ADDI64 r11, r254, 16d BMC r32, r11, 16h - LD r4, r254, 24a, 8h + LD r4, r254, 8a, 8h JNE r4, r33, :0 CP r2, r34 JAL r31, r0, :pass diff --git a/lang/tests/son_tests_tests_ptr_to_ptr_copy.txt b/lang/tests/son_tests_tests_ptr_to_ptr_copy.txt index 330c6e1c..e259c5e2 100644 --- a/lang/tests/son_tests_tests_ptr_to_ptr_copy.txt +++ b/lang/tests/son_tests_tests_ptr_to_ptr_copy.txt @@ -1,24 +1,24 @@ main: ADDI64 r254, r254, -10240d LI8 r6, 64b - LI64 r7, 1024d - LI64 r8, 1d + LI64 r7, 1d + LI64 r8, 1024d LI64 r9, 0d ADDI64 r5, r254, 0d - 4: JLTU r9, r7, :0 + 4: JLTU r9, r8, :0 LI64 r4, 10d - CP r6, r8 + CP r6, r7 3: JLTU r6, r4, :1 LD r10, r254, 2048a, 1h ANDI r1, r10, 255d JMP :2 - 1: ADD64 r12, r6, r8 + 1: ADD64 r12, r6, r7 MULI64 r1, r6, 1024d ADD64 r6, r5, r1 BMC r5, r6, 1024h CP r6, r12 JMP :3 - 0: ADD64 r1, r9, r8 + 0: ADD64 r1, r9, r7 ADD64 r10, r5, r9 ST r6, r10, 0a, 1h CP r9, r1 diff --git a/lang/tests/son_tests_wide_ret.txt b/lang/tests/son_tests_wide_ret.txt index 2b3ad3c0..e9639bfa 100644 --- a/lang/tests/son_tests_wide_ret.txt +++ b/lang/tests/son_tests_wide_ret.txt @@ -16,28 +16,28 @@ main: maina: ADDI64 r254, r254, -44d ST r31, r254, 36a, 8h - ADDI64 r6, r254, 16d + ADDI64 r6, r254, 32d JAL r31, r0, :small_struct - ST r1, r254, 16a, 4h + ST r1, r254, 32a, 4h LI8 r11, 0b - ADDI64 r10, r254, 0d - ST r11, r254, 0a, 1h - ST r11, r254, 1a, 1h - ST r11, r254, 2a, 1h + ADDI64 r10, r254, 24d + ST r11, r254, 24a, 1h + ST r11, r254, 25a, 1h + ST r11, r254, 26a, 1h LI8 r4, 3b - ST r4, r254, 3a, 1h + ST r4, r254, 27a, 1h LI8 r7, 1b - ST r7, r254, 4a, 1h - ST r11, r254, 5a, 1h - ST r11, r254, 6a, 1h - ST r11, r254, 7a, 1h - ADDI64 r1, r254, 8d - BMC r10, r1, 8h - ADDI64 r4, r254, 20d + ST r7, r254, 28a, 1h + ST r11, r254, 29a, 1h + ST r11, r254, 30a, 1h + ST r11, r254, 31a, 1h + ADDI64 r2, r254, 0d + BMC r10, r2, 8h + ADDI64 r5, r2, 8d + ADDI64 r4, r254, 16d + BMC r10, r5, 8h BMC r10, r4, 8h - ADDI64 r7, r4, 8d - BMC r1, r7, 8h - LD r1, r4, 0a, 16h + LD r1, r2, 0a, 16h LD r31, r254, 36a, 8h ADDI64 r254, r254, 44d JALA r0, r31, 0a