Only compare reprs in gen_dev

This commit is contained in:
Ayaz Hafiz 2023-05-11 12:48:38 -05:00
parent 4b7f09b175
commit 1b84cbafe3
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
5 changed files with 103 additions and 76 deletions

View file

@ -886,7 +886,7 @@ impl<
fn move_return_value(&mut self, dst: &Symbol, ret_layout: &InLayout<'a>) {
// move return value to dst.
match *ret_layout {
match self.interner().get(*ret_layout).repr {
single_register_integers!() => {
let width = RegisterWidth::try_from_layout(*ret_layout).unwrap();
@ -897,7 +897,7 @@ impl<
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
ASM::mov_freg64_freg64(&mut self.buf, dst_reg, CC::FLOAT_RETURN_REGS[0]);
}
Layout::I128 | Layout::U128 => {
LayoutRepr::I128 | LayoutRepr::U128 => {
let offset = self.storage_manager.claim_stack_area(dst, 16);
ASM::mov_base32_reg64(&mut self.buf, offset, CC::GENERAL_RETURN_REGS[0]);
@ -906,7 +906,7 @@ impl<
other => {
//
match self.layout_interner.get(other).repr {
match other {
LayoutRepr::Boxed(_) => {
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
ASM::mov_reg64_reg64(&mut self.buf, dst_reg, CC::GENERAL_RETURN_REGS[0]);
@ -1392,8 +1392,8 @@ impl<
}
fn build_eq(&mut self, dst: &Symbol, src1: &Symbol, src2: &Symbol, arg_layout: &InLayout<'a>) {
match *arg_layout {
single_register_int_builtins!() | Layout::BOOL => {
match self.interner().get(*arg_layout).repr {
single_register_int_builtins!() | LayoutRepr::BOOL => {
let width = match *arg_layout {
Layout::BOOL | Layout::I8 | Layout::U8 => RegisterWidth::W8,
Layout::I16 | Layout::U16 => RegisterWidth::W16,
@ -1411,7 +1411,7 @@ impl<
.load_to_general_reg(&mut self.buf, src2);
ASM::eq_reg_reg_reg(&mut self.buf, width, dst_reg, src1_reg, src2_reg);
}
Layout::U128 | Layout::I128 => {
LayoutRepr::U128 | LayoutRepr::I128 => {
let buf = &mut self.buf;
let dst_reg = self.storage_manager.claim_general_reg(buf, dst);
@ -1447,10 +1447,10 @@ impl<
self.storage_manager.free_symbol(&Symbol::DEV_TMP);
self.storage_manager.free_symbol(&Symbol::DEV_TMP2);
}
Layout::F32 => todo!("NumEq: layout, {:?}", self.layout_interner.dbg(Layout::F32)),
Layout::F64 => todo!("NumEq: layout, {:?}", self.layout_interner.dbg(Layout::F64)),
Layout::DEC => todo!("NumEq: layout, {:?}", self.layout_interner.dbg(Layout::DEC)),
Layout::STR => {
LayoutRepr::F32 => todo!("NumEq: layout, {:?}", self.layout_interner.dbg(Layout::F32)),
LayoutRepr::F64 => todo!("NumEq: layout, {:?}", self.layout_interner.dbg(Layout::F64)),
LayoutRepr::DEC => todo!("NumEq: layout, {:?}", self.layout_interner.dbg(Layout::DEC)),
LayoutRepr::STR => {
// use a zig call
self.build_fn_call(
dst,
@ -1470,7 +1470,7 @@ impl<
let dst_reg = self.storage_manager.load_to_general_reg(&mut self.buf, dst);
ASM::eq_reg_reg_reg(&mut self.buf, width, dst_reg, dst_reg, tmp_reg);
}
other => {
_ => {
let ident_ids = self
.interns
.all_ident_ids
@ -1482,27 +1482,33 @@ impl<
let (eq_symbol, eq_linker_data) = self.helper_proc_gen.gen_refcount_proc(
ident_ids,
self.layout_interner,
other,
*arg_layout,
HelperOp::Eq,
);
let fn_name = self.function_symbol_to_string(
eq_symbol,
[other, other].into_iter(),
[*arg_layout, *arg_layout].into_iter(),
None,
Layout::U8,
);
self.helper_proc_symbols.extend(eq_linker_data);
self.build_fn_call(dst, fn_name, &[*src1, *src2], &[other, other], &Layout::U8)
self.build_fn_call(
dst,
fn_name,
&[*src1, *src2],
&[*arg_layout, *arg_layout],
&Layout::U8,
)
}
}
}
fn build_neq(&mut self, dst: &Symbol, src1: &Symbol, src2: &Symbol, arg_layout: &InLayout<'a>) {
match *arg_layout {
single_register_int_builtins!() | Layout::BOOL => {
match self.interner().get(*arg_layout).repr {
single_register_int_builtins!() | LayoutRepr::BOOL => {
let width = match *arg_layout {
Layout::BOOL | Layout::I8 | Layout::U8 => RegisterWidth::W8,
Layout::I16 | Layout::U16 => RegisterWidth::W16,
@ -1520,7 +1526,7 @@ impl<
.load_to_general_reg(&mut self.buf, src2);
ASM::neq_reg64_reg64_reg64(&mut self.buf, width, dst_reg, src1_reg, src2_reg);
}
Layout::STR => {
LayoutRepr::STR => {
self.build_fn_call(
dst,
bitcode::STR_EQUAL.to_string(),
@ -1543,8 +1549,8 @@ impl<
}
fn build_not(&mut self, dst: &Symbol, src: &Symbol, arg_layout: &InLayout<'a>) {
match *arg_layout {
Layout::BOOL => {
match self.interner().get(*arg_layout).repr {
LayoutRepr::BOOL => {
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
let src_reg = self.storage_manager.load_to_general_reg(&mut self.buf, src);
@ -2817,9 +2823,10 @@ impl<
}
fn return_symbol(&mut self, sym: &Symbol, layout: &InLayout<'a>) {
let repr = self.layout_interner.get(*layout).repr;
if self.storage_manager.is_stored_primitive(sym) {
// Just load it to the correct type of reg as a stand alone value.
match *layout {
match repr {
single_register_integers!() => {
self.storage_manager.load_to_specified_general_reg(
&mut self.buf,
@ -2834,7 +2841,7 @@ impl<
CC::FLOAT_RETURN_REGS[0],
);
}
other => match self.layout_interner.get(other).repr {
other => match other {
LayoutRepr::Boxed(_) => {
// treat like a 64-bit integer
self.storage_manager.load_to_specified_general_reg(
@ -3195,7 +3202,7 @@ impl<
src2: &Symbol,
arg_layout: &InLayout<'a>,
) {
match *arg_layout {
match self.interner().get(*arg_layout).repr {
single_register_integers!() => {
let buf = &mut self.buf;
@ -3218,7 +3225,7 @@ impl<
ASM::unsigned_compare_reg64(buf, register_width, op, dst, src1, src2)
}
}
Layout::F32 | Layout::F64 => {
LayoutRepr::F32 | LayoutRepr::F64 => {
let float_width = match *arg_layout {
Layout::F32 => FloatWidth::F32,
Layout::F64 => FloatWidth::F64,
@ -3600,28 +3607,28 @@ macro_rules! zero_extended_int_builtins {
#[macro_export]
macro_rules! single_register_int_builtins {
() => {
Layout::I8
| Layout::I16
| Layout::I32
| Layout::I64
| Layout::U8
| Layout::U16
| Layout::U32
| Layout::U64
LayoutRepr::I8
| LayoutRepr::I16
| LayoutRepr::I32
| LayoutRepr::I64
| LayoutRepr::U8
| LayoutRepr::U16
| LayoutRepr::U32
| LayoutRepr::U64
};
}
#[macro_export]
macro_rules! single_register_integers {
() => {
Layout::BOOL | single_register_int_builtins!() | Layout::OPAQUE_PTR
LayoutRepr::BOOL | single_register_int_builtins!() | LayoutRepr::OPAQUE_PTR
};
}
#[macro_export]
macro_rules! single_register_floats {
() => {
Layout::F32 | Layout::F64
LayoutRepr::F32 | LayoutRepr::F64
};
}

View file

@ -1159,7 +1159,7 @@ impl<
symbol: Symbol,
layout: InLayout<'a>,
) {
match layout {
match layout_interner.get(layout).repr {
single_register_layouts!() => {
let base_offset = self.claim_stack_size(8);
self.symbol_storage_map.insert(
@ -1227,7 +1227,7 @@ impl<
layout: InLayout<'a>,
base_offset: i32,
) {
match layout {
match layout_interner.get(layout).repr {
single_register_integers!() => {
let reg = self.load_to_general_reg(buf, &symbol);
ASM::mov_base32_reg64(buf, base_offset, reg);
@ -1534,7 +1534,7 @@ impl<
}
fn is_primitive(layout_interner: &mut STLayoutInterner<'_>, layout: InLayout<'_>) -> bool {
match layout {
match layout_interner.get(layout).repr {
single_register_layouts!() => true,
_ => match layout_interner.get(layout).repr {
LayoutRepr::Boxed(_) => true,

View file

@ -8,7 +8,7 @@ use roc_builtins::bitcode::{FloatWidth, IntWidth};
use roc_error_macros::internal_error;
use roc_module::symbol::Symbol;
use roc_mono::layout::{
Builtin, InLayout, Layout, LayoutInterner, LayoutRepr, STLayoutInterner, UnionLayout,
Builtin, InLayout, LayoutInterner, LayoutRepr, STLayoutInterner, UnionLayout,
};
use super::{CompareOperation, RegisterWidth};
@ -346,12 +346,12 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg, X86_64Assembler> for X86_64Syste
sym: &Symbol,
layout: &InLayout<'a>,
) {
match *layout {
match layout_interner.get(*layout).repr {
single_register_layouts!() => {
internal_error!("single register layouts are not complex symbols");
}
x if layout_interner.stack_size(x) == 0 => {}
x if !Self::returns_via_arg_pointer(layout_interner, &x) => {
x if layout_interner.stack_size(*layout) == 0 => {}
x if !Self::returns_via_arg_pointer(layout_interner, layout) => {
let (base_offset, size) = storage_manager.stack_offset_and_size(sym);
debug_assert_eq!(base_offset % 8, 0);
if size <= 8 {
@ -404,14 +404,14 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg, X86_64Assembler> for X86_64Syste
sym: &Symbol,
layout: &InLayout<'a>,
) {
match *layout {
match layout_interner.get(*layout).repr {
single_register_layouts!() => {
internal_error!("single register layouts are not complex symbols");
}
x if layout_interner.stack_size(x) == 0 => {
x if layout_interner.stack_size(*layout) == 0 => {
storage_manager.no_data(sym);
}
x if !Self::returns_via_arg_pointer(layout_interner, &x) => {
x if !Self::returns_via_arg_pointer(layout_interner, layout) => {
let size = layout_interner.stack_size(*layout);
let offset = storage_manager.claim_stack_area(sym, size);
if size <= 8 {
@ -459,10 +459,10 @@ impl X64_64SystemVStoreArgs {
sym: Symbol,
in_layout: InLayout<'a>,
) {
match in_layout {
match layout_interner.get(in_layout).repr {
single_register_integers!() => self.store_arg_general(buf, storage_manager, sym),
single_register_floats!() => self.store_arg_float(buf, storage_manager, sym),
Layout::I128 | Layout::U128 => {
LayoutRepr::I128 | LayoutRepr::U128 => {
let (offset, _) = storage_manager.stack_offset_and_size(&sym);
if self.general_i + 1 < Self::GENERAL_PARAM_REGS.len() {
@ -486,8 +486,8 @@ impl X64_64SystemVStoreArgs {
self.tmp_stack_offset += 16;
}
}
x if layout_interner.stack_size(x) == 0 => {}
x if layout_interner.stack_size(x) > 16 => {
x if layout_interner.stack_size(in_layout) == 0 => {}
x if layout_interner.stack_size(in_layout) > 16 => {
// TODO: Double check this.
// Just copy onto the stack.
// Use return reg as buffer because it will be empty right now.
@ -509,7 +509,7 @@ impl X64_64SystemVStoreArgs {
}
other => {
// look at the layout in more detail
match layout_interner.get(other).repr {
match other {
LayoutRepr::Boxed(_) => {
// treat boxed like a 64-bit integer
self.store_arg_general(buf, storage_manager, sym)
@ -587,7 +587,10 @@ impl X64_64SystemVStoreArgs {
self.tmp_stack_offset += size as i32;
}
_ => {
todo!("calling with arg type, {:?}", layout_interner.dbg(other));
todo!(
"calling with arg type, {:?}",
layout_interner.dbg(in_layout)
);
}
}
}
@ -659,7 +662,7 @@ impl X64_64SystemVLoadArgs {
in_layout: InLayout<'a>,
) {
let stack_size = layout_interner.stack_size(in_layout);
match in_layout {
match layout_interner.get(in_layout).repr {
single_register_integers!() => self.load_arg_general(storage_manager, sym),
single_register_floats!() => self.load_arg_float(storage_manager, sym),
_ if stack_size == 0 => {
@ -670,7 +673,7 @@ impl X64_64SystemVLoadArgs {
storage_manager.complex_stack_arg(&sym, self.argument_offset, stack_size);
self.argument_offset += stack_size as i32;
}
other => match layout_interner.get(other).repr {
other => match other {
LayoutRepr::Boxed(_) => {
// boxed layouts are pointers, which we treat as 64-bit integers
self.load_arg_general(storage_manager, sym)
@ -696,7 +699,10 @@ impl X64_64SystemVLoadArgs {
self.argument_offset += stack_size as i32;
}
_ => {
todo!("Loading args with layout {:?}", layout_interner.dbg(other));
todo!(
"Loading args with layout {:?}",
layout_interner.dbg(in_layout)
);
}
},
}
@ -892,7 +898,7 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg, X86_64Assembler> for X86_64Windo
}
for (layout, sym) in args.iter() {
match *layout {
match layout_interner.get(*layout).repr {
single_register_integers!() => {
match Self::GENERAL_PARAM_REGS.get(general_registers_used) {
Some(reg) => {
@ -917,7 +923,7 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg, X86_64Assembler> for X86_64Windo
}
}
}
x if layout_interner.stack_size(x) == 0 => {}
x if layout_interner.stack_size(*layout) == 0 => {}
x => {
todo!("Loading args with layout {:?}", x);
}
@ -953,7 +959,7 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg, X86_64Assembler> for X86_64Windo
let mut float_registers_used = 0;
for (sym, layout) in args.iter().zip(arg_layouts.iter()) {
match *layout {
match layout_interner.get(*layout).repr {
single_register_integers!() => {
match Self::GENERAL_PARAM_REGS.get(general_registers_used) {
Some(reg) => {
@ -988,7 +994,7 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg, X86_64Assembler> for X86_64Windo
}
}
}
x if layout_interner.stack_size(x) == 0 => {}
x if layout_interner.stack_size(*layout) == 0 => {}
x => {
todo!("calling with arg type, {:?}", x);
}