diff --git a/compiler/gen_llvm/src/llvm/bitcode.rs b/compiler/gen_llvm/src/llvm/bitcode.rs index 5e2221111c..0ba1130580 100644 --- a/compiler/gen_llvm/src/llvm/bitcode.rs +++ b/compiler/gen_llvm/src/llvm/bitcode.rs @@ -30,6 +30,38 @@ pub fn call_bitcode_fn<'a, 'ctx, 'env>( }) } +pub fn call_list_bitcode_fn<'a, 'ctx, 'env>( + env: &Env<'a, 'ctx, 'env>, + args: &[BasicValueEnum<'ctx>], + fn_name: &str, +) -> BasicValueEnum<'ctx> { + call_bitcode_fn_help(env, args, fn_name) + .try_as_basic_value() + .left() + .unwrap_or_else(|| { + panic!( + "LLVM error: Did not get return value from bitcode function {:?}", + fn_name + ) + }) +} + +pub fn call_str_bitcode_fn<'a, 'ctx, 'env>( + env: &Env<'a, 'ctx, 'env>, + args: &[BasicValueEnum<'ctx>], + fn_name: &str, +) -> BasicValueEnum<'ctx> { + call_bitcode_fn_help(env, args, fn_name) + .try_as_basic_value() + .left() + .unwrap_or_else(|| { + panic!( + "LLVM error: Did not get return value from bitcode function {:?}", + fn_name + ) + }) +} + pub fn call_void_bitcode_fn<'a, 'ctx, 'env>( env: &Env<'a, 'ctx, 'env>, args: &[BasicValueEnum<'ctx>], diff --git a/compiler/gen_llvm/src/llvm/build_list.rs b/compiler/gen_llvm/src/llvm/build_list.rs index 828520f5d2..fdc229a45a 100644 --- a/compiler/gen_llvm/src/llvm/build_list.rs +++ b/compiler/gen_llvm/src/llvm/build_list.rs @@ -1,7 +1,7 @@ #![allow(clippy::too_many_arguments)] use crate::llvm::bitcode::{ build_dec_wrapper, build_eq_wrapper, build_has_tag_id, build_inc_n_wrapper, build_inc_wrapper, - call_bitcode_fn, call_void_bitcode_fn, + call_bitcode_fn, call_list_bitcode_fn, call_void_bitcode_fn, }; use crate::llvm::build::{ allocate_with_refcount_help, cast_basic_basic, complex_bitcast, Env, RocFunctionCall, @@ -29,29 +29,6 @@ pub fn pass_update_mode<'a, 'ctx, 'env>( } } -fn list_returned_from_zig<'a, 'ctx, 'env>( - env: &Env<'a, 'ctx, 'env>, - output: BasicValueEnum<'ctx>, -) -> BasicValueEnum<'ctx> { - // per the C ABI, our list objects are passed between functions as an i128/i64 - complex_bitcast( - env.builder, - output, - super::convert::zig_list_type(env).into(), - "from_str_list_int", - ) -} - -pub fn call_bitcode_fn_returns_list<'a, 'ctx, 'env>( - env: &Env<'a, 'ctx, 'env>, - args: &[BasicValueEnum<'ctx>], - fn_name: &str, -) -> BasicValueEnum<'ctx> { - let value = call_bitcode_fn(env, args, fn_name); - - list_returned_from_zig(env, value) -} - fn pass_element_as_opaque<'a, 'ctx, 'env>( env: &Env<'a, 'ctx, 'env>, element: BasicValueEnum<'ctx>, @@ -108,7 +85,7 @@ pub fn list_single<'a, 'ctx, 'env>( element: BasicValueEnum<'ctx>, element_layout: &Layout<'a>, ) -> BasicValueEnum<'ctx> { - call_bitcode_fn_returns_list( + call_list_bitcode_fn( env, &[ env.alignment_intvalue(element_layout), @@ -129,7 +106,7 @@ pub fn list_repeat<'a, 'ctx, 'env>( ) -> BasicValueEnum<'ctx> { let inc_element_fn = build_inc_n_wrapper(env, layout_ids, element_layout); - call_bitcode_fn_returns_list( + call_list_bitcode_fn( env, &[ list_len.into(), @@ -148,7 +125,7 @@ pub fn list_join<'a, 'ctx, 'env>( outer_list: BasicValueEnum<'ctx>, element_layout: &Layout<'a>, ) -> BasicValueEnum<'ctx> { - call_bitcode_fn_returns_list( + call_list_bitcode_fn( env, &[ pass_list_cc(env, outer_list), @@ -166,7 +143,7 @@ pub fn list_reverse<'a, 'ctx, 'env>( element_layout: &Layout<'a>, update_mode: UpdateMode, ) -> BasicValueEnum<'ctx> { - call_bitcode_fn_returns_list( + call_list_bitcode_fn( env, &[ pass_list_cc(env, list), @@ -213,7 +190,7 @@ pub fn list_append<'a, 'ctx, 'env>( element_layout: &Layout<'a>, update_mode: UpdateMode, ) -> BasicValueEnum<'ctx> { - call_bitcode_fn_returns_list( + call_list_bitcode_fn( env, &[ pass_list_cc(env, original_wrapper.into()), @@ -233,7 +210,7 @@ pub fn list_prepend<'a, 'ctx, 'env>( element: BasicValueEnum<'ctx>, element_layout: &Layout<'a>, ) -> BasicValueEnum<'ctx> { - call_bitcode_fn_returns_list( + call_list_bitcode_fn( env, &[ pass_list_cc(env, original_wrapper.into()), @@ -254,7 +231,7 @@ pub fn list_swap<'a, 'ctx, 'env>( element_layout: &Layout<'a>, update_mode: UpdateMode, ) -> BasicValueEnum<'ctx> { - call_bitcode_fn_returns_list( + call_list_bitcode_fn( env, &[ pass_list_cc(env, original_wrapper.into()), @@ -278,7 +255,7 @@ pub fn list_sublist<'a, 'ctx, 'env>( element_layout: &Layout<'a>, ) -> BasicValueEnum<'ctx> { let dec_element_fn = build_dec_wrapper(env, layout_ids, element_layout); - call_bitcode_fn_returns_list( + call_list_bitcode_fn( env, &[ pass_list_cc(env, original_wrapper.into()), @@ -301,7 +278,7 @@ pub fn list_drop_at<'a, 'ctx, 'env>( element_layout: &Layout<'a>, ) -> BasicValueEnum<'ctx> { let dec_element_fn = build_dec_wrapper(env, layout_ids, element_layout); - call_bitcode_fn_returns_list( + call_list_bitcode_fn( env, &[ pass_list_cc(env, original_wrapper.into()), @@ -543,7 +520,7 @@ pub fn list_keep_if<'a, 'ctx, 'env>( let inc_element_fn = build_inc_wrapper(env, layout_ids, element_layout); let dec_element_fn = build_dec_wrapper(env, layout_ids, element_layout); - call_bitcode_fn_returns_list( + call_list_bitcode_fn( env, &[ pass_list_cc(env, list), @@ -672,7 +649,7 @@ pub fn list_sort_with<'a, 'ctx, 'env>( list: BasicValueEnum<'ctx>, element_layout: &Layout<'a>, ) -> BasicValueEnum<'ctx> { - call_bitcode_fn_returns_list( + call_list_bitcode_fn( env, &[ pass_list_cc(env, list), @@ -695,7 +672,7 @@ pub fn list_map_with_index<'a, 'ctx, 'env>( element_layout: &Layout<'a>, return_layout: &Layout<'a>, ) -> BasicValueEnum<'ctx> { - call_bitcode_fn_returns_list( + call_list_bitcode_fn( env, &[ pass_list_cc(env, list), @@ -719,7 +696,7 @@ pub fn list_map<'a, 'ctx, 'env>( element_layout: &Layout<'a>, return_layout: &Layout<'a>, ) -> BasicValueEnum<'ctx> { - call_bitcode_fn_returns_list( + call_list_bitcode_fn( env, &[ pass_list_cc(env, list), @@ -784,7 +761,7 @@ pub fn list_map3<'a, 'ctx, 'env>( let dec_b = build_dec_wrapper(env, layout_ids, element2_layout); let dec_c = build_dec_wrapper(env, layout_ids, element3_layout); - call_bitcode_fn_returns_list( + call_list_bitcode_fn( env, &[ pass_list_cc(env, list1), @@ -826,7 +803,7 @@ pub fn list_map4<'a, 'ctx, 'env>( let dec_c = build_dec_wrapper(env, layout_ids, element3_layout); let dec_d = build_dec_wrapper(env, layout_ids, element4_layout); - call_bitcode_fn_returns_list( + call_list_bitcode_fn( env, &[ pass_list_cc(env, list1), @@ -859,7 +836,7 @@ pub fn list_concat<'a, 'ctx, 'env>( second_list: BasicValueEnum<'ctx>, element_layout: &Layout<'a>, ) -> BasicValueEnum<'ctx> { - call_bitcode_fn_returns_list( + call_list_bitcode_fn( env, &[ pass_list_cc(env, first_list), diff --git a/compiler/gen_llvm/src/llvm/build_str.rs b/compiler/gen_llvm/src/llvm/build_str.rs index 4ce155aac6..966112c69d 100644 --- a/compiler/gen_llvm/src/llvm/build_str.rs +++ b/compiler/gen_llvm/src/llvm/build_str.rs @@ -1,8 +1,8 @@ -use crate::llvm::bitcode::{call_bitcode_fn, call_void_bitcode_fn}; -use crate::llvm::build::{complex_bitcast, Env, Scope}; -use crate::llvm::build_list::{ - allocate_list, call_bitcode_fn_returns_list, pass_update_mode, store_list, +use crate::llvm::bitcode::{ + call_bitcode_fn, call_list_bitcode_fn, call_str_bitcode_fn, call_void_bitcode_fn, }; +use crate::llvm::build::{complex_bitcast, Env, Scope}; +use crate::llvm::build_list::{allocate_list, pass_update_mode, store_list}; use inkwell::builder::Builder; use inkwell::values::{BasicValueEnum, FunctionValue, IntValue, PointerValue, StructValue}; use inkwell::AddressSpace; @@ -25,7 +25,7 @@ pub fn str_repeat<'a, 'ctx, 'env>( ) -> BasicValueEnum<'ctx> { let str_c_abi = str_symbol_to_c_abi(env, scope, str_symbol); let count = load_symbol(scope, &count_symbol); - call_bitcode_fn(env, &[str_c_abi.into(), count], bitcode::STR_REPEAT) + call_str_bitcode_fn(env, &[str_c_abi.into(), count], bitcode::STR_REPEAT) } /// Str.split : Str, Str -> List Str @@ -40,7 +40,7 @@ pub fn str_split<'a, 'ctx, 'env>( let str_c_abi = str_symbol_to_c_abi(env, scope, str_symbol); let delim_c_abi = str_symbol_to_c_abi(env, scope, delimiter_symbol); - let segment_count = call_bitcode_fn( + let segment_count = call_list_bitcode_fn( env, &[str_c_abi.into(), delim_c_abi.into()], bitcode::STR_COUNT_SEGMENTS, @@ -140,7 +140,7 @@ pub fn str_concat<'a, 'ctx, 'env>( let str1_c_abi = str_symbol_to_c_abi(env, scope, str1_symbol); let str2_c_abi = str_symbol_to_c_abi(env, scope, str2_symbol); - call_bitcode_fn( + call_str_bitcode_fn( env, &[str1_c_abi.into(), str2_c_abi.into()], bitcode::STR_CONCAT, @@ -159,7 +159,7 @@ pub fn str_join_with<'a, 'ctx, 'env>( let list_i128 = str_symbol_to_c_abi(env, scope, list_symbol); let str_i128 = str_symbol_to_c_abi(env, scope, str_symbol); - call_bitcode_fn( + call_str_bitcode_fn( env, &[list_i128.into(), str_i128.into()], bitcode::STR_JOIN_WITH, @@ -255,7 +255,7 @@ pub fn str_trim<'a, 'ctx, 'env>( str_symbol: Symbol, ) -> BasicValueEnum<'ctx> { let str_i128 = str_symbol_to_c_abi(env, scope, str_symbol); - call_bitcode_fn(env, &[str_i128.into()], bitcode::STR_TRIM) + call_str_bitcode_fn(env, &[str_i128.into()], bitcode::STR_TRIM) } /// Str.trimLeft : Str -> Str @@ -265,7 +265,7 @@ pub fn str_trim_left<'a, 'ctx, 'env>( str_symbol: Symbol, ) -> BasicValueEnum<'ctx> { let str_i128 = str_symbol_to_c_abi(env, scope, str_symbol); - call_bitcode_fn(env, &[str_i128.into()], bitcode::STR_TRIM_LEFT) + call_str_bitcode_fn(env, &[str_i128.into()], bitcode::STR_TRIM_LEFT) } /// Str.trimRight : Str -> Str @@ -275,7 +275,7 @@ pub fn str_trim_right<'a, 'ctx, 'env>( str_symbol: Symbol, ) -> BasicValueEnum<'ctx> { let str_i128 = str_symbol_to_c_abi(env, scope, str_symbol); - call_bitcode_fn(env, &[str_i128.into()], bitcode::STR_TRIM_RIGHT) + call_str_bitcode_fn(env, &[str_i128.into()], bitcode::STR_TRIM_RIGHT) } /// Str.fromInt : Int -> Str @@ -284,7 +284,7 @@ pub fn str_from_int<'a, 'ctx, 'env>( value: IntValue<'ctx>, int_width: IntWidth, ) -> BasicValueEnum<'ctx> { - call_bitcode_fn(env, &[value.into()], &bitcode::STR_FROM_INT[int_width]) + call_str_bitcode_fn(env, &[value.into()], &bitcode::STR_FROM_INT[int_width]) } /// Str.toUtf8 : Str -> List U8 @@ -299,7 +299,7 @@ pub fn str_to_utf8<'a, 'ctx, 'env>( "to_utf8", ); - call_bitcode_fn_returns_list(env, &[string], bitcode::STR_TO_UTF8) + call_list_bitcode_fn(env, &[string], bitcode::STR_TO_UTF8) } fn decode_from_utf8_result<'a, 'ctx, 'env>( @@ -411,7 +411,7 @@ pub fn str_from_float<'a, 'ctx, 'env>( ) -> BasicValueEnum<'ctx> { let float = load_symbol(scope, &int_symbol); - call_bitcode_fn(env, &[float], bitcode::STR_FROM_FLOAT) + call_str_bitcode_fn(env, &[float], bitcode::STR_FROM_FLOAT) } /// Str.equal : Str, Str -> Bool diff --git a/compiler/test_gen/src/helpers/llvm.rs b/compiler/test_gen/src/helpers/llvm.rs index d7a24effa9..24569e3906 100644 --- a/compiler/test_gen/src/helpers/llvm.rs +++ b/compiler/test_gen/src/helpers/llvm.rs @@ -3,13 +3,10 @@ use inkwell::module::Module; use libloading::Library; use roc_build::link::module_to_dylib; use roc_build::program::FunctionIterator; -use roc_can::def::Def; use roc_collections::all::{MutMap, MutSet}; use roc_gen_llvm::llvm::externs::add_default_roc_externs; -use roc_module::symbol::Symbol; use roc_mono::ir::OptLevel; use roc_region::all::LineInfo; -use roc_types::subs::VarStore; use target_lexicon::Triple; fn promote_expr_to_module(src: &str) -> String {