This commit is contained in:
Folkert 2022-03-09 16:33:36 +01:00
parent 6c0b6751ea
commit 5d15166bb5
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
5 changed files with 60 additions and 62 deletions

View file

@ -24,7 +24,7 @@ use crate::llvm::build_str::{
};
use crate::llvm::compare::{generic_eq, generic_neq};
use crate::llvm::convert::{
self, basic_type_from_builtin, basic_type_from_layout, basic_type_from_layout_1,
self, basic_type_from_builtin, basic_type_from_layout, basic_type_from_layout_tag_as_alloca,
block_of_memory_slices,
};
use crate::llvm::refcounting::{
@ -4225,7 +4225,7 @@ fn build_proc_header<'a, 'ctx, 'env>(
let mut arg_basic_types = Vec::with_capacity_in(args.len(), arena);
for (layout, _) in args.iter() {
let arg_type = basic_type_from_layout_1(env, layout);
let arg_type = basic_type_from_layout_tag_as_alloca(env, layout);
arg_basic_types.push(arg_type);
}

View file

@ -4,7 +4,7 @@ use crate::llvm::build::tag_pointer_clear_tag_id;
use crate::llvm::build::Env;
use crate::llvm::build::{get_tag_id, FAST_CALL_CONV, TAG_DATA_INDEX};
use crate::llvm::build_str;
use crate::llvm::convert::{basic_type_from_layout, basic_type_from_layout_1};
use crate::llvm::convert::{basic_type_from_layout, basic_type_from_layout_tag_as_alloca};
use bumpalo::collections::Vec;
use inkwell::values::{
BasicValue, BasicValueEnum, FunctionValue, IntValue, PointerValue, StructValue,
@ -13,6 +13,8 @@ use roc_builtins::bitcode;
use roc_module::symbol::Symbol;
use roc_mono::layout::{Builtin, Layout, LayoutIds, UnionLayout};
use super::convert::stack_basic_type_from_union_layout;
#[derive(Clone, Debug)]
enum WhenRecursive<'a> {
Unreachable,
@ -68,9 +70,7 @@ fn build_hash_layout<'a, 'ctx, 'env>(
when_recursive,
),
Layout::Union(union_layout) => {
build_hash_tag(env, layout_ids, layout, union_layout, seed, val)
}
Layout::Union(union_layout) => build_hash_tag(env, layout_ids, union_layout, seed, val),
Layout::RecursivePointer => match when_recursive {
WhenRecursive::Unreachable => {
@ -87,14 +87,7 @@ fn build_hash_layout<'a, 'ctx, 'env>(
.build_bitcast(val, bt, "i64_to_opaque")
.into_pointer_value();
build_hash_tag(
env,
layout_ids,
&layout,
&union_layout,
seed,
field_cast.into(),
)
build_hash_tag(env, layout_ids, &union_layout, seed, field_cast.into())
}
},
}
@ -308,7 +301,6 @@ fn hash_struct<'a, 'ctx, 'env>(
fn build_hash_tag<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
layout_ids: &mut LayoutIds<'a>,
layout: &Layout<'a>,
union_layout: &UnionLayout<'a>,
seed: IntValue<'ctx>,
value: BasicValueEnum<'ctx>,
@ -318,7 +310,7 @@ fn build_hash_tag<'a, 'ctx, 'env>(
let symbol = Symbol::GENERIC_HASH;
let fn_name = layout_ids
.get(symbol, layout)
.get(symbol, &Layout::Union(*union_layout))
.to_symbol_string(symbol, &env.interns);
let function = match env.module.get_function(fn_name.as_str()) {
@ -326,7 +318,7 @@ fn build_hash_tag<'a, 'ctx, 'env>(
None => {
let seed_type = env.context.i64_type();
let arg_type = basic_type_from_layout_1(env, layout);
let arg_type = stack_basic_type_from_union_layout(env, union_layout);
let function_value = crate::llvm::refcounting::build_header_help(
env,
@ -805,7 +797,7 @@ fn hash_ptr_to_struct<'a, 'ctx, 'env>(
) -> IntValue<'ctx> {
use inkwell::types::BasicType;
let wrapper_type = basic_type_from_layout_1(env, &Layout::Union(*union_layout));
let wrapper_type = basic_type_from_layout_tag_as_alloca(env, &Layout::Union(*union_layout));
// cast the opaque pointer to a pointer of the correct shape
let wrapper_ptr = env

View file

@ -2,7 +2,7 @@ use crate::llvm::bitcode::call_bitcode_fn;
use crate::llvm::build::{get_tag_id, tag_pointer_clear_tag_id, Env, 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, basic_type_from_layout_1};
use crate::llvm::convert::{basic_type_from_layout, basic_type_from_layout_tag_as_alloca};
use bumpalo::collections::Vec;
use inkwell::types::BasicType;
use inkwell::values::{
@ -780,7 +780,7 @@ fn build_tag_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_1(env, tag_layout);
let arg_type = basic_type_from_layout_tag_as_alloca(env, tag_layout);
let function_value = crate::llvm::refcounting::build_header_help(
env,

View file

@ -82,7 +82,50 @@ pub fn basic_type_from_layout<'a, 'ctx, 'env>(
}
}
pub fn basic_type_from_layout_1<'a, 'ctx, 'env>(
pub fn stack_basic_type_from_union_layout<'a, 'ctx, 'env>(
env: &crate::llvm::build::Env<'a, 'ctx, 'env>,
union_layout: &UnionLayout<'_>,
) -> BasicTypeEnum<'ctx> {
use UnionLayout::*;
let tag_id_type = basic_type_from_layout(env, &union_layout.tag_id_layout());
match union_layout {
NonRecursive(tags) => {
let data = block_of_memory_slices(env.context, tags, env.target_info);
let struct_type = env.context.struct_type(&[data, tag_id_type], false);
struct_type.ptr_type(AddressSpace::Generic).into()
}
Recursive(tags)
| NullableWrapped {
other_tags: tags, ..
} => {
let data = block_of_memory_slices(env.context, tags, env.target_info);
if union_layout.stores_tag_id_as_data(env.target_info) {
env.context
.struct_type(&[data, tag_id_type], false)
.ptr_type(AddressSpace::Generic)
.into()
} else {
data.ptr_type(AddressSpace::Generic).into()
}
}
NullableUnwrapped { other_fields, .. } => {
let block = block_of_memory_slices(env.context, &[other_fields], env.target_info);
block.ptr_type(AddressSpace::Generic).into()
}
NonNullableUnwrapped(fields) => {
let block = block_of_memory_slices(env.context, &[fields], env.target_info);
block.ptr_type(AddressSpace::Generic).into()
}
}
}
/// If the layout is a layout of a non-recursive tag,
/// give not the representation of this tag value but a pointer type to that value.
pub fn basic_type_from_layout_tag_as_alloca<'a, 'ctx, 'env>(
env: &crate::llvm::build::Env<'a, 'ctx, 'env>,
layout: &Layout<'_>,
) -> BasicTypeEnum<'ctx> {
@ -94,46 +137,9 @@ pub fn basic_type_from_layout_1<'a, 'ctx, 'env>(
..
} => basic_type_from_record(env, sorted_fields),
LambdaSet(lambda_set) => {
basic_type_from_layout_1(env, &lambda_set.runtime_representation())
}
Union(union_layout) => {
use UnionLayout::*;
let tag_id_type = basic_type_from_layout(env, &union_layout.tag_id_layout());
match union_layout {
NonRecursive(tags) => {
let data = block_of_memory_slices(env.context, tags, env.target_info);
let struct_type = env.context.struct_type(&[data, tag_id_type], false);
struct_type.ptr_type(AddressSpace::Generic).into()
}
Recursive(tags)
| NullableWrapped {
other_tags: tags, ..
} => {
let data = block_of_memory_slices(env.context, tags, env.target_info);
if union_layout.stores_tag_id_as_data(env.target_info) {
env.context
.struct_type(&[data, tag_id_type], false)
.ptr_type(AddressSpace::Generic)
.into()
} else {
data.ptr_type(AddressSpace::Generic).into()
}
}
NullableUnwrapped { other_fields, .. } => {
let block =
block_of_memory_slices(env.context, &[other_fields], env.target_info);
block.ptr_type(AddressSpace::Generic).into()
}
NonNullableUnwrapped(fields) => {
let block = block_of_memory_slices(env.context, &[fields], env.target_info);
block.ptr_type(AddressSpace::Generic).into()
}
}
basic_type_from_layout_tag_as_alloca(env, &lambda_set.runtime_representation())
}
Union(union_layout) => stack_basic_type_from_union_layout(env, union_layout),
RecursivePointer => {
// TODO make this dynamic
env.context

View file

@ -5,7 +5,7 @@ use crate::llvm::build::{
FAST_CALL_CONV, TAG_DATA_INDEX, TAG_ID_INDEX,
};
use crate::llvm::build_list::{incrementing_elem_loop, list_len, load_list};
use crate::llvm::convert::{basic_type_from_layout, basic_type_from_layout_1};
use crate::llvm::convert::{basic_type_from_layout, basic_type_from_layout_tag_as_alloca};
use bumpalo::collections::Vec;
use inkwell::basic_block::BasicBlock;
use inkwell::context::Context;
@ -1635,7 +1635,7 @@ fn modify_refcount_union<'a, 'ctx, 'env>(
let function = match env.module.get_function(fn_name.as_str()) {
Some(function_value) => function_value,
None => {
let basic_type = basic_type_from_layout_1(env, &layout);
let basic_type = basic_type_from_layout_tag_as_alloca(env, &layout);
let function_value = build_header(env, basic_type, mode, &fn_name);
modify_refcount_union_help(