mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 15:21:12 +00:00
fix all the things
This commit is contained in:
parent
99d0d9c732
commit
16f6259f7f
23 changed files with 81 additions and 149 deletions
|
@ -1,9 +1,7 @@
|
|||
use crate::debug_info_init;
|
||||
use crate::llvm::bitcode::call_bitcode_fn;
|
||||
use crate::llvm::build::Env;
|
||||
use crate::llvm::build::{
|
||||
cast_block_of_memory_to_tag, complex_bitcast, get_tag_id, FAST_CALL_CONV,
|
||||
};
|
||||
use crate::llvm::build::{cast_block_of_memory_to_tag, get_tag_id, FAST_CALL_CONV, TAG_DATA_INDEX};
|
||||
use crate::llvm::build_str;
|
||||
use crate::llvm::convert::basic_type_from_layout;
|
||||
use bumpalo::collections::Vec;
|
||||
|
@ -408,7 +406,7 @@ fn hash_tag<'a, 'ctx, 'env>(
|
|||
env.builder.position_at_end(entry_block);
|
||||
match union_layout {
|
||||
NonRecursive(tags) => {
|
||||
let tag_id = nonrec_tag_id(env, tag.into_struct_value());
|
||||
let tag_id = get_tag_id(env, parent, union_layout, tag).into_int_value();
|
||||
|
||||
let mut cases = Vec::with_capacity_in(tags.len(), env.arena);
|
||||
|
||||
|
@ -484,7 +482,6 @@ fn hash_tag<'a, 'ctx, 'env>(
|
|||
}
|
||||
NullableUnwrapped { other_fields, .. } => {
|
||||
let tag = tag.into_pointer_value();
|
||||
let other_fields = &other_fields[1..];
|
||||
|
||||
let is_null = env.builder.build_is_null(tag, "is_null");
|
||||
|
||||
|
@ -534,11 +531,6 @@ fn hash_tag<'a, 'ctx, 'env>(
|
|||
}
|
||||
|
||||
{
|
||||
env.builder.position_at_end(hash_other_block);
|
||||
|
||||
// SAFETY recursive tag unions are not NULL
|
||||
let tag_id = unsafe { rec_tag_id_unsafe(env, tag) };
|
||||
|
||||
let mut cases = Vec::with_capacity_in(other_tags.len(), env.arena);
|
||||
|
||||
for (tag_id, field_layouts) in other_tags.iter().enumerate() {
|
||||
|
@ -559,6 +551,8 @@ fn hash_tag<'a, 'ctx, 'env>(
|
|||
|
||||
env.builder.position_at_end(hash_other_block);
|
||||
|
||||
let tag_id = get_tag_id(env, parent, union_layout, tag.into()).into_int_value();
|
||||
|
||||
let default = cases.pop().unwrap().1;
|
||||
|
||||
env.builder.build_switch(tag_id, default, &cases);
|
||||
|
@ -765,18 +759,27 @@ fn hash_ptr_to_struct<'a, 'ctx, 'env>(
|
|||
) -> IntValue<'ctx> {
|
||||
use inkwell::types::BasicType;
|
||||
|
||||
let struct_layout = Layout::Struct(field_layouts);
|
||||
|
||||
let wrapper_type = basic_type_from_layout(env, &struct_layout);
|
||||
debug_assert!(wrapper_type.is_struct_type());
|
||||
let wrapper_type = basic_type_from_layout(env, &Layout::Union(*union_layout));
|
||||
|
||||
// cast the opaque pointer to a pointer of the correct shape
|
||||
let wrapper_ptr = env
|
||||
.builder
|
||||
.build_bitcast(tag, wrapper_type, "opaque_to_correct")
|
||||
.into_pointer_value();
|
||||
|
||||
let struct_ptr = env
|
||||
.builder
|
||||
.build_struct_gep(wrapper_ptr, TAG_DATA_INDEX, "get_tag_data")
|
||||
.unwrap();
|
||||
|
||||
let struct_layout = Layout::Struct(field_layouts);
|
||||
let struct_type = basic_type_from_layout(env, &struct_layout);
|
||||
let struct_ptr = env
|
||||
.builder
|
||||
.build_bitcast(
|
||||
tag,
|
||||
wrapper_type.ptr_type(inkwell::AddressSpace::Generic),
|
||||
"opaque_to_correct",
|
||||
struct_ptr,
|
||||
struct_type.ptr_type(inkwell::AddressSpace::Generic),
|
||||
"cast_tag_data",
|
||||
)
|
||||
.into_pointer_value();
|
||||
|
||||
|
@ -830,34 +833,3 @@ fn hash_bitcode_fn<'a, 'ctx, 'env>(
|
|||
)
|
||||
.into_int_value()
|
||||
}
|
||||
|
||||
fn nonrec_tag_id<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
tag: StructValue<'ctx>,
|
||||
) -> IntValue<'ctx> {
|
||||
complex_bitcast(
|
||||
env.builder,
|
||||
tag.into(),
|
||||
env.context.i64_type().into(),
|
||||
"load_tag_id",
|
||||
)
|
||||
.into_int_value()
|
||||
}
|
||||
|
||||
unsafe fn rec_tag_id_unsafe<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
tag: PointerValue<'ctx>,
|
||||
) -> IntValue<'ctx> {
|
||||
let ptr = env
|
||||
.builder
|
||||
.build_bitcast(
|
||||
tag,
|
||||
env.context
|
||||
.i64_type()
|
||||
.ptr_type(inkwell::AddressSpace::Generic),
|
||||
"cast_for_tag_id",
|
||||
)
|
||||
.into_pointer_value();
|
||||
|
||||
env.builder.build_load(ptr, "load_tag_id").into_int_value()
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::llvm::build::Env;
|
||||
use crate::llvm::build::{cast_block_of_memory_to_tag, FAST_CALL_CONV};
|
||||
use crate::llvm::build::{cast_block_of_memory_to_tag, get_tag_id, FAST_CALL_CONV};
|
||||
use crate::llvm::build_list::{list_len, load_list_ptr};
|
||||
use crate::llvm::build_str::str_equal;
|
||||
use crate::llvm::convert::basic_type_from_layout;
|
||||
|
@ -846,10 +846,8 @@ fn build_tag_eq_help<'a, 'ctx, 'env>(
|
|||
|
||||
match union_layout {
|
||||
NonRecursive(tags) => {
|
||||
let id1 =
|
||||
crate::llvm::build::get_tag_id(env, parent, union_layout, tag1).into_int_value();
|
||||
let id2 =
|
||||
crate::llvm::build::get_tag_id(env, parent, union_layout, tag2).into_int_value();
|
||||
let id1 = get_tag_id(env, parent, union_layout, tag1).into_int_value();
|
||||
let id2 = get_tag_id(env, parent, union_layout, tag2).into_int_value();
|
||||
|
||||
let compare_tag_fields = ctx.append_basic_block(parent, "compare_tag_fields");
|
||||
|
||||
|
@ -927,9 +925,8 @@ fn build_tag_eq_help<'a, 'ctx, 'env>(
|
|||
|
||||
env.builder.position_at_end(compare_tag_ids);
|
||||
|
||||
// SAFETY we know that non-recursive tags cannot be NULL
|
||||
let id1 = unsafe { rec_tag_id_unsafe(env, tag1.into_pointer_value()) };
|
||||
let id2 = unsafe { rec_tag_id_unsafe(env, tag2.into_pointer_value()) };
|
||||
let id1 = get_tag_id(env, parent, union_layout, tag1).into_int_value();
|
||||
let id2 = get_tag_id(env, parent, union_layout, tag2).into_int_value();
|
||||
|
||||
let compare_tag_fields = ctx.append_basic_block(parent, "compare_tag_fields");
|
||||
|
||||
|
@ -974,9 +971,6 @@ fn build_tag_eq_help<'a, 'ctx, 'env>(
|
|||
env.builder.build_switch(id1, default, &cases);
|
||||
}
|
||||
NullableUnwrapped { other_fields, .. } => {
|
||||
// drop the tag id; it is not stored
|
||||
let other_fields = &other_fields[1..];
|
||||
|
||||
let ptr_equal = env.builder.build_int_compare(
|
||||
IntPredicate::EQ,
|
||||
env.builder
|
||||
|
@ -1082,9 +1076,8 @@ fn build_tag_eq_help<'a, 'ctx, 'env>(
|
|||
|
||||
env.builder.position_at_end(compare_other);
|
||||
|
||||
// SAFETY we know at this point that tag1/tag2 are not NULL
|
||||
let id1 = unsafe { rec_tag_id_unsafe(env, tag1.into_pointer_value()) };
|
||||
let id2 = unsafe { rec_tag_id_unsafe(env, tag2.into_pointer_value()) };
|
||||
let id1 = get_tag_id(env, parent, union_layout, tag1).into_int_value();
|
||||
let id2 = get_tag_id(env, parent, union_layout, tag2).into_int_value();
|
||||
|
||||
let compare_tag_fields = ctx.append_basic_block(parent, "compare_tag_fields");
|
||||
|
||||
|
@ -1212,19 +1205,3 @@ fn eq_ptr_to_struct<'a, 'ctx, 'env>(
|
|||
)
|
||||
.into_int_value()
|
||||
}
|
||||
|
||||
unsafe fn rec_tag_id_unsafe<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
tag: PointerValue<'ctx>,
|
||||
) -> IntValue<'ctx> {
|
||||
let ptr = env
|
||||
.builder
|
||||
.build_bitcast(
|
||||
tag,
|
||||
env.context.i64_type().ptr_type(AddressSpace::Generic),
|
||||
"cast_for_tag_id",
|
||||
)
|
||||
.into_pointer_value();
|
||||
|
||||
env.builder.build_load(ptr, "load_tag_id").into_int_value()
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::debug_info_init;
|
||||
use crate::llvm::build::{
|
||||
add_func, cast_basic_basic, cast_block_of_memory_to_tag, Env, FAST_CALL_CONV,
|
||||
add_func, cast_basic_basic, cast_block_of_memory_to_tag, get_tag_id, Env, FAST_CALL_CONV,
|
||||
LLVM_SADD_WITH_OVERFLOW_I64, TAG_DATA_INDEX, TAG_ID_INDEX,
|
||||
};
|
||||
use crate::llvm::build_list::{incrementing_elem_loop, list_len, load_list};
|
||||
|
@ -1520,7 +1520,8 @@ fn build_rec_union_recursive_decrement<'a, 'ctx, 'env>(
|
|||
env.builder.build_unconditional_branch(only_branch);
|
||||
} else {
|
||||
// read the tag_id
|
||||
let current_tag_id = rec_union_read_tag(env, value_ptr);
|
||||
let current_tag_id =
|
||||
get_tag_id(env, parent, &union_layout, value_ptr.into()).into_int_value();
|
||||
|
||||
let merge_block = env.context.append_basic_block(parent, "decrement_merge");
|
||||
|
||||
|
@ -1538,23 +1539,6 @@ fn build_rec_union_recursive_decrement<'a, 'ctx, 'env>(
|
|||
}
|
||||
}
|
||||
|
||||
fn rec_union_read_tag<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
value_ptr: PointerValue<'ctx>,
|
||||
) -> IntValue<'ctx> {
|
||||
// Assumption: the tag is the first thing stored
|
||||
// so cast the pointer to the data to a `i64*`
|
||||
let tag_ptr_type = env.context.i64_type().ptr_type(AddressSpace::Generic);
|
||||
let tag_ptr = env
|
||||
.builder
|
||||
.build_bitcast(value_ptr, tag_ptr_type, "cast_tag_ptr")
|
||||
.into_pointer_value();
|
||||
|
||||
env.builder
|
||||
.build_load(tag_ptr, "load_tag_id")
|
||||
.into_int_value()
|
||||
}
|
||||
|
||||
fn function_name_from_mode<'a>(
|
||||
layout_ids: &mut LayoutIds<'a>,
|
||||
interns: &Interns,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue