Wrap layouts in a LayoutRepr constructor

Part 1 of support semantic layout representations.
This commit is contained in:
Ayaz Hafiz 2023-05-10 13:22:10 -05:00
parent c2d2bd4bb9
commit c3eeb5e2cc
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
32 changed files with 1254 additions and 1021 deletions

View file

@ -13,8 +13,8 @@ use roc_mono::ir::{
SelfRecursive, Stmt,
};
use roc_mono::layout::{
Builtin, InLayout, Layout, LayoutIds, LayoutInterner, STLayoutInterner, TagIdIntType,
UnionLayout,
Builtin, InLayout, Layout, LayoutIds, LayoutInterner, LayoutRepr, STLayoutInterner,
TagIdIntType, UnionLayout,
};
use roc_mono::low_level::HigherOrder;
use roc_target::TargetInfo;
@ -906,12 +906,12 @@ impl<
other => {
//
match self.layout_interner.get(other) {
Layout::Boxed(_) => {
match self.layout_interner.get(other).repr {
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]);
}
Layout::LambdaSet(lambda_set) => {
LayoutRepr::LambdaSet(lambda_set) => {
self.move_return_value(dst, &lambda_set.runtime_representation())
}
_ => {
@ -1064,13 +1064,13 @@ impl<
}
fn build_num_abs(&mut self, dst: &Symbol, src: &Symbol, layout: &InLayout<'a>) {
match self.interner().get(*layout) {
Layout::Builtin(Builtin::Int(IntWidth::I64 | IntWidth::U64)) => {
match self.interner().get(*layout).repr {
LayoutRepr::Builtin(Builtin::Int(IntWidth::I64 | IntWidth::U64)) => {
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);
ASM::abs_reg64_reg64(&mut self.buf, dst_reg, src_reg);
}
Layout::Builtin(Builtin::Float(FloatWidth::F64)) => {
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F64)) => {
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
let src_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src);
ASM::abs_freg64_freg64(&mut self.buf, &mut self.relocs, dst_reg, src_reg);
@ -1080,8 +1080,8 @@ impl<
}
fn build_num_add(&mut self, dst: &Symbol, src1: &Symbol, src2: &Symbol, layout: &InLayout<'a>) {
match self.layout_interner.get(*layout) {
Layout::Builtin(Builtin::Int(quadword_and_smaller!())) => {
match self.layout_interner.get(*layout).repr {
LayoutRepr::Builtin(Builtin::Int(quadword_and_smaller!())) => {
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
let src1_reg = self
.storage_manager
@ -1091,13 +1091,13 @@ impl<
.load_to_general_reg(&mut self.buf, src2);
ASM::add_reg64_reg64_reg64(&mut self.buf, dst_reg, src1_reg, src2_reg);
}
Layout::Builtin(Builtin::Float(FloatWidth::F64)) => {
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F64)) => {
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
let src1_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src1);
let src2_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src2);
ASM::add_freg64_freg64_freg64(&mut self.buf, dst_reg, src1_reg, src2_reg);
}
Layout::Builtin(Builtin::Float(FloatWidth::F32)) => {
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F32)) => {
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
let src1_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src1);
let src2_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src2);
@ -1123,8 +1123,10 @@ impl<
let base_offset = self.storage_manager.claim_stack_area(dst, struct_size);
match self.layout_interner.get(*num_layout) {
Layout::Builtin(Int(IntWidth::I64 | IntWidth::I32 | IntWidth::I16 | IntWidth::I8)) => {
match self.layout_interner.get(*num_layout).repr {
LayoutRepr::Builtin(Int(
IntWidth::I64 | IntWidth::I32 | IntWidth::I16 | IntWidth::I8,
)) => {
let dst_reg = self
.storage_manager
.claim_general_reg(buf, &Symbol::DEV_TMP);
@ -1145,13 +1147,15 @@ impl<
self.free_symbol(&Symbol::DEV_TMP);
self.free_symbol(&Symbol::DEV_TMP2);
}
Layout::Builtin(Int(IntWidth::U64 | IntWidth::U32 | IntWidth::U16 | IntWidth::U8)) => {
LayoutRepr::Builtin(Int(
IntWidth::U64 | IntWidth::U32 | IntWidth::U16 | IntWidth::U8,
)) => {
todo!("addChecked for unsigned integers")
}
Layout::Builtin(Builtin::Float(FloatWidth::F64)) => {
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F64)) => {
todo!("addChecked for f64")
}
Layout::Builtin(Builtin::Float(FloatWidth::F32)) => {
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F32)) => {
todo!("addChecked for f32")
}
x => todo!("NumAdd: layout, {:?}", x),
@ -1166,10 +1170,10 @@ impl<
num_layout: &InLayout<'a>,
return_layout: &InLayout<'a>,
) {
let function_name = match self.interner().get(*num_layout) {
Layout::Builtin(Builtin::Int(width)) => &bitcode::NUM_SUB_CHECKED_INT[width],
Layout::Builtin(Builtin::Float(width)) => &bitcode::NUM_SUB_CHECKED_FLOAT[width],
Layout::Builtin(Builtin::Decimal) => bitcode::DEC_SUB_WITH_OVERFLOW,
let function_name = match self.interner().get(*num_layout).repr {
LayoutRepr::Builtin(Builtin::Int(width)) => &bitcode::NUM_SUB_CHECKED_INT[width],
LayoutRepr::Builtin(Builtin::Float(width)) => &bitcode::NUM_SUB_CHECKED_FLOAT[width],
LayoutRepr::Builtin(Builtin::Decimal) => bitcode::DEC_SUB_WITH_OVERFLOW,
x => internal_error!("NumSubChecked is not defined for {:?}", x),
};
@ -1185,8 +1189,10 @@ impl<
fn build_num_mul(&mut self, dst: &Symbol, src1: &Symbol, src2: &Symbol, layout: &InLayout<'a>) {
use Builtin::Int;
match self.layout_interner.get(*layout) {
Layout::Builtin(Int(IntWidth::I64 | IntWidth::I32 | IntWidth::I16 | IntWidth::I8)) => {
match self.layout_interner.get(*layout).repr {
LayoutRepr::Builtin(Int(
IntWidth::I64 | IntWidth::I32 | IntWidth::I16 | IntWidth::I8,
)) => {
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
let src1_reg = self
.storage_manager
@ -1196,7 +1202,9 @@ impl<
.load_to_general_reg(&mut self.buf, src2);
ASM::imul_reg64_reg64_reg64(&mut self.buf, dst_reg, src1_reg, src2_reg);
}
Layout::Builtin(Int(IntWidth::U64 | IntWidth::U32 | IntWidth::U16 | IntWidth::U8)) => {
LayoutRepr::Builtin(Int(
IntWidth::U64 | IntWidth::U32 | IntWidth::U16 | IntWidth::U8,
)) => {
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
let src1_reg = self
.storage_manager
@ -1213,7 +1221,7 @@ impl<
src2_reg,
);
}
Layout::Builtin(Builtin::Int(IntWidth::I128 | IntWidth::U128)) => {
LayoutRepr::Builtin(Builtin::Int(IntWidth::I128 | IntWidth::U128)) => {
let int_width = match *layout {
Layout::I128 => IntWidth::I128,
Layout::U128 => IntWidth::U128,
@ -1228,13 +1236,13 @@ impl<
layout,
);
}
Layout::Builtin(Builtin::Float(FloatWidth::F64)) => {
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F64)) => {
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
let src1_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src1);
let src2_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src2);
ASM::mul_freg64_freg64_freg64(&mut self.buf, dst_reg, src1_reg, src2_reg);
}
Layout::Builtin(Builtin::Float(FloatWidth::F32)) => {
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F32)) => {
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
let src1_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src1);
let src2_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src2);
@ -1245,8 +1253,8 @@ impl<
}
fn build_num_div(&mut self, dst: &Symbol, src1: &Symbol, src2: &Symbol, layout: &InLayout<'a>) {
match self.layout_interner.get(*layout) {
Layout::Builtin(Builtin::Int(
match self.layout_interner.get(*layout).repr {
LayoutRepr::Builtin(Builtin::Int(
IntWidth::I64 | IntWidth::I32 | IntWidth::I16 | IntWidth::I8,
)) => {
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
@ -1265,7 +1273,7 @@ impl<
src2_reg,
);
}
Layout::Builtin(Builtin::Int(
LayoutRepr::Builtin(Builtin::Int(
IntWidth::U64 | IntWidth::U32 | IntWidth::U16 | IntWidth::U8,
)) => {
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
@ -1284,13 +1292,13 @@ impl<
src2_reg,
);
}
Layout::Builtin(Builtin::Float(FloatWidth::F64)) => {
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F64)) => {
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
let src1_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src1);
let src2_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src2);
ASM::div_freg64_freg64_freg64(&mut self.buf, dst_reg, src1_reg, src2_reg);
}
Layout::Builtin(Builtin::Float(FloatWidth::F32)) => {
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F32)) => {
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
let src1_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src1);
let src2_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src2);
@ -1301,8 +1309,8 @@ impl<
}
fn build_num_rem(&mut self, dst: &Symbol, src1: &Symbol, src2: &Symbol, layout: &InLayout<'a>) {
match self.layout_interner.get(*layout) {
Layout::Builtin(Builtin::Int(
match self.layout_interner.get(*layout).repr {
LayoutRepr::Builtin(Builtin::Int(
IntWidth::I64 | IntWidth::I32 | IntWidth::I16 | IntWidth::I8,
)) => {
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
@ -1321,7 +1329,7 @@ impl<
src2_reg,
);
}
Layout::Builtin(Builtin::Int(
LayoutRepr::Builtin(Builtin::Int(
IntWidth::U64 | IntWidth::U32 | IntWidth::U16 | IntWidth::U8,
)) => {
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
@ -1345,8 +1353,8 @@ impl<
}
fn build_num_neg(&mut self, dst: &Symbol, src: &Symbol, layout: &InLayout<'a>) {
match self.layout_interner.get(*layout) {
Layout::Builtin(Builtin::Int(IntWidth::I64 | IntWidth::U64)) => {
match self.layout_interner.get(*layout).repr {
LayoutRepr::Builtin(Builtin::Int(IntWidth::I64 | IntWidth::U64)) => {
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);
ASM::neg_reg64_reg64(&mut self.buf, dst_reg, src_reg);
@ -1368,8 +1376,8 @@ impl<
src2: &Symbol,
layout: &InLayout<'a>,
) {
match self.layout_interner.get(*layout) {
Layout::Builtin(Builtin::Int(quadword_and_smaller!())) => {
match self.layout_interner.get(*layout).repr {
LayoutRepr::Builtin(Builtin::Int(quadword_and_smaller!())) => {
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
let src1_reg = self
.storage_manager
@ -1560,47 +1568,47 @@ impl<
) {
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
match (
self.layout_interner.get(*arg_layout),
self.layout_interner.get(*ret_layout),
self.layout_interner.get(*arg_layout).repr,
self.layout_interner.get(*ret_layout).repr,
) {
(
Layout::Builtin(Builtin::Int(IntWidth::I32 | IntWidth::I64)),
Layout::Builtin(Builtin::Float(FloatWidth::F64)),
LayoutRepr::Builtin(Builtin::Int(IntWidth::I32 | IntWidth::I64)),
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F64)),
) => {
let src_reg = self.storage_manager.load_to_general_reg(&mut self.buf, src);
ASM::to_float_freg64_reg64(&mut self.buf, dst_reg, src_reg);
}
(
Layout::Builtin(Builtin::Int(IntWidth::I32 | IntWidth::I64)),
Layout::Builtin(Builtin::Float(FloatWidth::F32)),
LayoutRepr::Builtin(Builtin::Int(IntWidth::I32 | IntWidth::I64)),
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F32)),
) => {
let src_reg = self.storage_manager.load_to_general_reg(&mut self.buf, src);
ASM::to_float_freg32_reg64(&mut self.buf, dst_reg, src_reg);
}
(
Layout::Builtin(Builtin::Float(FloatWidth::F64)),
Layout::Builtin(Builtin::Float(FloatWidth::F32)),
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F64)),
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F32)),
) => {
let src_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src);
ASM::to_float_freg32_freg64(&mut self.buf, dst_reg, src_reg);
}
(
Layout::Builtin(Builtin::Float(FloatWidth::F32)),
Layout::Builtin(Builtin::Float(FloatWidth::F64)),
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F32)),
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F64)),
) => {
let src_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src);
ASM::to_float_freg64_freg32(&mut self.buf, dst_reg, src_reg);
}
(
Layout::Builtin(Builtin::Float(FloatWidth::F64)),
Layout::Builtin(Builtin::Float(FloatWidth::F64)),
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F64)),
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F64)),
) => {
let src_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src);
ASM::mov_freg64_freg64(&mut self.buf, dst_reg, src_reg);
}
(
Layout::Builtin(Builtin::Float(FloatWidth::F32)),
Layout::Builtin(Builtin::Float(FloatWidth::F32)),
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F32)),
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F32)),
) => {
let src_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src);
ASM::mov_freg64_freg64(&mut self.buf, dst_reg, src_reg);
@ -1808,8 +1816,10 @@ impl<
let old_element_layout = higher_order.passed_function.argument_layouts[0];
let new_element_layout = higher_order.passed_function.return_layout;
let input_list_layout = Layout::Builtin(Builtin::List(old_element_layout));
let input_list_in_layout = self.layout_interner.insert(input_list_layout);
let input_list_layout = LayoutRepr::Builtin(Builtin::List(old_element_layout));
let input_list_in_layout = self.layout_interner.insert(Layout {
repr: input_list_layout,
});
let caller = self.debug_symbol("caller");
let data = self.debug_symbol("data");
@ -2212,15 +2222,16 @@ impl<
.storage_manager
.claim_stack_area(dst, self.layout_interner.stack_size(*ret_layout));
let ret_fields =
if let Layout::Struct { field_layouts, .. } = self.layout_interner.get(*ret_layout) {
field_layouts
} else {
internal_error!(
"Expected replace to return a struct instead found: {:?}",
ret_layout
)
};
let ret_fields = if let LayoutRepr::Struct { field_layouts, .. } =
self.layout_interner.get(*ret_layout).repr
{
field_layouts
} else {
internal_error!(
"Expected replace to return a struct instead found: {:?}",
ret_layout
)
};
// Only return list and old element.
debug_assert_eq!(ret_fields.len(), 2);
@ -2561,7 +2572,9 @@ impl<
);
}
_ => {
let union_in_layout = self.layout_interner.insert(Layout::Union(*union_layout));
let union_in_layout = self.layout_interner.insert(Layout {
repr: LayoutRepr::Union(*union_layout),
});
todo!(
"loading from union type: {:?}",
self.layout_interner.dbg(union_in_layout)
@ -2673,14 +2686,14 @@ impl<
fn load_literal(&mut self, sym: &Symbol, layout: &InLayout<'a>, lit: &Literal<'a>) {
let layout = self.layout_interner.get(*layout);
if let Layout::LambdaSet(lambda_set) = layout {
if let LayoutRepr::LambdaSet(lambda_set) = layout.repr {
return self.load_literal(sym, &lambda_set.runtime_representation(), lit);
}
match (lit, layout) {
match (lit, layout.repr) {
(
Literal::Int(x),
Layout::Builtin(Builtin::Int(
LayoutRepr::Builtin(Builtin::Int(
IntWidth::U8
| IntWidth::U16
| IntWidth::U32
@ -2697,7 +2710,7 @@ impl<
}
(
Literal::Int(bytes) | Literal::U128(bytes),
Layout::Builtin(Builtin::Int(IntWidth::I128 | IntWidth::U128)),
LayoutRepr::Builtin(Builtin::Int(IntWidth::I128 | IntWidth::U128)),
) => {
self.storage_manager.with_tmp_general_reg(
&mut self.buf,
@ -2717,26 +2730,26 @@ impl<
},
);
}
(Literal::Byte(x), Layout::Builtin(Builtin::Int(IntWidth::U8 | IntWidth::I8))) => {
(Literal::Byte(x), LayoutRepr::Builtin(Builtin::Int(IntWidth::U8 | IntWidth::I8))) => {
let reg = self.storage_manager.claim_general_reg(&mut self.buf, sym);
let val = *x;
ASM::mov_reg64_imm64(&mut self.buf, reg, val as i64);
}
(Literal::Bool(x), Layout::Builtin(Builtin::Bool)) => {
(Literal::Bool(x), LayoutRepr::Builtin(Builtin::Bool)) => {
let reg = self.storage_manager.claim_general_reg(&mut self.buf, sym);
ASM::mov_reg64_imm64(&mut self.buf, reg, *x as i64);
}
(Literal::Float(x), Layout::Builtin(Builtin::Float(FloatWidth::F64))) => {
(Literal::Float(x), LayoutRepr::Builtin(Builtin::Float(FloatWidth::F64))) => {
let reg = self.storage_manager.claim_float_reg(&mut self.buf, sym);
let val = *x;
ASM::mov_freg64_imm64(&mut self.buf, &mut self.relocs, reg, val);
}
(Literal::Float(x), Layout::Builtin(Builtin::Float(FloatWidth::F32))) => {
(Literal::Float(x), LayoutRepr::Builtin(Builtin::Float(FloatWidth::F32))) => {
let reg = self.storage_manager.claim_float_reg(&mut self.buf, sym);
let val = *x as f32;
ASM::mov_freg32_imm32(&mut self.buf, &mut self.relocs, reg, val);
}
(Literal::Decimal(bytes), Layout::Builtin(Builtin::Decimal)) => {
(Literal::Decimal(bytes), LayoutRepr::Builtin(Builtin::Decimal)) => {
self.storage_manager.with_tmp_general_reg(
&mut self.buf,
|storage_manager, buf, reg| {
@ -2755,7 +2768,7 @@ impl<
},
);
}
(Literal::Str(x), Layout::Builtin(Builtin::Str)) => {
(Literal::Str(x), LayoutRepr::Builtin(Builtin::Str)) => {
if x.len() < 24 {
// Load small string.
self.storage_manager.with_tmp_general_reg(
@ -2822,8 +2835,8 @@ impl<
CC::FLOAT_RETURN_REGS[0],
);
}
other => match self.layout_interner.get(other) {
Layout::Boxed(_) => {
other => match self.layout_interner.get(other).repr {
LayoutRepr::Boxed(_) => {
// treat like a 64-bit integer
self.storage_manager.load_to_specified_general_reg(
&mut self.buf,
@ -2831,7 +2844,7 @@ impl<
CC::GENERAL_RETURN_REGS[0],
);
}
Layout::LambdaSet(lambda_set) => {
LayoutRepr::LambdaSet(lambda_set) => {
self.return_symbol(sym, &lambda_set.runtime_representation())
}
_ => {
@ -3327,8 +3340,8 @@ impl<
element_in_layout: InLayout<'a>,
dst: Symbol,
) {
match layout_interner.get(element_in_layout) {
Layout::Builtin(builtin) => match builtin {
match layout_interner.get(element_in_layout).repr {
LayoutRepr::Builtin(builtin) => match builtin {
Builtin::Int(int_width) => match int_width {
IntWidth::I128 | IntWidth::U128 => {
// can we treat this as 2 u64's?
@ -3374,13 +3387,13 @@ impl<
}
},
Layout::Boxed(_) => {
LayoutRepr::Boxed(_) => {
// the same as 64-bit integer (for 64-bit targets)
let dst_reg = storage_manager.claim_general_reg(buf, &dst);
ASM::mov_reg64_mem64_offset32(buf, dst_reg, ptr_reg, 0);
}
Layout::Struct { .. } => {
LayoutRepr::Struct { .. } => {
// put it on the stack
let stack_size = layout_interner.stack_size(element_in_layout);
@ -3389,7 +3402,7 @@ impl<
});
}
Layout::Union(UnionLayout::NonRecursive(_)) => {
LayoutRepr::Union(UnionLayout::NonRecursive(_)) => {
// put it on the stack
let stack_size = layout_interner.stack_size(element_in_layout);
@ -3398,7 +3411,7 @@ impl<
});
}
Layout::LambdaSet(lambda_set) => {
LayoutRepr::LambdaSet(lambda_set) => {
Self::ptr_read(
buf,
storage_manager,
@ -3424,32 +3437,32 @@ impl<
element_layout: Layout<'a>,
value: Symbol,
) {
match element_layout {
Layout::Builtin(Builtin::Int(IntWidth::I64 | IntWidth::U64)) => {
match element_layout.repr {
LayoutRepr::Builtin(Builtin::Int(IntWidth::I64 | IntWidth::U64)) => {
let sym_reg = storage_manager.load_to_general_reg(buf, &value);
ASM::mov_mem64_offset32_reg64(buf, ptr_reg, element_offset, sym_reg);
}
Layout::Builtin(Builtin::Int(IntWidth::I32 | IntWidth::U32)) => {
LayoutRepr::Builtin(Builtin::Int(IntWidth::I32 | IntWidth::U32)) => {
let sym_reg = storage_manager.load_to_general_reg(buf, &value);
ASM::mov_mem32_offset32_reg32(buf, ptr_reg, element_offset, sym_reg);
}
Layout::Builtin(Builtin::Int(IntWidth::I16 | IntWidth::U16)) => {
LayoutRepr::Builtin(Builtin::Int(IntWidth::I16 | IntWidth::U16)) => {
let sym_reg = storage_manager.load_to_general_reg(buf, &value);
ASM::mov_mem16_offset32_reg16(buf, ptr_reg, element_offset, sym_reg);
}
Layout::Builtin(Builtin::Int(IntWidth::I8 | IntWidth::U8) | Builtin::Bool) => {
LayoutRepr::Builtin(Builtin::Int(IntWidth::I8 | IntWidth::U8) | Builtin::Bool) => {
let sym_reg = storage_manager.load_to_general_reg(buf, &value);
ASM::mov_mem8_offset32_reg8(buf, ptr_reg, element_offset, sym_reg);
}
Layout::Builtin(Builtin::Float(FloatWidth::F64 | FloatWidth::F32)) => {
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F64 | FloatWidth::F32)) => {
let sym_reg = storage_manager.load_to_float_reg(buf, &value);
ASM::movesd_mem64_offset32_freg64(buf, ptr_reg, element_offset, sym_reg);
}
Layout::Boxed(_) => {
LayoutRepr::Boxed(_) => {
let sym_reg = storage_manager.load_to_general_reg(buf, &value);
ASM::mov_mem64_offset32_reg64(buf, ptr_reg, element_offset, sym_reg);
}
Layout::LambdaSet(lambda_set) => {
LayoutRepr::LambdaSet(lambda_set) => {
let layout = layout_interner.get(lambda_set.runtime_representation());
Self::ptr_write(

View file

@ -11,7 +11,8 @@ use roc_module::symbol::Symbol;
use roc_mono::{
ir::{JoinPointId, Param},
layout::{
Builtin, InLayout, Layout, LayoutInterner, STLayoutInterner, TagIdIntType, UnionLayout,
Builtin, InLayout, Layout, LayoutInterner, LayoutRepr, STLayoutInterner, TagIdIntType,
UnionLayout,
},
};
use roc_target::TargetInfo;
@ -667,13 +668,13 @@ impl<
let mut in_layout = *layout;
let layout = loop {
match layout_interner.get(in_layout) {
Layout::LambdaSet(inner) => in_layout = inner.runtime_representation(),
match layout_interner.get(in_layout).repr {
LayoutRepr::LambdaSet(inner) => in_layout = inner.runtime_representation(),
other => break other,
}
};
if let Layout::Struct { field_layouts, .. } = layout {
if let LayoutRepr::Struct { field_layouts, .. } = layout {
let mut current_offset = base_offset;
for (field, field_layout) in fields.iter().zip(field_layouts.iter()) {
self.copy_symbol_to_stack_offset(
@ -780,8 +781,8 @@ impl<
sym: &Symbol,
layout: &InLayout<'a>,
) {
match layout_interner.get(*layout) {
Layout::Builtin(builtin) => match builtin {
match layout_interner.get(*layout).repr {
LayoutRepr::Builtin(builtin) => match builtin {
Builtin::Int(int_width) => match int_width {
IntWidth::I128 | IntWidth::U128 => {
let (from_offset, size) = self.stack_offset_and_size(sym);
@ -844,13 +845,13 @@ impl<
self.copy_to_stack_offset(buf, size, from_offset, to_offset)
}
},
Layout::Boxed(_) => {
LayoutRepr::Boxed(_) => {
// like a 64-bit integer
debug_assert_eq!(to_offset % 8, 0);
let reg = self.load_to_general_reg(buf, sym);
ASM::mov_base32_reg64(buf, to_offset, reg);
}
Layout::LambdaSet(lambda_set) => {
LayoutRepr::LambdaSet(lambda_set) => {
// like its runtime representation
self.copy_symbol_to_stack_offset(
layout_interner,
@ -861,7 +862,7 @@ impl<
)
}
_ if layout_interner.stack_size(*layout) == 0 => {}
Layout::Struct { .. } | Layout::Union(UnionLayout::NonRecursive(_)) => {
LayoutRepr::Struct { .. } | LayoutRepr::Union(UnionLayout::NonRecursive(_)) => {
let (from_offset, size) = self.stack_offset_and_size(sym);
debug_assert_eq!(size, layout_interner.stack_size(*layout));
@ -1172,7 +1173,7 @@ impl<
.insert(symbol, Rc::new((base_offset, 8)));
}
_ => {
if let Layout::LambdaSet(lambda_set) = layout_interner.get(layout) {
if let LayoutRepr::LambdaSet(lambda_set) = layout_interner.get(layout).repr {
self.joinpoint_argument_stack_storage(
layout_interner,
symbol,
@ -1236,7 +1237,7 @@ impl<
ASM::mov_base32_freg64(buf, base_offset, reg);
}
_ => {
if let Layout::LambdaSet(lambda_set) = layout_interner.get(layout) {
if let LayoutRepr::LambdaSet(lambda_set) = layout_interner.get(layout).repr {
self.jump_argument_stack_storage(
layout_interner,
buf,
@ -1535,9 +1536,9 @@ impl<
fn is_primitive(layout_interner: &mut STLayoutInterner<'_>, layout: InLayout<'_>) -> bool {
match layout {
single_register_layouts!() => true,
_ => match layout_interner.get(layout) {
Layout::Boxed(_) => true,
Layout::LambdaSet(lambda_set) => {
_ => match layout_interner.get(layout).repr {
LayoutRepr::Boxed(_) => true,
LayoutRepr::LambdaSet(lambda_set) => {
is_primitive(layout_interner, lambda_set.runtime_representation())
}
_ => false,

View file

@ -7,7 +7,9 @@ use bumpalo::collections::Vec;
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, STLayoutInterner, UnionLayout};
use roc_mono::layout::{
Builtin, InLayout, Layout, LayoutInterner, LayoutRepr, STLayoutInterner, UnionLayout,
};
use super::{CompareOperation, RegisterWidth};
@ -507,19 +509,19 @@ impl X64_64SystemVStoreArgs {
}
other => {
// look at the layout in more detail
match layout_interner.get(other) {
Layout::Boxed(_) => {
match layout_interner.get(other).repr {
LayoutRepr::Boxed(_) => {
// treat boxed like a 64-bit integer
self.store_arg_general(buf, storage_manager, sym)
}
Layout::LambdaSet(lambda_set) => self.store_arg(
LayoutRepr::LambdaSet(lambda_set) => self.store_arg(
buf,
storage_manager,
layout_interner,
sym,
lambda_set.runtime_representation(),
),
Layout::Struct { .. } => {
LayoutRepr::Struct { .. } => {
// for now, just also store this on the stack
let (base_offset, size) = storage_manager.stack_offset_and_size(&sym);
debug_assert_eq!(base_offset % 8, 0);
@ -537,7 +539,7 @@ impl X64_64SystemVStoreArgs {
}
self.tmp_stack_offset += size as i32;
}
Layout::Union(UnionLayout::NonRecursive(_)) => {
LayoutRepr::Union(UnionLayout::NonRecursive(_)) => {
type ASM = X86_64Assembler;
let tmp_reg = Self::GENERAL_RETURN_REGS[0];
@ -668,27 +670,27 @@ 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) {
Layout::Boxed(_) => {
other => match layout_interner.get(other).repr {
LayoutRepr::Boxed(_) => {
// boxed layouts are pointers, which we treat as 64-bit integers
self.load_arg_general(storage_manager, sym)
}
Layout::LambdaSet(lambda_set) => self.load_arg(
LayoutRepr::LambdaSet(lambda_set) => self.load_arg(
storage_manager,
layout_interner,
sym,
lambda_set.runtime_representation(),
),
Layout::Struct { .. } => {
LayoutRepr::Struct { .. } => {
// for now, just also store this on the stack
storage_manager.complex_stack_arg(&sym, self.argument_offset, stack_size);
self.argument_offset += stack_size as i32;
}
Layout::Builtin(Builtin::Int(IntWidth::U128 | IntWidth::I128)) => {
LayoutRepr::Builtin(Builtin::Int(IntWidth::U128 | IntWidth::I128)) => {
storage_manager.complex_stack_arg(&sym, self.argument_offset, stack_size);
self.argument_offset += stack_size as i32;
}
Layout::Union(UnionLayout::NonRecursive(_)) => {
LayoutRepr::Union(UnionLayout::NonRecursive(_)) => {
// for now, just also store this on the stack
storage_manager.complex_stack_arg(&sym, self.argument_offset, stack_size);
self.argument_offset += stack_size as i32;

View file

@ -18,8 +18,8 @@ use roc_mono::ir::{
Literal, Param, Proc, ProcLayout, SelfRecursive, Stmt,
};
use roc_mono::layout::{
Builtin, InLayout, Layout, LayoutIds, LayoutInterner, STLayoutInterner, TagIdIntType,
UnionLayout,
Builtin, InLayout, Layout, LayoutIds, LayoutInterner, LayoutRepr, STLayoutInterner,
TagIdIntType, UnionLayout,
};
use roc_mono::list_element_layout;
@ -174,8 +174,8 @@ trait Backend<'a> {
}
fn list_argument(&mut self, list_layout: InLayout<'a>) -> ListArgument<'a> {
let element_layout = match self.interner().get(list_layout) {
Layout::Builtin(Builtin::List(e)) => e,
let element_layout = match self.interner().get(list_layout).repr {
LayoutRepr::Builtin(Builtin::List(e)) => e,
_ => unreachable!(),
};
@ -196,7 +196,9 @@ trait Backend<'a> {
}
fn increment_fn_pointer(&mut self, layout: InLayout<'a>) -> Symbol {
let box_layout = self.interner_mut().insert(Layout::Boxed(layout));
let box_layout = self.interner_mut().insert(Layout {
repr: LayoutRepr::Boxed(layout),
});
let element_increment = self.debug_symbol("element_increment");
let element_increment_symbol = self.build_indirect_inc(layout);
@ -214,7 +216,9 @@ trait Backend<'a> {
}
fn decrement_fn_pointer(&mut self, layout: InLayout<'a>) -> Symbol {
let box_layout = self.interner_mut().insert(Layout::Boxed(layout));
let box_layout = self.interner_mut().insert(Layout {
repr: LayoutRepr::Boxed(layout),
});
let element_decrement = self.debug_symbol("element_decrement");
let element_decrement_symbol = self.build_indirect_dec(layout);
@ -609,8 +613,8 @@ trait Backend<'a> {
self.tag(sym, arguments, tag_layout, *tag_id);
}
Expr::ExprBox { symbol: value } => {
let element_layout = match self.interner().get(*layout) {
Layout::Boxed(boxed) => boxed,
let element_layout = match self.interner().get(*layout).repr {
LayoutRepr::Boxed(boxed) => boxed,
_ => unreachable!("{:?}", self.interner().dbg(*layout)),
};
@ -782,78 +786,90 @@ trait Backend<'a> {
);
self.build_num_sub_wrap(sym, &args[0], &args[1], ret_layout)
}
LowLevel::NumSubSaturated => match self.interner().get(*ret_layout) {
Layout::Builtin(Builtin::Int(int_width)) => self.build_fn_call(
LowLevel::NumSubSaturated => match self.interner().get(*ret_layout).repr {
LayoutRepr::Builtin(Builtin::Int(int_width)) => self.build_fn_call(
sym,
bitcode::NUM_SUB_SATURATED_INT[int_width].to_string(),
args,
arg_layouts,
ret_layout,
),
Layout::Builtin(Builtin::Float(FloatWidth::F32)) => {
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F32)) => {
self.build_num_sub(sym, &args[0], &args[1], ret_layout)
}
Layout::Builtin(Builtin::Float(FloatWidth::F64)) => {
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F64)) => {
// saturated sub is just normal sub
self.build_num_sub(sym, &args[0], &args[1], ret_layout)
}
Layout::Builtin(Builtin::Decimal) => {
LayoutRepr::Builtin(Builtin::Decimal) => {
// self.load_args_and_call_zig(backend, bitcode::DEC_SUB_SATURATED)
todo!()
}
_ => internal_error!("invalid return type"),
},
LowLevel::NumBitwiseAnd => {
if let Layout::Builtin(Builtin::Int(int_width)) = self.interner().get(*ret_layout) {
if let LayoutRepr::Builtin(Builtin::Int(int_width)) =
self.interner().get(*ret_layout).repr
{
self.build_int_bitwise_and(sym, &args[0], &args[1], int_width)
} else {
internal_error!("bitwise and on a non-integer")
}
}
LowLevel::NumBitwiseOr => {
if let Layout::Builtin(Builtin::Int(int_width)) = self.interner().get(*ret_layout) {
if let LayoutRepr::Builtin(Builtin::Int(int_width)) =
self.interner().get(*ret_layout).repr
{
self.build_int_bitwise_or(sym, &args[0], &args[1], int_width)
} else {
internal_error!("bitwise or on a non-integer")
}
}
LowLevel::NumBitwiseXor => {
if let Layout::Builtin(Builtin::Int(int_width)) = self.interner().get(*ret_layout) {
if let LayoutRepr::Builtin(Builtin::Int(int_width)) =
self.interner().get(*ret_layout).repr
{
self.build_int_bitwise_xor(sym, &args[0], &args[1], int_width)
} else {
internal_error!("bitwise xor on a non-integer")
}
}
LowLevel::And => {
if let Layout::Builtin(Builtin::Bool) = self.interner().get(*ret_layout) {
if let LayoutRepr::Builtin(Builtin::Bool) = self.interner().get(*ret_layout).repr {
self.build_int_bitwise_and(sym, &args[0], &args[1], IntWidth::U8)
} else {
internal_error!("bitwise and on a non-integer")
}
}
LowLevel::Or => {
if let Layout::Builtin(Builtin::Bool) = self.interner().get(*ret_layout) {
if let LayoutRepr::Builtin(Builtin::Bool) = self.interner().get(*ret_layout).repr {
self.build_int_bitwise_or(sym, &args[0], &args[1], IntWidth::U8)
} else {
internal_error!("bitwise or on a non-integer")
}
}
LowLevel::NumShiftLeftBy => {
if let Layout::Builtin(Builtin::Int(int_width)) = self.interner().get(*ret_layout) {
if let LayoutRepr::Builtin(Builtin::Int(int_width)) =
self.interner().get(*ret_layout).repr
{
self.build_int_shift_left(sym, &args[0], &args[1], int_width)
} else {
internal_error!("shift left on a non-integer")
}
}
LowLevel::NumShiftRightBy => {
if let Layout::Builtin(Builtin::Int(int_width)) = self.interner().get(*ret_layout) {
if let LayoutRepr::Builtin(Builtin::Int(int_width)) =
self.interner().get(*ret_layout).repr
{
self.build_int_shift_right(sym, &args[0], &args[1], int_width)
} else {
internal_error!("shift right on a non-integer")
}
}
LowLevel::NumShiftRightZfBy => {
if let Layout::Builtin(Builtin::Int(int_width)) = self.interner().get(*ret_layout) {
if let LayoutRepr::Builtin(Builtin::Int(int_width)) =
self.interner().get(*ret_layout).repr
{
self.build_int_shift_right_zero_fill(sym, &args[0], &args[1], int_width)
} else {
internal_error!("shift right zero-fill on a non-integer")
@ -1273,18 +1289,18 @@ trait Backend<'a> {
ret_layout,
),
LowLevel::StrToNum => {
let number_layout = match self.interner().get(*ret_layout) {
Layout::Struct { field_layouts, .. } => field_layouts[0], // TODO: why is it sometimes a struct?
let number_layout = match self.interner().get(*ret_layout).repr {
LayoutRepr::Struct { field_layouts, .. } => field_layouts[0], // TODO: why is it sometimes a struct?
_ => unreachable!(),
};
// match on the return layout to figure out which zig builtin we need
let intrinsic = match self.interner().get(number_layout) {
Layout::Builtin(Builtin::Int(int_width)) => &bitcode::STR_TO_INT[int_width],
Layout::Builtin(Builtin::Float(float_width)) => {
let intrinsic = match self.interner().get(number_layout).repr {
LayoutRepr::Builtin(Builtin::Int(int_width)) => &bitcode::STR_TO_INT[int_width],
LayoutRepr::Builtin(Builtin::Float(float_width)) => {
&bitcode::STR_TO_FLOAT[float_width]
}
Layout::Builtin(Builtin::Decimal) => bitcode::DEC_FROM_STR,
LayoutRepr::Builtin(Builtin::Decimal) => bitcode::DEC_FROM_STR,
_ => unreachable!(),
};
@ -1299,8 +1315,8 @@ trait Backend<'a> {
self.build_ptr_cast(sym, &args[0])
}
LowLevel::PtrWrite => {
let element_layout = match self.interner().get(*ret_layout) {
Layout::Boxed(boxed) => boxed,
let element_layout = match self.interner().get(*ret_layout).repr {
LayoutRepr::Boxed(boxed) => boxed,
_ => unreachable!("cannot write to {:?}", self.interner().dbg(*ret_layout)),
};
@ -1343,10 +1359,10 @@ trait Backend<'a> {
),
LowLevel::NumToStr => {
let arg_layout = arg_layouts[0];
let intrinsic = match self.interner().get(arg_layout) {
Layout::Builtin(Builtin::Int(width)) => &bitcode::STR_FROM_INT[width],
Layout::Builtin(Builtin::Float(width)) => &bitcode::STR_FROM_FLOAT[width],
Layout::Builtin(Builtin::Decimal) => bitcode::DEC_TO_STR,
let intrinsic = match self.interner().get(arg_layout).repr {
LayoutRepr::Builtin(Builtin::Int(width)) => &bitcode::STR_FROM_INT[width],
LayoutRepr::Builtin(Builtin::Float(width)) => &bitcode::STR_FROM_FLOAT[width],
LayoutRepr::Builtin(Builtin::Decimal) => bitcode::DEC_TO_STR,
x => internal_error!("NumToStr is not defined for {:?}", x),
};
@ -1357,13 +1373,13 @@ trait Backend<'a> {
self.build_fn_call(sym, intrinsic, args, arg_layouts, ret_layout);
}
LowLevel::NumIntCast => {
let source_width = match self.interner().get(arg_layouts[0]) {
Layout::Builtin(Builtin::Int(width)) => width,
let source_width = match self.interner().get(arg_layouts[0]).repr {
LayoutRepr::Builtin(Builtin::Int(width)) => width,
_ => unreachable!(),
};
let target_width = match self.interner().get(*ret_layout) {
Layout::Builtin(Builtin::Int(width)) => width,
let target_width = match self.interner().get(*ret_layout).repr {
LayoutRepr::Builtin(Builtin::Int(width)) => width,
_ => unreachable!(),
};

View file

@ -456,9 +456,9 @@ fn build_exposed_generic_proc<'a, B: Backend<'a>>(backend: &mut B, proc: &Proc<'
let s2 = backend.debug_symbol_in(platform, "s2");
let s3 = backend.debug_symbol_in(platform, "s3");
let box_layout = backend
.interner_mut()
.insert(roc_mono::layout::Layout::Boxed(proc.ret_layout));
let box_layout = backend.interner_mut().insert(Layout {
repr: roc_mono::layout::LayoutRepr::Boxed(proc.ret_layout),
});
let mut args = bumpalo::collections::Vec::new_in(arena);
args.extend(proc.args);