mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 05:19:08 +00:00
Update llvm backend
This commit is contained in:
parent
9d70c45781
commit
03ece6e274
10 changed files with 696 additions and 701 deletions
|
@ -27,8 +27,8 @@ pub fn generic_eq<'a, 'ctx, 'env>(
|
|||
layout_ids: &mut LayoutIds<'a>,
|
||||
lhs_val: BasicValueEnum<'ctx>,
|
||||
rhs_val: BasicValueEnum<'ctx>,
|
||||
lhs_layout: &Layout<'a>,
|
||||
rhs_layout: &Layout<'a>,
|
||||
lhs_layout: InLayout<'a>,
|
||||
rhs_layout: InLayout<'a>,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
build_eq(
|
||||
env,
|
||||
|
@ -48,8 +48,8 @@ pub fn generic_neq<'a, 'ctx, 'env>(
|
|||
layout_ids: &mut LayoutIds<'a>,
|
||||
lhs_val: BasicValueEnum<'ctx>,
|
||||
rhs_val: BasicValueEnum<'ctx>,
|
||||
lhs_layout: &Layout<'a>,
|
||||
rhs_layout: &Layout<'a>,
|
||||
lhs_layout: InLayout<'a>,
|
||||
rhs_layout: InLayout<'a>,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
build_neq(
|
||||
env,
|
||||
|
@ -129,16 +129,19 @@ fn build_eq_builtin<'a, 'ctx, 'env>(
|
|||
Builtin::Decimal => dec_binop_with_unchecked(env, bitcode::DEC_EQ, lhs_val, rhs_val),
|
||||
|
||||
Builtin::Str => str_equal(env, lhs_val, rhs_val),
|
||||
Builtin::List(elem) => build_list_eq(
|
||||
env,
|
||||
layout_interner,
|
||||
layout_ids,
|
||||
&Layout::Builtin(*builtin),
|
||||
*elem,
|
||||
lhs_val.into_struct_value(),
|
||||
rhs_val.into_struct_value(),
|
||||
when_recursive,
|
||||
),
|
||||
Builtin::List(elem) => {
|
||||
let list_layout = layout_interner.insert(Layout::Builtin(*builtin));
|
||||
build_list_eq(
|
||||
env,
|
||||
layout_interner,
|
||||
layout_ids,
|
||||
list_layout,
|
||||
*elem,
|
||||
lhs_val.into_struct_value(),
|
||||
rhs_val.into_struct_value(),
|
||||
when_recursive,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,12 +151,11 @@ fn build_eq<'a, 'ctx, 'env>(
|
|||
layout_ids: &mut LayoutIds<'a>,
|
||||
lhs_val: BasicValueEnum<'ctx>,
|
||||
rhs_val: BasicValueEnum<'ctx>,
|
||||
lhs_layout: &Layout<'a>,
|
||||
rhs_layout: &Layout<'a>,
|
||||
lhs_layout: InLayout<'a>,
|
||||
rhs_layout: InLayout<'a>,
|
||||
when_recursive: WhenRecursive<'a>,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
let lhs_layout = &lhs_layout.runtime_representation(layout_interner);
|
||||
let rhs_layout = &rhs_layout.runtime_representation(layout_interner);
|
||||
let lhs_layout_raw = &layout_interner.runtime_representation(lhs_layout);
|
||||
if lhs_layout != rhs_layout {
|
||||
panic!(
|
||||
"Equality of different layouts; did you have a type mismatch?\n{:?} == {:?}",
|
||||
|
@ -161,7 +163,7 @@ fn build_eq<'a, 'ctx, 'env>(
|
|||
);
|
||||
}
|
||||
|
||||
match lhs_layout {
|
||||
match lhs_layout_raw {
|
||||
Layout::Builtin(builtin) => build_eq_builtin(
|
||||
env,
|
||||
layout_interner,
|
||||
|
@ -211,9 +213,9 @@ fn build_eq<'a, 'ctx, 'env>(
|
|||
}
|
||||
|
||||
WhenRecursive::Loop(union_layout) => {
|
||||
let layout = Layout::Union(union_layout);
|
||||
let layout = layout_interner.insert(Layout::Union(union_layout));
|
||||
|
||||
let bt = basic_type_from_layout(env, layout_interner, &layout);
|
||||
let bt = basic_type_from_layout(env, layout_interner, layout);
|
||||
|
||||
// cast the i64 pointer to a pointer to block of memory
|
||||
let field1_cast = env.builder.build_pointer_cast(
|
||||
|
@ -314,11 +316,12 @@ fn build_neq_builtin<'a, 'ctx, 'env>(
|
|||
result.into()
|
||||
}
|
||||
Builtin::List(elem) => {
|
||||
let builtin_layout = layout_interner.insert(Layout::Builtin(*builtin));
|
||||
let is_equal = build_list_eq(
|
||||
env,
|
||||
layout_interner,
|
||||
layout_ids,
|
||||
&Layout::Builtin(*builtin),
|
||||
builtin_layout,
|
||||
*elem,
|
||||
lhs_val.into_struct_value(),
|
||||
rhs_val.into_struct_value(),
|
||||
|
@ -339,8 +342,8 @@ fn build_neq<'a, 'ctx, 'env>(
|
|||
layout_ids: &mut LayoutIds<'a>,
|
||||
lhs_val: BasicValueEnum<'ctx>,
|
||||
rhs_val: BasicValueEnum<'ctx>,
|
||||
lhs_layout: &Layout<'a>,
|
||||
rhs_layout: &Layout<'a>,
|
||||
lhs_layout: InLayout<'a>,
|
||||
rhs_layout: InLayout<'a>,
|
||||
when_recursive: WhenRecursive<'a>,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
if lhs_layout != rhs_layout {
|
||||
|
@ -350,14 +353,14 @@ fn build_neq<'a, 'ctx, 'env>(
|
|||
);
|
||||
}
|
||||
|
||||
match lhs_layout {
|
||||
match layout_interner.get(lhs_layout) {
|
||||
Layout::Builtin(builtin) => build_neq_builtin(
|
||||
env,
|
||||
layout_interner,
|
||||
layout_ids,
|
||||
lhs_val,
|
||||
rhs_val,
|
||||
builtin,
|
||||
&builtin,
|
||||
when_recursive,
|
||||
),
|
||||
|
||||
|
@ -384,7 +387,7 @@ fn build_neq<'a, 'ctx, 'env>(
|
|||
layout_interner,
|
||||
layout_ids,
|
||||
when_recursive,
|
||||
union_layout,
|
||||
&union_layout,
|
||||
lhs_val,
|
||||
rhs_val,
|
||||
)
|
||||
|
@ -402,7 +405,7 @@ fn build_neq<'a, 'ctx, 'env>(
|
|||
layout_ids,
|
||||
when_recursive,
|
||||
lhs_layout,
|
||||
*inner_layout,
|
||||
inner_layout,
|
||||
lhs_val,
|
||||
rhs_val,
|
||||
)
|
||||
|
@ -424,7 +427,7 @@ fn build_list_eq<'a, 'ctx, 'env>(
|
|||
env: &Env<'a, 'ctx, 'env>,
|
||||
layout_interner: &mut STLayoutInterner<'a>,
|
||||
layout_ids: &mut LayoutIds<'a>,
|
||||
list_layout: &Layout<'a>,
|
||||
list_layout: InLayout<'a>,
|
||||
element_layout: InLayout<'a>,
|
||||
list1: StructValue<'ctx>,
|
||||
list2: StructValue<'ctx>,
|
||||
|
@ -436,6 +439,7 @@ fn build_list_eq<'a, 'ctx, 'env>(
|
|||
let symbol = Symbol::LIST_EQ;
|
||||
let element_layout = layout_interner.get(element_layout);
|
||||
let element_layout = when_recursive.unwrap_recursive_pointer(element_layout);
|
||||
let element_layout = layout_interner.insert(element_layout);
|
||||
let fn_name = layout_ids
|
||||
.get(symbol, &element_layout)
|
||||
.to_symbol_string(symbol, &env.interns);
|
||||
|
@ -458,7 +462,7 @@ fn build_list_eq<'a, 'ctx, 'env>(
|
|||
layout_ids,
|
||||
when_recursive,
|
||||
function_value,
|
||||
&element_layout,
|
||||
element_layout,
|
||||
);
|
||||
|
||||
function_value
|
||||
|
@ -483,7 +487,7 @@ fn build_list_eq_help<'a, 'ctx, 'env>(
|
|||
layout_ids: &mut LayoutIds<'a>,
|
||||
when_recursive: WhenRecursive<'a>,
|
||||
parent: FunctionValue<'ctx>,
|
||||
element_layout: &Layout<'a>,
|
||||
element_layout: InLayout<'a>,
|
||||
) {
|
||||
let ctx = env.context;
|
||||
let builder = env.builder;
|
||||
|
@ -582,14 +586,14 @@ fn build_list_eq_help<'a, 'ctx, 'env>(
|
|||
let elem_ptr = unsafe {
|
||||
builder.new_build_in_bounds_gep(element_type, ptr1, &[curr_index], "load_index")
|
||||
};
|
||||
load_roc_value(env, layout_interner, *element_layout, elem_ptr, "get_elem")
|
||||
load_roc_value(env, layout_interner, element_layout, elem_ptr, "get_elem")
|
||||
};
|
||||
|
||||
let elem2 = {
|
||||
let elem_ptr = unsafe {
|
||||
builder.new_build_in_bounds_gep(element_type, ptr2, &[curr_index], "load_index")
|
||||
};
|
||||
load_roc_value(env, layout_interner, *element_layout, elem_ptr, "get_elem")
|
||||
load_roc_value(env, layout_interner, element_layout, elem_ptr, "get_elem")
|
||||
};
|
||||
|
||||
let are_equal = build_eq(
|
||||
|
@ -641,7 +645,7 @@ fn build_struct_eq<'a, 'ctx, 'env>(
|
|||
env: &Env<'a, 'ctx, 'env>,
|
||||
layout_interner: &mut STLayoutInterner<'a>,
|
||||
layout_ids: &mut LayoutIds<'a>,
|
||||
field_layouts: &'a [Layout<'a>],
|
||||
field_layouts: &'a [InLayout<'a>],
|
||||
when_recursive: WhenRecursive<'a>,
|
||||
struct1: StructValue<'ctx>,
|
||||
struct2: StructValue<'ctx>,
|
||||
|
@ -649,7 +653,7 @@ fn build_struct_eq<'a, 'ctx, 'env>(
|
|||
let block = env.builder.get_insert_block().expect("to be in a function");
|
||||
let di_location = env.builder.get_current_debug_location().unwrap();
|
||||
|
||||
let struct_layout = Layout::struct_no_name_order(field_layouts);
|
||||
let struct_layout = layout_interner.insert(Layout::struct_no_name_order(field_layouts));
|
||||
|
||||
let symbol = Symbol::GENERIC_EQ;
|
||||
let fn_name = layout_ids
|
||||
|
@ -659,7 +663,7 @@ fn build_struct_eq<'a, 'ctx, 'env>(
|
|||
let function = match env.module.get_function(fn_name.as_str()) {
|
||||
Some(function_value) => function_value,
|
||||
None => {
|
||||
let arg_type = basic_type_from_layout(env, layout_interner, &struct_layout);
|
||||
let arg_type = basic_type_from_layout(env, layout_interner, struct_layout);
|
||||
|
||||
let function_value = crate::llvm::refcounting::build_header_help(
|
||||
env,
|
||||
|
@ -699,7 +703,7 @@ fn build_struct_eq_help<'a, 'ctx, 'env>(
|
|||
layout_ids: &mut LayoutIds<'a>,
|
||||
parent: FunctionValue<'ctx>,
|
||||
when_recursive: WhenRecursive<'a>,
|
||||
field_layouts: &[Layout<'a>],
|
||||
field_layouts: &[InLayout<'a>],
|
||||
) {
|
||||
let ctx = env.context;
|
||||
let builder = env.builder;
|
||||
|
@ -756,15 +760,15 @@ fn build_struct_eq_help<'a, 'ctx, 'env>(
|
|||
.build_extract_value(struct2, index as u32, "eq_field")
|
||||
.unwrap();
|
||||
|
||||
let are_equal = if let Layout::RecursivePointer = field_layout {
|
||||
let are_equal = if let Layout::RecursivePointer = layout_interner.get(*field_layout) {
|
||||
match &when_recursive {
|
||||
WhenRecursive::Unreachable => {
|
||||
unreachable!("The current layout should not be recursive, but is")
|
||||
}
|
||||
WhenRecursive::Loop(union_layout) => {
|
||||
let field_layout = Layout::Union(*union_layout);
|
||||
let field_layout = layout_interner.insert(Layout::Union(*union_layout));
|
||||
|
||||
let bt = basic_type_from_layout(env, layout_interner, &field_layout);
|
||||
let bt = basic_type_from_layout(env, layout_interner, field_layout);
|
||||
|
||||
// cast the i64 pointer to a pointer to block of memory
|
||||
let field1_cast = env.builder.build_pointer_cast(
|
||||
|
@ -785,8 +789,8 @@ fn build_struct_eq_help<'a, 'ctx, 'env>(
|
|||
layout_ids,
|
||||
field1_cast.into(),
|
||||
field2_cast.into(),
|
||||
&field_layout,
|
||||
&field_layout,
|
||||
field_layout,
|
||||
field_layout,
|
||||
WhenRecursive::Loop(*union_layout),
|
||||
)
|
||||
.into_int_value()
|
||||
|
@ -801,8 +805,8 @@ fn build_struct_eq_help<'a, 'ctx, 'env>(
|
|||
layout_ids,
|
||||
lhs,
|
||||
rhs,
|
||||
field_layout,
|
||||
field_layout,
|
||||
*field_layout,
|
||||
*field_layout,
|
||||
when_recursive,
|
||||
)
|
||||
.into_int_value()
|
||||
|
@ -842,7 +846,7 @@ fn build_tag_eq<'a, 'ctx, 'env>(
|
|||
let block = env.builder.get_insert_block().expect("to be in a function");
|
||||
let di_location = env.builder.get_current_debug_location().unwrap();
|
||||
|
||||
let tag_layout = Layout::Union(*union_layout);
|
||||
let tag_layout = layout_interner.insert(Layout::Union(*union_layout));
|
||||
let symbol = Symbol::GENERIC_EQ;
|
||||
let fn_name = layout_ids
|
||||
.get(symbol, &tag_layout)
|
||||
|
@ -1285,13 +1289,13 @@ fn eq_ptr_to_struct<'a, 'ctx, 'env>(
|
|||
layout_ids: &mut LayoutIds<'a>,
|
||||
union_layout: &UnionLayout<'a>,
|
||||
opt_when_recursive: Option<WhenRecursive<'a>>,
|
||||
field_layouts: &'a [Layout<'a>],
|
||||
field_layouts: &'a [InLayout<'a>],
|
||||
tag1: PointerValue<'ctx>,
|
||||
tag2: PointerValue<'ctx>,
|
||||
) -> IntValue<'ctx> {
|
||||
let struct_layout = Layout::struct_no_name_order(field_layouts);
|
||||
let struct_layout = layout_interner.insert(Layout::struct_no_name_order(field_layouts));
|
||||
|
||||
let wrapper_type = basic_type_from_layout(env, layout_interner, &struct_layout);
|
||||
let wrapper_type = basic_type_from_layout(env, layout_interner, struct_layout);
|
||||
debug_assert!(wrapper_type.is_struct_type());
|
||||
|
||||
// cast the opaque pointer to a pointer of the correct shape
|
||||
|
@ -1336,7 +1340,7 @@ fn build_box_eq<'a, 'ctx, 'env>(
|
|||
layout_interner: &mut STLayoutInterner<'a>,
|
||||
layout_ids: &mut LayoutIds<'a>,
|
||||
when_recursive: WhenRecursive<'a>,
|
||||
box_layout: &Layout<'a>,
|
||||
box_layout: InLayout<'a>,
|
||||
inner_layout: InLayout<'a>,
|
||||
tag1: BasicValueEnum<'ctx>,
|
||||
tag2: BasicValueEnum<'ctx>,
|
||||
|
@ -1346,7 +1350,7 @@ fn build_box_eq<'a, 'ctx, 'env>(
|
|||
|
||||
let symbol = Symbol::GENERIC_EQ;
|
||||
let fn_name = layout_ids
|
||||
.get(symbol, box_layout)
|
||||
.get(symbol, &box_layout)
|
||||
.to_symbol_string(symbol, &env.interns);
|
||||
|
||||
let function = match env.module.get_function(fn_name.as_str()) {
|
||||
|
@ -1456,8 +1460,6 @@ fn build_box_eq_help<'a, 'ctx, 'env>(
|
|||
let box1 = box1.into_pointer_value();
|
||||
let box2 = box2.into_pointer_value();
|
||||
|
||||
let inner_layout = layout_interner.get(inner_layout);
|
||||
|
||||
let value1 = load_roc_value(env, layout_interner, inner_layout, box1, "load_box1");
|
||||
let value2 = load_roc_value(env, layout_interner, inner_layout, box2, "load_box2");
|
||||
|
||||
|
@ -1467,8 +1469,8 @@ fn build_box_eq_help<'a, 'ctx, 'env>(
|
|||
layout_ids,
|
||||
value1,
|
||||
value2,
|
||||
&inner_layout,
|
||||
&inner_layout,
|
||||
inner_layout,
|
||||
inner_layout,
|
||||
when_recursive,
|
||||
);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue