make dict functions work on 32bit platforms

This commit is contained in:
Folkert 2021-08-25 20:38:12 +02:00
parent e99237e302
commit 05d2b8150f

View file

@ -6,7 +6,7 @@ use crate::llvm::build::{
complex_bitcast, load_symbol, load_symbol_and_layout, Env, RocFunctionCall, Scope, complex_bitcast, load_symbol, load_symbol_and_layout, Env, RocFunctionCall, Scope,
}; };
use crate::llvm::build_list::{layout_width, pass_as_opaque}; use crate::llvm::build_list::{layout_width, pass_as_opaque};
use crate::llvm::convert::basic_type_from_layout; use crate::llvm::convert::{basic_type_from_layout, zig_dict_type, zig_list_type};
use crate::llvm::refcounting::Mode; use crate::llvm::refcounting::Mode;
use inkwell::attributes::{Attribute, AttributeLoc}; use inkwell::attributes::{Attribute, AttributeLoc};
use inkwell::types::BasicType; use inkwell::types::BasicType;
@ -59,12 +59,11 @@ pub fn dict_len<'a, 'ctx, 'env>(
// let dict_as_int = dict_symbol_to_i128(env, scope, dict_symbol); // let dict_as_int = dict_symbol_to_i128(env, scope, dict_symbol);
let dict_as_zig_dict = dict_symbol_to_zig_dict(env, scope, dict_symbol); let dict_as_zig_dict = dict_symbol_to_zig_dict(env, scope, dict_symbol);
let dict_ptr = env call_bitcode_fn(
.builder env,
.build_alloca(dict_as_zig_dict.get_type(), "dict_ptr"); &[pass_dict_c_abi(env, dict_as_zig_dict.into())],
env.builder.build_store(dict_ptr, dict_as_zig_dict); bitcode::DICT_LEN,
)
call_bitcode_fn(env, &[dict_ptr.into()], bitcode::DICT_LEN)
} }
Layout::Builtin(Builtin::EmptyDict) => ctx.i64_type().const_zero().into(), Layout::Builtin(Builtin::EmptyDict) => ctx.i64_type().const_zero().into(),
_ => unreachable!("Invalid layout given to Dict.len : {:?}", dict_layout), _ => unreachable!("Invalid layout given to Dict.len : {:?}", dict_layout),
@ -95,14 +94,11 @@ pub fn dict_insert<'a, 'ctx, 'env>(
) -> BasicValueEnum<'ctx> { ) -> BasicValueEnum<'ctx> {
let builder = env.builder; let builder = env.builder;
let zig_dict_type = env.module.get_struct_type("dict.RocDict").unwrap();
let u8_ptr = env.context.i8_type().ptr_type(AddressSpace::Generic); let u8_ptr = env.context.i8_type().ptr_type(AddressSpace::Generic);
let dict_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
let key_ptr = builder.build_alloca(key.get_type(), "key_ptr"); let key_ptr = builder.build_alloca(key.get_type(), "key_ptr");
let value_ptr = builder.build_alloca(value.get_type(), "value_ptr"); let value_ptr = builder.build_alloca(value.get_type(), "value_ptr");
env.builder.build_store(dict_ptr, dict);
env.builder.build_store(key_ptr, key); env.builder.build_store(key_ptr, key);
env.builder.build_store(value_ptr, value); env.builder.build_store(value_ptr, value);
@ -114,7 +110,7 @@ pub fn dict_insert<'a, 'ctx, 'env>(
.ptr_int() .ptr_int()
.const_int(value_layout.stack_size(env.ptr_bytes) as u64, false); .const_int(value_layout.stack_size(env.ptr_bytes) as u64, false);
let result_ptr = builder.build_alloca(zig_dict_type, "result_ptr"); let result_ptr = builder.build_alloca(zig_dict_type(env), "result_ptr");
let alignment = Alignment::from_key_value_layout(key_layout, value_layout, env.ptr_bytes); let alignment = Alignment::from_key_value_layout(key_layout, value_layout, env.ptr_bytes);
let alignment_iv = env.context.i8_type().const_int(alignment as u64, false); let alignment_iv = env.context.i8_type().const_int(alignment as u64, false);
@ -128,7 +124,7 @@ pub fn dict_insert<'a, 'ctx, 'env>(
call_void_bitcode_fn( call_void_bitcode_fn(
env, env,
&[ &[
dict_ptr.into(), pass_dict_c_abi(env, dict),
alignment_iv.into(), alignment_iv.into(),
env.builder.build_bitcast(key_ptr, u8_ptr, "to_u8_ptr"), env.builder.build_bitcast(key_ptr, u8_ptr, "to_u8_ptr"),
key_width.into(), key_width.into(),
@ -157,13 +153,10 @@ pub fn dict_remove<'a, 'ctx, 'env>(
) -> BasicValueEnum<'ctx> { ) -> BasicValueEnum<'ctx> {
let builder = env.builder; let builder = env.builder;
let zig_dict_type = env.module.get_struct_type("dict.RocDict").unwrap();
let u8_ptr = env.context.i8_type().ptr_type(AddressSpace::Generic); let u8_ptr = env.context.i8_type().ptr_type(AddressSpace::Generic);
let dict_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
let key_ptr = builder.build_alloca(key.get_type(), "key_ptr"); let key_ptr = builder.build_alloca(key.get_type(), "key_ptr");
env.builder.build_store(dict_ptr, dict);
env.builder.build_store(key_ptr, key); env.builder.build_store(key_ptr, key);
let key_width = env let key_width = env
@ -174,7 +167,7 @@ pub fn dict_remove<'a, 'ctx, 'env>(
.ptr_int() .ptr_int()
.const_int(value_layout.stack_size(env.ptr_bytes) as u64, false); .const_int(value_layout.stack_size(env.ptr_bytes) as u64, false);
let result_ptr = builder.build_alloca(zig_dict_type, "result_ptr"); let result_ptr = builder.build_alloca(zig_dict_type(env), "result_ptr");
let alignment = Alignment::from_key_value_layout(key_layout, value_layout, env.ptr_bytes); let alignment = Alignment::from_key_value_layout(key_layout, value_layout, env.ptr_bytes);
let alignment_iv = env.context.i8_type().const_int(alignment as u64, false); let alignment_iv = env.context.i8_type().const_int(alignment as u64, false);
@ -188,7 +181,7 @@ pub fn dict_remove<'a, 'ctx, 'env>(
call_void_bitcode_fn( call_void_bitcode_fn(
env, env,
&[ &[
dict_ptr.into(), pass_dict_c_abi(env, dict),
alignment_iv.into(), alignment_iv.into(),
env.builder.build_bitcast(key_ptr, u8_ptr, "to_u8_ptr"), env.builder.build_bitcast(key_ptr, u8_ptr, "to_u8_ptr"),
key_width.into(), key_width.into(),
@ -216,13 +209,10 @@ pub fn dict_contains<'a, 'ctx, 'env>(
) -> BasicValueEnum<'ctx> { ) -> BasicValueEnum<'ctx> {
let builder = env.builder; let builder = env.builder;
let zig_dict_type = env.module.get_struct_type("dict.RocDict").unwrap();
let u8_ptr = env.context.i8_type().ptr_type(AddressSpace::Generic); let u8_ptr = env.context.i8_type().ptr_type(AddressSpace::Generic);
let dict_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
let key_ptr = builder.build_alloca(key.get_type(), "key_ptr"); let key_ptr = builder.build_alloca(key.get_type(), "key_ptr");
env.builder.build_store(dict_ptr, dict);
env.builder.build_store(key_ptr, key); env.builder.build_store(key_ptr, key);
let key_width = env let key_width = env
@ -242,7 +232,7 @@ pub fn dict_contains<'a, 'ctx, 'env>(
call_bitcode_fn( call_bitcode_fn(
env, env,
&[ &[
dict_ptr.into(), pass_dict_c_abi(env, dict),
alignment_iv.into(), alignment_iv.into(),
env.builder.build_bitcast(key_ptr, u8_ptr, "to_u8_ptr"), env.builder.build_bitcast(key_ptr, u8_ptr, "to_u8_ptr"),
key_width.into(), key_width.into(),
@ -265,13 +255,10 @@ pub fn dict_get<'a, 'ctx, 'env>(
) -> BasicValueEnum<'ctx> { ) -> BasicValueEnum<'ctx> {
let builder = env.builder; let builder = env.builder;
let zig_dict_type = env.module.get_struct_type("dict.RocDict").unwrap();
let u8_ptr = env.context.i8_type().ptr_type(AddressSpace::Generic); let u8_ptr = env.context.i8_type().ptr_type(AddressSpace::Generic);
let dict_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
let key_ptr = builder.build_alloca(key.get_type(), "key_ptr"); let key_ptr = builder.build_alloca(key.get_type(), "key_ptr");
env.builder.build_store(dict_ptr, dict);
env.builder.build_store(key_ptr, key); env.builder.build_store(key_ptr, key);
let key_width = env let key_width = env
@ -294,7 +281,7 @@ pub fn dict_get<'a, 'ctx, 'env>(
let result = call_bitcode_fn( let result = call_bitcode_fn(
env, env,
&[ &[
dict_ptr.into(), pass_dict_c_abi(env, dict),
alignment_iv.into(), alignment_iv.into(),
env.builder.build_bitcast(key_ptr, u8_ptr, "to_u8_ptr"), env.builder.build_bitcast(key_ptr, u8_ptr, "to_u8_ptr"),
key_width.into(), key_width.into(),
@ -376,13 +363,6 @@ pub fn dict_elements_rc<'a, 'ctx, 'env>(
value_layout: &Layout<'a>, value_layout: &Layout<'a>,
rc_operation: Mode, rc_operation: Mode,
) { ) {
let builder = env.builder;
let zig_dict_type = env.module.get_struct_type("dict.RocDict").unwrap();
let dict_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
env.builder.build_store(dict_ptr, dict);
let key_width = env let key_width = env
.ptr_int() .ptr_int()
.const_int(key_layout.stack_size(env.ptr_bytes) as u64, false); .const_int(key_layout.stack_size(env.ptr_bytes) as u64, false);
@ -408,7 +388,7 @@ pub fn dict_elements_rc<'a, 'ctx, 'env>(
call_void_bitcode_fn( call_void_bitcode_fn(
env, env,
&[ &[
dict_ptr.into(), pass_dict_c_abi(env, dict),
alignment_iv.into(), alignment_iv.into(),
key_width.into(), key_width.into(),
value_width.into(), value_width.into(),
@ -429,12 +409,6 @@ pub fn dict_keys<'a, 'ctx, 'env>(
) -> BasicValueEnum<'ctx> { ) -> BasicValueEnum<'ctx> {
let builder = env.builder; let builder = env.builder;
let zig_dict_type = env.module.get_struct_type("dict.RocDict").unwrap();
let zig_list_type = env.module.get_struct_type("list.RocList").unwrap();
let dict_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
env.builder.build_store(dict_ptr, dict);
let key_width = env let key_width = env
.ptr_int() .ptr_int()
.const_int(key_layout.stack_size(env.ptr_bytes) as u64, false); .const_int(key_layout.stack_size(env.ptr_bytes) as u64, false);
@ -448,12 +422,12 @@ pub fn dict_keys<'a, 'ctx, 'env>(
let inc_key_fn = build_inc_wrapper(env, layout_ids, key_layout); let inc_key_fn = build_inc_wrapper(env, layout_ids, key_layout);
let list_ptr = builder.build_alloca(zig_list_type, "list_ptr"); let list_ptr = builder.build_alloca(zig_list_type(env), "list_ptr");
call_void_bitcode_fn( call_void_bitcode_fn(
env, env,
&[ &[
dict_ptr.into(), pass_dict_c_abi(env, dict),
alignment_iv.into(), alignment_iv.into(),
key_width.into(), key_width.into(),
value_width.into(), value_width.into(),
@ -475,6 +449,26 @@ pub fn dict_keys<'a, 'ctx, 'env>(
env.builder.build_load(list_ptr, "load_keys_list") env.builder.build_load(list_ptr, "load_keys_list")
} }
fn pass_dict_c_abi<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
dict: BasicValueEnum<'ctx>,
) -> BasicValueEnum<'ctx> {
match env.ptr_bytes {
4 => {
let target_type = env.context.custom_width_int_type(96).into();
complex_bitcast(env.builder, dict, target_type, "to_i96")
}
8 => {
let dict_ptr = env.builder.build_alloca(zig_dict_type(env), "dict_ptr");
env.builder.build_store(dict_ptr, dict);
dict_ptr.into()
}
_ => unreachable!(),
}
}
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn dict_union<'a, 'ctx, 'env>( pub fn dict_union<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>, env: &Env<'a, 'ctx, 'env>,
@ -486,14 +480,6 @@ pub fn dict_union<'a, 'ctx, 'env>(
) -> BasicValueEnum<'ctx> { ) -> BasicValueEnum<'ctx> {
let builder = env.builder; let builder = env.builder;
let zig_dict_type = env.module.get_struct_type("dict.RocDict").unwrap();
let dict1_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
let dict2_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
env.builder.build_store(dict1_ptr, dict1);
env.builder.build_store(dict2_ptr, dict2);
let key_width = env let key_width = env
.ptr_int() .ptr_int()
.const_int(key_layout.stack_size(env.ptr_bytes) as u64, false); .const_int(key_layout.stack_size(env.ptr_bytes) as u64, false);
@ -511,13 +497,13 @@ pub fn dict_union<'a, 'ctx, 'env>(
let inc_key_fn = build_inc_wrapper(env, layout_ids, key_layout); let inc_key_fn = build_inc_wrapper(env, layout_ids, key_layout);
let inc_value_fn = build_inc_wrapper(env, layout_ids, value_layout); let inc_value_fn = build_inc_wrapper(env, layout_ids, value_layout);
let output_ptr = builder.build_alloca(zig_dict_type, "output_ptr"); let output_ptr = builder.build_alloca(zig_dict_type(env), "output_ptr");
call_void_bitcode_fn( call_void_bitcode_fn(
env, env,
&[ &[
dict1_ptr.into(), pass_dict_c_abi(env, dict1),
dict2_ptr.into(), pass_dict_c_abi(env, dict2),
alignment_iv.into(), alignment_iv.into(),
key_width.into(), key_width.into(),
value_width.into(), value_width.into(),
@ -587,12 +573,6 @@ fn dict_intersect_or_difference<'a, 'ctx, 'env>(
let zig_dict_type = env.module.get_struct_type("dict.RocDict").unwrap(); let zig_dict_type = env.module.get_struct_type("dict.RocDict").unwrap();
let dict1_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
let dict2_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
env.builder.build_store(dict1_ptr, dict1);
env.builder.build_store(dict2_ptr, dict2);
let key_width = env let key_width = env
.ptr_int() .ptr_int()
.const_int(key_layout.stack_size(env.ptr_bytes) as u64, false); .const_int(key_layout.stack_size(env.ptr_bytes) as u64, false);
@ -615,8 +595,8 @@ fn dict_intersect_or_difference<'a, 'ctx, 'env>(
call_void_bitcode_fn( call_void_bitcode_fn(
env, env,
&[ &[
dict1_ptr.into(), pass_dict_c_abi(env, dict1),
dict2_ptr.into(), pass_dict_c_abi(env, dict2),
alignment_iv.into(), alignment_iv.into(),
key_width.into(), key_width.into(),
value_width.into(), value_width.into(),
@ -645,10 +625,6 @@ pub fn dict_walk<'a, 'ctx, 'env>(
let builder = env.builder; let builder = env.builder;
let u8_ptr = env.context.i8_type().ptr_type(AddressSpace::Generic); let u8_ptr = env.context.i8_type().ptr_type(AddressSpace::Generic);
let zig_dict_type = env.module.get_struct_type("dict.RocDict").unwrap();
let dict_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
env.builder.build_store(dict_ptr, dict);
let accum_bt = basic_type_from_layout(env, accum_layout); let accum_bt = basic_type_from_layout(env, accum_layout);
let accum_ptr = builder.build_alloca(accum_bt, "accum_ptr"); let accum_ptr = builder.build_alloca(accum_bt, "accum_ptr");
@ -662,7 +638,7 @@ pub fn dict_walk<'a, 'ctx, 'env>(
call_void_bitcode_fn( call_void_bitcode_fn(
env, env,
&[ &[
dict_ptr.into(), pass_dict_c_abi(env, dict),
roc_function_call.caller.into(), roc_function_call.caller.into(),
pass_as_opaque(env, roc_function_call.data), pass_as_opaque(env, roc_function_call.data),
roc_function_call.inc_n_data.into(), roc_function_call.inc_n_data.into(),
@ -690,12 +666,8 @@ pub fn dict_values<'a, 'ctx, 'env>(
) -> BasicValueEnum<'ctx> { ) -> BasicValueEnum<'ctx> {
let builder = env.builder; let builder = env.builder;
let zig_dict_type = super::convert::zig_dict_type(env);
let zig_list_type = super::convert::zig_list_type(env); let zig_list_type = super::convert::zig_list_type(env);
let dict_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
env.builder.build_store(dict_ptr, dict);
let key_width = env let key_width = env
.ptr_int() .ptr_int()
.const_int(key_layout.stack_size(env.ptr_bytes) as u64, false); .const_int(key_layout.stack_size(env.ptr_bytes) as u64, false);
@ -714,7 +686,7 @@ pub fn dict_values<'a, 'ctx, 'env>(
call_void_bitcode_fn( call_void_bitcode_fn(
env, env,
&[ &[
dict_ptr.into(), pass_dict_c_abi(env, dict),
alignment_iv.into(), alignment_iv.into(),
key_width.into(), key_width.into(),
value_width.into(), value_width.into(),
@ -748,7 +720,7 @@ pub fn set_from_list<'a, 'ctx, 'env>(
let list_alloca = builder.build_alloca(list.get_type(), "list_alloca"); let list_alloca = builder.build_alloca(list.get_type(), "list_alloca");
let list_ptr = env.builder.build_bitcast( let list_ptr = env.builder.build_bitcast(
list_alloca, list_alloca,
env.context.i128_type().ptr_type(AddressSpace::Generic), env.str_list_c_abi().ptr_type(AddressSpace::Generic),
"to_zig_list", "to_zig_list",
); );
@ -865,11 +837,11 @@ fn dict_symbol_to_zig_dict<'a, 'ctx, 'env>(
) -> StructValue<'ctx> { ) -> StructValue<'ctx> {
let dict = load_symbol(scope, &symbol); let dict = load_symbol(scope, &symbol);
let zig_dict_type = env.module.get_struct_type("dict.RocDict").unwrap(); complex_bitcast(
env.builder,
complex_bitcast(env.builder, dict, zig_dict_type.into(), "dict_to_zig_dict").into_struct_value() dict,
} crate::llvm::convert::zig_dict_type(env).into(),
"dict_to_zig_dict",
fn zig_dict_type<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> inkwell::types::StructType<'ctx> { )
env.module.get_struct_type("dict.RocDict").unwrap() .into_struct_value()
} }