simplifing code patterns and sixing argument passing

This commit is contained in:
Jakub Doka 2024-10-21 17:04:29 +02:00
parent ad4aed9c98
commit 73c9ccef6a
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
5 changed files with 169 additions and 158 deletions

View file

@ -8,7 +8,7 @@ use {
}, },
reg, reg,
ty::{self, TyCheck}, ty::{self, TyCheck},
Comptime, Field, Func, Global, OffsetIter, ParamAlloc, Reloc, Sig, Struct, SymKey, Comptime, Field, Func, Global, OffsetIter, PLoc, ParamAlloc, Reloc, Sig, Struct, SymKey,
TypeParser, TypedReloc, Types, TypeParser, TypedReloc, Types,
}, },
alloc::{string::String, vec::Vec}, alloc::{string::String, vec::Vec},
@ -1037,7 +1037,7 @@ impl Codegen {
); );
}; };
let mut parama = self.tys.parama(ty); let (_, mut parama) = self.tys.parama(ty);
let base = self.pool.arg_locs.len(); let base = self.pool.arg_locs.len();
for arg in args { for arg in args {
let arg = self.expr(arg)?; let arg = self.expr(arg)?;
@ -1402,7 +1402,7 @@ impl Codegen {
unreachable!(); unreachable!();
}; };
let mut parama = self.tys.parama(sig.ret); let (_, mut parama) = self.tys.parama(sig.ret);
let base = self.pool.arg_locs.len(); let base = self.pool.arg_locs.len();
let mut sig_args = sig.args.range(); let mut sig_args = sig.args.range();
let mut should_momize = !args.is_empty() && sig.ret == ty::Id::from(ty::TYPE); let mut should_momize = !args.is_empty() && sig.ret == ty::Id::from(ty::TYPE);
@ -2135,7 +2135,7 @@ impl Codegen {
self.ci.emit_prelude(); self.ci.emit_prelude();
let mut parama = self.tys.parama(sig.ret); let (ret, mut parama) = self.tys.parama(sig.ret);
let mut sig_args = sig.args.range(); let mut sig_args = sig.args.range();
for arg in args.iter() { for arg in args.iter() {
let ty = self.tys.ins.args[sig_args.next().unwrap()]; let ty = self.tys.ins.args[sig_args.next().unwrap()];
@ -2147,7 +2147,7 @@ impl Codegen {
self.ci.vars.push(Variable { id: arg.id, value: Value { ty, loc } }); self.ci.vars.push(Variable { id: arg.id, value: Value { ty, loc } });
} }
if self.tys.size_of(sig.ret) > 16 { if let PLoc::Ref(..) = ret {
let reg = self.ci.regs.allocate(); let reg = self.ci.regs.allocate();
self.ci.emit(instrs::cp(reg.get(), 1)); self.ci.emit(instrs::cp(reg.get(), 1));
self.ci.ret_reg = reg; self.ci.ret_reg = reg;
@ -2179,20 +2179,21 @@ impl Codegen {
if size == 0 { if size == 0 {
return Loc::default(); return Loc::default();
} }
let (src, dst) = match size { let (src, dst) = match parama.next(ty, &self.tys) {
0 => (Loc::default(), Loc::default()), PLoc::None => (Loc::default(), Loc::default()),
..=8 if flags & idfl::REFERENCED == 0 => { PLoc::Reg(r, _) if flags & idfl::REFERENCED == 0 => {
(Loc::reg(parama.next()), Loc::reg(self.ci.regs.allocate())) (Loc::reg(r), Loc::reg(self.ci.regs.allocate()))
} }
1..=8 => (Loc::reg(parama.next()), Loc::stack(self.ci.stack.allocate(size))), PLoc::Reg(r, _) => (Loc::reg(r), Loc::stack(self.ci.stack.allocate(size))),
9..=16 => (Loc::reg(parama.next_wide()), Loc::stack(self.ci.stack.allocate(size))), PLoc::WideReg(r, _) => (Loc::reg(r), Loc::stack(self.ci.stack.allocate(size))),
_ if flags & (idfl::MUTABLE | idfl::REFERENCED) == 0 => { PLoc::Ref(ptr, _) if flags & (idfl::MUTABLE | idfl::REFERENCED) == 0 => {
let ptr = parama.next();
let reg = self.ci.regs.allocate(); let reg = self.ci.regs.allocate();
self.ci.emit(instrs::cp(reg.get(), ptr)); self.ci.emit(instrs::cp(reg.get(), ptr));
return Loc::reg(reg).into_derefed(); return Loc::reg(reg).into_derefed();
} }
_ => (Loc::reg(parama.next()).into_derefed(), Loc::stack(self.ci.stack.allocate(size))), PLoc::Ref(ptr, _) => {
(Loc::reg(ptr).into_derefed(), Loc::stack(self.ci.stack.allocate(size)))
}
}; };
self.store_sized(src, &dst, size); self.store_sized(src, &dst, size);
@ -2265,23 +2266,16 @@ impl Codegen {
} }
fn pass_arg(&mut self, value: &Value, parama: &mut ParamAlloc) { fn pass_arg(&mut self, value: &Value, parama: &mut ParamAlloc) {
self.pass_arg_low(&value.loc, self.tys.size_of(value.ty), parama) match parama.next(value.ty, &self.tys) {
PLoc::None => {}
PLoc::Reg(r, _) | PLoc::WideReg(r, _) => {
self.store_typed(&value.loc, Loc::reg(r), value.ty)
}
PLoc::Ref(ptr, _) => {
let Loc::Rt { reg, stack, offset, .. } = &value.loc else { unreachable!() };
self.stack_offset(ptr, reg.get(), stack.as_ref(), *offset as _);
} }
fn pass_arg_low(&mut self, loc: &Loc, size: Size, parama: &mut ParamAlloc) {
if size > 16 {
let Loc::Rt { reg, stack, offset, .. } = loc else { unreachable!() };
self.stack_offset(parama.next(), reg.get(), stack.as_ref(), *offset as _);
return;
} }
let dst = match size {
0 => return,
9..=16 => Loc::reg(parama.next_wide()),
_ => Loc::reg(parama.next()),
};
self.store_sized(loc, dst, size);
} }
fn store_typed(&mut self, src: impl Into<LocCow>, dst: impl Into<LocCow>, ty: ty::Id) { fn store_typed(&mut self, src: impl Into<LocCow>, dst: impl Into<LocCow>, ty: ty::Id) {

View file

@ -21,7 +21,8 @@
str_from_raw_parts, str_from_raw_parts,
ptr_sub_ptr, ptr_sub_ptr,
slice_from_ptr_range, slice_from_ptr_range,
is_sorted is_sorted,
iter_next_chunk
)] )]
#![feature(pointer_is_aligned_to)] #![feature(pointer_is_aligned_to)]
#![warn(clippy::dbg_macro)] #![warn(clippy::dbg_macro)]
@ -247,7 +248,7 @@ mod ty {
ident, ident,
lexer::TokenKind, lexer::TokenKind,
parser::{self, Pos}, parser::{self, Pos},
Size, Size, Types,
}, },
core::{num::NonZeroU32, ops::Range}, core::{num::NonZeroU32, ops::Range},
}; };
@ -405,6 +406,21 @@ mod ty {
Self::UINT Self::UINT
} }
} }
pub fn loc(&self, tys: &Types) -> Loc {
match self.expand() {
Kind::Ptr(_) | Kind::Builtin(_) => Loc::Reg,
Kind::Struct(_) if tys.size_of(*self) == 0 => Loc::Reg,
Kind::Struct(_) | Kind::Slice(_) => Loc::Stack,
Kind::Func(_) | Kind::Global(_) | Kind::Module(_) => unreachable!(),
}
}
}
#[derive(PartialEq, Eq, Clone, Copy)]
pub enum Loc {
Reg,
Stack,
} }
#[derive(PartialEq, Eq, Default, Debug, Clone, Copy)] #[derive(PartialEq, Eq, Default, Debug, Clone, Copy)]
@ -771,15 +787,23 @@ impl Array {
} }
} }
enum PLoc {
None,
Reg(u8, u16),
WideReg(u8, u16),
Ref(u8, u32),
}
struct ParamAlloc(Range<u8>); struct ParamAlloc(Range<u8>);
impl ParamAlloc { impl ParamAlloc {
pub fn next(&mut self) -> u8 { pub fn next(&mut self, ty: ty::Id, tys: &Types) -> PLoc {
self.0.next().expect("too many paramteters") match tys.size_of(ty) {
0 => PLoc::None,
size @ 1..=8 => PLoc::Reg(self.0.next().unwrap(), size as _),
size @ 9..=16 => PLoc::WideReg(self.0.next_chunk::<2>().unwrap()[0], size as _),
size @ 17.. => PLoc::Ref(self.0.next().unwrap(), size),
} }
fn next_wide(&mut self) -> u8 {
(self.next(), self.next()).0
} }
} }
@ -1202,8 +1226,13 @@ impl Types {
instrs::disasm(&mut sluce, &functions, output, eca_handler) instrs::disasm(&mut sluce, &functions, output, eca_handler)
} }
fn parama(&self, ret: impl Into<ty::Id>) -> ParamAlloc { fn parama(&self, ret: impl Into<ty::Id>) -> (PLoc, ParamAlloc) {
ParamAlloc(2 + (9..=16).contains(&self.size_of(ret.into())) as u8..12) let mut iter = ParamAlloc(1..12);
let ret = iter.next(ret.into(), self);
if let PLoc::None = ret {
iter.0.start += 1;
}
(ret, iter)
} }
fn make_ptr(&mut self, base: ty::Id) -> ty::Id { fn make_ptr(&mut self, base: ty::Id) -> ty::Id {

View file

@ -10,10 +10,10 @@ use {
CtorField, Expr, ExprRef, FileId, Pos, CtorField, Expr, ExprRef, FileId, Pos,
}, },
reg, task, reg, task,
ty::{self, ArrayLen, Tuple}, ty::{self, ArrayLen, Loc, Tuple},
vc::{BitSet, Vc}, vc::{BitSet, Vc},
Comptime, Func, Global, HashMap, Offset, OffsetIter, Reloc, Sig, TypeParser, TypedReloc, Comptime, Func, Global, HashMap, Offset, OffsetIter, PLoc, Reloc, Sig, TypeParser,
Types, TypedReloc, Types,
}, },
alloc::{string::String, vec::Vec}, alloc::{string::String, vec::Vec},
core::{ core::{
@ -1093,20 +1093,16 @@ impl ItemCtx {
*saved_regs.entry(hvenc).or_insert(would_insert) *saved_regs.entry(hvenc).or_insert(would_insert)
}; };
let mut parama = tys.parama(sig.ret); let (retl, mut parama) = tys.parama(sig.ret);
for (ti, &arg) in sig.args.range().zip(fuc.nodes[VOID].outputs.iter().skip(2)) { for (ti, &arg) in sig.args.range().zip(fuc.nodes[VOID].outputs.iter().skip(2)) {
let ty = tys.ins.args[ti]; let ty = tys.ins.args[ti];
if tys.size_of(ty) == 0 { let (rg, size) = match parama.next(ty, tys) {
continue; PLoc::WideReg(rg, size) => (rg, size),
} PLoc::Reg(rg, size) if ty.loc(tys) == Loc::Stack => (rg, size),
if let size @ 9..=16 = tys.size_of(ty) { PLoc::Reg(..) | PLoc::Ref(..) | PLoc::None => continue,
let rg = parama.next_wide(); };
self.emit(instrs::st(rg, reg::STACK_PTR, fuc.nodes[arg].offset as _, size as _)); self.emit(instrs::st(rg, reg::STACK_PTR, fuc.nodes[arg].offset as _, size));
self.emit(instrs::addi64(rg, reg::STACK_PTR, fuc.nodes[arg].offset as _)); self.emit(instrs::addi64(rg, reg::STACK_PTR, fuc.nodes[arg].offset as _));
} else {
parama.next();
}
} }
for (i, block) in fuc.blocks.iter().enumerate() { for (i, block) in fuc.blocks.iter().enumerate() {
@ -1177,17 +1173,13 @@ impl ItemCtx {
} }
} }
Kind::Return => { Kind::Return => {
match tys.size_of(sig.ret) { match retl {
0..=8 => {} PLoc::None | PLoc::Reg(..) => {}
size @ 9..=16 => { PLoc::WideReg(r, size) => {
self.emit(instrs::ld(reg::RET, atr(allocs[0]), 0, size as _)); self.emit(instrs::ld(r, atr(allocs[0]), 0, size))
} }
size @ 17.. => { PLoc::Ref(r, size) => {
self.emit(instrs::bmc( self.emit(instrs::bmc(atr(allocs[0]), r, size.try_into().unwrap()));
atr(allocs[0]),
reg::RET,
size.try_into().unwrap(),
));
} }
} }
@ -1243,14 +1235,29 @@ impl ItemCtx {
} }
} }
Kind::Call { func } => { Kind::Call { func } => {
let (ret, mut parama) = tys.parama(node.ty);
let mut allocs = allocs.iter();
for ti in tys.ins.funcs[func as usize].sig.unwrap().args.range() {
let ty = tys.ins.args[ti];
let (rg, size) = match parama.next(ty, tys) {
PLoc::Reg(rg, size) if ty.loc(tys) == Loc::Stack => (rg, size),
PLoc::WideReg(rg, size) => (rg, size),
PLoc::None | PLoc::Ref(..) | PLoc::Reg(..) => continue,
};
let &arg = allocs.next().unwrap();
if size > 8 {
allocs.next().unwrap();
}
self.emit(instrs::ld(rg, atr(arg), 0, size));
}
self.relocs.push(TypedReloc { self.relocs.push(TypedReloc {
target: ty::Kind::Func(func).compress(), target: ty::Kind::Func(func).compress(),
reloc: Reloc::new(self.code.len(), 3, 4), reloc: Reloc::new(self.code.len(), 3, 4),
}); });
self.emit(instrs::jal(reg::RET_ADDR, reg::ZERO, 0)); self.emit(instrs::jal(reg::RET_ADDR, reg::ZERO, 0));
if let size @ 9..=16 = tys.size_of(node.ty) { if let PLoc::WideReg(r, size) = ret {
let stck = fuc.nodes[*node.inputs.last().unwrap()].offset; let stck = fuc.nodes[*node.inputs.last().unwrap()].offset;
self.emit(instrs::st(reg::RET, reg::STACK_PTR, stck as _, size as _)); self.emit(instrs::st(r, reg::STACK_PTR, stck as _, size));
} }
} }
Kind::Global { global } => { Kind::Global { global } => {
@ -1589,6 +1596,7 @@ impl TypeParser for Codegen<'_> {
code: core::mem::take(&mut self.ci.code), code: core::mem::take(&mut self.ci.code),
..Default::default() ..Default::default()
}; };
self.pool.pop_ci(&mut self.ci); self.pool.pop_ci(&mut self.ci);
self.complete_call_graph(); self.complete_call_graph();
@ -2043,12 +2051,8 @@ impl<'a> Codegen<'a> {
let mut inps = Vc::from([self.ci.ctrl]); let mut inps = Vc::from([self.ci.ctrl]);
for ((arg, carg), tyx) in args.iter().zip(cargs).zip(sig.args.range()) { for ((arg, carg), tyx) in args.iter().zip(cargs).zip(sig.args.range()) {
let ty = self.tys.ins.args[tyx]; let ty = self.tys.ins.args[tyx];
if self.tys.size_of(ty) == 0 {
continue;
}
let mut value = self.expr_ctx(arg, Ctx::default().with_ty(ty))?; let mut value = self.expr_ctx(arg, Ctx::default().with_ty(ty))?;
debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre); debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre);
debug_assert_ne!(value.id, 0);
self.assert_ty(arg.pos(), &mut value, ty, fa!("argument {}", carg.name)); self.assert_ty(arg.pos(), &mut value, ty, fa!("argument {}", carg.name));
self.ci.nodes.lock(value.id); self.ci.nodes.lock(value.id);
@ -2074,9 +2078,9 @@ impl<'a> Codegen<'a> {
false false
}); });
let alt_value = match self.tys.size_of(sig.ret) { let alt_value = match sig.ret.loc(&self.tys) {
0..=8 => None, Loc::Reg => None,
9.. => { Loc::Stack => {
let stck = self.ci.nodes.new_node_nop(sig.ret, Kind::Stck, [VOID, MEM]); let stck = self.ci.nodes.new_node_nop(sig.ret, Kind::Stck, [VOID, MEM]);
inps.push(stck); inps.push(stck);
Some(Value::ptr(stck).ty(sig.ret)) Some(Value::ptr(stck).ty(sig.ret))
@ -2692,7 +2696,7 @@ impl<'a> Codegen<'a> {
for arg in args.iter() { for arg in args.iter() {
let ty = self.tys.ins.args[sig_args.next().unwrap()]; let ty = self.tys.ins.args[sig_args.next().unwrap()];
let mut deps = Vc::from([VOID]); let mut deps = Vc::from([VOID]);
if matches!(self.tys.size_of(ty), 9..=16) { if ty.loc(&self.tys) == Loc::Stack {
deps.push(MEM); deps.push(MEM);
} }
let value = self.ci.nodes.new_node_nop(ty, Kind::Arg, [VOID]); let value = self.ci.nodes.new_node_nop(ty, Kind::Arg, [VOID]);
@ -2994,18 +2998,15 @@ impl<'a> Function<'a> {
} }
} }
Kind::Return => { Kind::Return => {
let ops = match self.tys.size_of(self.sig.ret) { let ops = match self.tys.parama(self.sig.ret).0 {
0 => vec![], PLoc::None => vec![],
1..=8 => { PLoc::Reg(r, ..) => {
vec![regalloc2::Operand::reg_fixed_use( vec![regalloc2::Operand::reg_fixed_use(
self.rg(node.inputs[1]), self.rg(node.inputs[1]),
regalloc2::PReg::new(1, regalloc2::RegClass::Int), regalloc2::PReg::new(r as _, regalloc2::RegClass::Int),
)] )]
} }
9..=16 => { PLoc::WideReg(..) | PLoc::Ref(..) => {
vec![self.urg(self.nodes[node.inputs[1]].inputs[1])]
}
17.. => {
vec![self.urg(self.nodes[node.inputs[1]].inputs[1])] vec![self.urg(self.nodes[node.inputs[1]].inputs[1])]
} }
}; };
@ -3035,32 +3036,17 @@ impl<'a> Function<'a> {
Kind::Entry => { Kind::Entry => {
self.nodes[nid].ralloc_backref = self.add_block(nid); self.nodes[nid].ralloc_backref = self.add_block(nid);
let mut parama = self.tys.parama(self.sig.ret); let (_, mut parama) = self.tys.parama(self.sig.ret);
for (ti, arg) in for (ti, arg) in
self.sig.args.range().zip(self.nodes[VOID].clone().outputs.into_iter().skip(2)) self.sig.args.range().zip(self.nodes[VOID].clone().outputs.into_iter().skip(2))
{ {
let ty = self.tys.ins.args[ti]; let ty = self.tys.ins.args[ti];
match self.tys.size_of(ty) { match parama.next(ty, self.tys) {
0 => continue, PLoc::None => {}
1..=8 => { PLoc::Reg(r, _) | PLoc::WideReg(r, _) | PLoc::Ref(r, _) => {
self.add_instr(NEVER, vec![regalloc2::Operand::reg_fixed_def( self.add_instr(NEVER, vec![regalloc2::Operand::reg_fixed_def(
self.rg(arg), self.rg(arg),
regalloc2::PReg::new(parama.next() as _, regalloc2::RegClass::Int), regalloc2::PReg::new(r as _, regalloc2::RegClass::Int),
)]);
}
9..=16 => {
self.add_instr(NEVER, vec![regalloc2::Operand::reg_fixed_def(
self.rg(arg),
regalloc2::PReg::new(
parama.next_wide() as _,
regalloc2::RegClass::Int,
),
)]);
}
_ => {
self.add_instr(NEVER, vec![regalloc2::Operand::reg_fixed_def(
self.rg(arg),
regalloc2::PReg::new(parama.next() as _, regalloc2::RegClass::Int),
)]); )]);
} }
} }
@ -3120,20 +3106,18 @@ impl<'a> Function<'a> {
)); ));
} }
let mut parama = self.tys.parama(fuc.ret); let (ret, mut parama) = self.tys.parama(fuc.ret);
let mut inps = node.inputs[1..].iter(); for (ti, &(mut i)) in fuc.args.range().zip(node.inputs[1..].iter()) {
for ti in fuc.args.range() {
let ty = self.tys.ins.args[ti]; let ty = self.tys.ins.args[ti];
match self.tys.size_of(ty) { match parama.next(ty, self.tys) {
0 => continue, PLoc::None => {}
1..=8 => { PLoc::Reg(r, _) => {
ops.push(regalloc2::Operand::reg_fixed_use( ops.push(regalloc2::Operand::reg_fixed_use(
self.rg(*inps.next().unwrap()), self.rg(i),
regalloc2::PReg::new(parama.next() as _, regalloc2::RegClass::Int), regalloc2::PReg::new(r as _, regalloc2::RegClass::Int),
)); ));
} }
9..=16 => { PLoc::WideReg(r, _) => {
let mut i = *inps.next().unwrap();
loop { loop {
match self.nodes[i].kind { match self.nodes[i].kind {
Kind::Stre { .. } => i = self.nodes[i].inputs[2], Kind::Stre { .. } => i = self.nodes[i].inputs[2],
@ -3145,15 +3129,14 @@ impl<'a> Function<'a> {
debug_assert!(i != 0); debug_assert!(i != 0);
ops.push(regalloc2::Operand::reg_fixed_use( ops.push(regalloc2::Operand::reg_fixed_use(
self.rg(i), self.rg(i),
regalloc2::PReg::new(parama.next() as _, regalloc2::RegClass::Int), regalloc2::PReg::new(r as _, regalloc2::RegClass::Int),
)); ));
ops.push(regalloc2::Operand::reg_fixed_use( ops.push(regalloc2::Operand::reg_fixed_use(
self.rg(i), self.rg(i),
regalloc2::PReg::new(parama.next() as _, regalloc2::RegClass::Int), regalloc2::PReg::new(r as usize + 1, regalloc2::RegClass::Int),
)); ));
} }
_ => { PLoc::Ref(r, _) => {
let mut i = *inps.next().unwrap();
loop { loop {
match self.nodes[i].kind { match self.nodes[i].kind {
Kind::Stre { .. } => i = self.nodes[i].inputs[2], Kind::Stre { .. } => i = self.nodes[i].inputs[2],
@ -3165,21 +3148,18 @@ impl<'a> Function<'a> {
debug_assert!(i != 0); debug_assert!(i != 0);
ops.push(regalloc2::Operand::reg_fixed_use( ops.push(regalloc2::Operand::reg_fixed_use(
self.rg(i), self.rg(i),
regalloc2::PReg::new(parama.next() as _, regalloc2::RegClass::Int), regalloc2::PReg::new(r as _, regalloc2::RegClass::Int),
)); ));
} }
} }
} }
match self.tys.size_of(fuc.ret) { if let PLoc::Ref(r, _) = ret {
0..=16 => {}
17.. => {
ops.push(regalloc2::Operand::reg_fixed_use( ops.push(regalloc2::Operand::reg_fixed_use(
self.rg(*node.inputs.last().unwrap()), self.rg(*node.inputs.last().unwrap()),
regalloc2::PReg::new(1, regalloc2::RegClass::Int), regalloc2::PReg::new(r as _, regalloc2::RegClass::Int),
)); ));
} }
}
self.add_instr(nid, ops); self.add_instr(nid, ops);
@ -3203,6 +3183,7 @@ impl<'a> Function<'a> {
// .iter() // .iter()
// .all(|&n| matches!(self.nodes[n].kind, Kind::Stre | Kind::Load))) // .all(|&n| matches!(self.nodes[n].kind, Kind::Stre | Kind::Load)))
// }) => {} // }) => {}
Kind::Stck if self.tys.size_of(node.ty) == 0 => self.nodes.lock(nid),
Kind::Stck => { Kind::Stck => {
let ops = vec![self.drg(nid)]; let ops = vec![self.drg(nid)];
self.add_instr(nid, ops); self.add_instr(nid, ops);
@ -3212,6 +3193,9 @@ impl<'a> Function<'a> {
self.add_instr(nid, ops); self.add_instr(nid, ops);
} }
Kind::Phi | Kind::Arg | Kind::Mem => {} Kind::Phi | Kind::Arg | Kind::Mem => {}
Kind::Load { .. } if matches!(self.tys.size_of(node.ty), 0 | 9..) => {
self.nodes.lock(nid)
}
Kind::Load { .. } => { Kind::Load { .. } => {
let mut region = node.inputs[1]; let mut region = node.inputs[1];
if self.nodes[region].kind == (Kind::BinOp { op: TokenKind::Add }) if self.nodes[region].kind == (Kind::BinOp { op: TokenKind::Add })
@ -3219,14 +3203,12 @@ impl<'a> Function<'a> {
{ {
region = self.nodes[region].inputs[1] region = self.nodes[region].inputs[1]
} }
if self.tys.size_of(node.ty) <= 8 {
let ops = match self.nodes[region].kind { let ops = match self.nodes[region].kind {
Kind::Stck => vec![self.drg(nid)], Kind::Stck => vec![self.drg(nid)],
_ => vec![self.drg(nid), self.urg(region)], _ => vec![self.drg(nid), self.urg(region)],
}; };
self.add_instr(nid, ops); self.add_instr(nid, ops);
} }
}
Kind::Stre if node.inputs[2] == VOID => self.nodes.lock(nid), Kind::Stre if node.inputs[2] == VOID => self.nodes.lock(nid),
Kind::Stre => { Kind::Stre => {
let mut region = node.inputs[2]; let mut region = node.inputs[2];

View file

@ -47,6 +47,9 @@ main:
CP r2, r3 CP r2, r3
CP r4, r5 CP r4, r5
CP r6, r7 CP r6, r7
LD r2, r2, 0a, 16h
LD r4, r4, 0a, 16h
LD r6, r6, 0a, 16h
JAL r31, r0, :line JAL r31, r0, :line
ADDI64 r7, r254, 0d ADDI64 r7, r254, 0d
ADDI64 r5, r254, 16d ADDI64 r5, r254, 16d
@ -61,6 +64,9 @@ main:
CP r2, r3 CP r2, r3
CP r4, r5 CP r4, r5
CP r6, r7 CP r6, r7
LD r2, r2, 0a, 16h
LD r4, r4, 0a, 16h
LD r6, r6, 0a, 16h
JAL r31, r0, :rect_line JAL r31, r0, :rect_line
JAL r31, r0, :example JAL r31, r0, :example
LD r31, r254, 96a, 16h LD r31, r254, 96a, 16h
@ -86,7 +92,6 @@ rect_line:
2: ADDI64 r9, r9, 1d 2: ADDI64 r9, r9, 1d
JMP :4 JMP :4
1: JALA r0, r31, 0a 1: JALA r0, r31, 0a
timed out code size: 875
code size: 797 ret: 4
ret: 0
status: Ok(()) status: Ok(())

View file

@ -14,29 +14,30 @@ main:
ADDI64 r254, r254, 56d ADDI64 r254, r254, 56d
JALA r0, r31, 0a JALA r0, r31, 0a
maina: maina:
ADDI64 r254, r254, -88d ADDI64 r254, r254, -100d
ST r31, r254, 24a, 64h ST r31, r254, 28a, 72h
ADDI64 r32, r254, 24d
JAL r31, r0, :small_struct JAL r31, r0, :small_struct
LI64 r32, 1d LI64 r33, 1d
LI64 r33, 3d LI64 r34, 3d
LI64 r34, 0d LI64 r35, 0d
ADDI64 r35, r254, 0d ADDI64 r36, r254, 0d
ADDI64 r36, r254, 16d ADDI64 r37, r254, 16d
ST r34, r254, 16a, 1h ST r35, r254, 16a, 1h
ST r34, r254, 17a, 1h ST r35, r254, 17a, 1h
ST r34, r254, 18a, 1h ST r35, r254, 18a, 1h
ST r33, r254, 19a, 1h ST r34, r254, 19a, 1h
ST r32, r254, 20a, 1h ST r33, r254, 20a, 1h
ST r34, r254, 21a, 1h ST r35, r254, 21a, 1h
ST r34, r254, 22a, 1h ST r35, r254, 22a, 1h
ST r34, r254, 23a, 1h ST r35, r254, 23a, 1h
LD r37, r254, 16a, 8h
ST r37, r254, 0a, 8h
LD r38, r254, 16a, 8h LD r38, r254, 16a, 8h
ST r38, r254, 8a, 8h ST r38, r254, 0a, 8h
LD r1, r35, 0a, 16h LD r39, r254, 16a, 8h
LD r31, r254, 24a, 64h ST r39, r254, 8a, 8h
ADDI64 r254, r254, 88d LD r1, r36, 0a, 16h
LD r31, r254, 28a, 72h
ADDI64 r254, r254, 100d
JALA r0, r31, 0a JALA r0, r31, 0a
small_struct: small_struct:
ADDI64 r254, r254, -4d ADDI64 r254, r254, -4d
@ -47,6 +48,6 @@ small_struct:
LD r1, r254, 0a, 4h LD r1, r254, 0a, 4h
ADDI64 r254, r254, 4d ADDI64 r254, r254, 4d
JALA r0, r31, 0a JALA r0, r31, 0a
code size: 532 code size: 543
ret: 2 ret: 2
status: Ok(()) status: Ok(())