diff --git a/Cargo.lock b/Cargo.lock index 8c69e69d22..394fba4073 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1786,20 +1786,20 @@ dependencies = [ [[package]] name = "inkwell" version = "0.1.0" -source = "git+https://github.com/rtfeldman/inkwell?branch=master#b3fb82c653ffe754e078ac778d7fd9a619a26c0c" +source = "git+https://github.com/rtfeldman/inkwell?branch=master#32aebaf0ee1110ad4f6eaa901fe58078a4cd8894" dependencies = [ "either", "inkwell_internals", "libc", "llvm-sys", "once_cell", - "parking_lot 0.11.2", + "parking_lot 0.12.0", ] [[package]] name = "inkwell_internals" version = "0.5.0" -source = "git+https://github.com/rtfeldman/inkwell?branch=master#b3fb82c653ffe754e078ac778d7fd9a619a26c0c" +source = "git+https://github.com/rtfeldman/inkwell?branch=master#32aebaf0ee1110ad4f6eaa901fe58078a4cd8894" dependencies = [ "proc-macro2", "quote", @@ -1996,9 +1996,9 @@ checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" [[package]] name = "llvm-sys" -version = "120.2.1" +version = "120.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4a810627ac62b396f5fd2214ba9bbd8748d4d6efdc4d2c1c1303ea7a75763ce" +checksum = "ce76f8393b7a607a906087666db398d872db739622e644e58552c198ccdfdf45" dependencies = [ "cc", "lazy_static", diff --git a/compiler/gen_llvm/src/llvm/bitcode.rs b/compiler/gen_llvm/src/llvm/bitcode.rs index f78a0950a9..db1af14724 100644 --- a/compiler/gen_llvm/src/llvm/bitcode.rs +++ b/compiler/gen_llvm/src/llvm/bitcode.rs @@ -131,30 +131,28 @@ fn call_bitcode_fn_help<'a, 'ctx, 'env>( let call = env.builder.build_call(fn_val, &arguments, "call_builtin"); + for i in 0..fn_val.count_params() { + let attributes = fn_val.attributes(AttributeLoc::Param(i)); + + for attribute in attributes { + if attribute.is_type() {} + call.add_attribute(AttributeLoc::Param(i), attribute) + } + } + match fn_name { bitcode::STR_NUMBER_OF_BYTES | bitcode::STR_COUNT_GRAPEHEME_CLUSTERS => { - // hacks + string_argument(env, call, 0); + } + bitcode::STR_ENDS_WITH | bitcode::STR_STARTS_WITH => { + string_argument(env, call, 0); + string_argument(env, call, 1); + } + bitcode::STR_STR_SPLIT_IN_PLACE => { + string_argument(env, call, 0); + string_argument(env, call, 1); - let i = 0; - call.add_attribute( - AttributeLoc::Param(0), - type_attribute(env.context, "byval", zig_str_type(env).into()), - ); - - call.add_attribute( - AttributeLoc::Param(i as u32), - enum_attribute(env.context, "nonnull"), - ); - - call.add_attribute( - AttributeLoc::Param(i as u32), - enum_attribute(env.context, "nocapture"), - ); - - call.add_attribute( - AttributeLoc::Param(i as u32), - enum_attribute(env.context, "readonly"), - ); + dbg!(fn_val.get_type()); } _ => {} } @@ -163,6 +161,32 @@ fn call_bitcode_fn_help<'a, 'ctx, 'env>( call } +fn string_argument<'a, 'ctx, 'env>( + env: &Env<'a, 'ctx, 'env>, + call: CallSiteValue, + parameter_index: u32, +) { + call.add_attribute( + AttributeLoc::Param(0), + type_attribute(env.context, "byval", zig_str_type(env).into()), + ); + + call.add_attribute( + AttributeLoc::Param(parameter_index as u32), + enum_attribute(env.context, "nonnull"), + ); + + call.add_attribute( + AttributeLoc::Param(parameter_index as u32), + enum_attribute(env.context, "nocapture"), + ); + + call.add_attribute( + AttributeLoc::Param(parameter_index as u32), + enum_attribute(env.context, "readonly"), + ); +} + pub fn call_bitcode_fn_fixing_for_convention<'a, 'ctx, 'env>( env: &Env<'a, 'ctx, 'env>, args: &[BasicValueEnum<'ctx>], diff --git a/compiler/load/Cargo.toml b/compiler/load/Cargo.toml index 77274cb312..4f7632fb60 100644 --- a/compiler/load/Cargo.toml +++ b/compiler/load/Cargo.toml @@ -18,5 +18,5 @@ roc_collections = { path = "../collections" } roc_load_internal = { path = "../load_internal" } roc_builtins = { path = "../builtins" } roc_module = { path = "../module" } -bumpalo = { version = "3.8.0", features = ["collections"] } roc_target = { path = "../roc_target" } +bumpalo = { version = "3.8.0", features = ["collections"] } diff --git a/compiler/mono/src/layout.rs b/compiler/mono/src/layout.rs index f0cac0ce7a..23ff8e6123 100644 --- a/compiler/mono/src/layout.rs +++ b/compiler/mono/src/layout.rs @@ -554,6 +554,31 @@ impl<'a> UnionLayout<'a> { (size, alignment_bytes) } + + /// Very important to use this when doing a memcpy! + fn stack_size_without_alignment(&self, target_info: TargetInfo) -> u32 { + match self { + UnionLayout::NonRecursive(tags) => { + let id_layout = self.tag_id_layout(); + + let mut size = 0; + + for field_layouts in tags.iter() { + let fields = Layout::struct_no_name_order(field_layouts); + let fields_and_id = [fields, id_layout]; + + let data = Layout::struct_no_name_order(&fields_and_id); + size = size.max(data.stack_size_without_alignment(target_info)); + } + + size + } + UnionLayout::Recursive(_) + | UnionLayout::NonNullableUnwrapped(_) + | UnionLayout::NullableWrapped { .. } + | UnionLayout::NullableUnwrapped { .. } => target_info.ptr_width() as u32, + } + } } /// Custom type so we can get the numeric representation of a symbol in tests (so `#UserApp.3` @@ -1042,7 +1067,8 @@ impl<'a> Layout<'a> { (size, alignment) } - fn stack_size_without_alignment(&self, target_info: TargetInfo) -> u32 { + /// Very important to use this when doing a memcpy! + pub fn stack_size_without_alignment(&self, target_info: TargetInfo) -> u32 { use Layout::*; match self { @@ -1056,18 +1082,7 @@ impl<'a> Layout<'a> { sum } - Union(variant) => { - use UnionLayout::*; - - match variant { - NonRecursive(_) => variant.data_size_and_alignment(target_info).0, - - Recursive(_) - | NullableWrapped { .. } - | NullableUnwrapped { .. } - | NonNullableUnwrapped(_) => target_info.ptr_width() as u32, - } - } + Union(variant) => variant.stack_size_without_alignment(target_info), LambdaSet(lambda_set) => lambda_set .runtime_representation() .stack_size_without_alignment(target_info), @@ -2950,4 +2965,16 @@ mod test { assert_eq!(layout.stack_size(target_info), 1); assert_eq!(layout.alignment_bytes(target_info), 1); } + + #[test] + fn memcpy_size_result_u32_unit() { + let ok_tag = &[Layout::Builtin(Builtin::Int(IntWidth::U32))]; + let err_tag = &[Layout::UNIT]; + let tags = [ok_tag as &[_], err_tag as &[_]]; + let union_layout = UnionLayout::NonRecursive(&tags as &[_]); + let layout = Layout::Union(union_layout); + + let target_info = TargetInfo::default_x86_64(); + assert_eq!(layout.stack_size_without_alignment(target_info), 5); + } } diff --git a/compiler/test_gen/src/helpers/llvm.rs b/compiler/test_gen/src/helpers/llvm.rs index f6660f977b..a016453070 100644 --- a/compiler/test_gen/src/helpers/llvm.rs +++ b/compiler/test_gen/src/helpers/llvm.rs @@ -265,7 +265,8 @@ pub fn helper<'a>( let target = target_lexicon::Triple::host(); let opt_level = if cfg!(debug_assertions) { - OptLevel::Normal + // OptLevel::Normal + OptLevel::Optimize } else { OptLevel::Optimize };