mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 21:39:07 +00:00
switch to passing the copy function into zig (implement llvm)
This commit is contained in:
parent
d028aa3c74
commit
82764dc697
5 changed files with 173 additions and 102 deletions
|
@ -5,6 +5,7 @@ use crate::llvm::build::{
|
|||
FAST_CALL_CONV,
|
||||
};
|
||||
use crate::llvm::convert::basic_type_from_layout;
|
||||
use crate::llvm::memcpy::build_memcpy;
|
||||
use crate::llvm::refcounting::{
|
||||
decrement_refcount_layout, increment_n_refcount_layout, increment_refcount_layout,
|
||||
};
|
||||
|
@ -736,6 +737,78 @@ pub fn build_compare_wrapper<'a, 'ctx>(
|
|||
function_value
|
||||
}
|
||||
|
||||
pub fn build_copy_wrapper<'a, 'ctx>(
|
||||
env: &Env<'a, 'ctx, '_>,
|
||||
layout_interner: &STLayoutInterner<'a>,
|
||||
layout_ids: &mut LayoutIds<'a>,
|
||||
layout: InLayout<'a>,
|
||||
) -> FunctionValue<'ctx> {
|
||||
let block = env.builder.get_insert_block().expect("to be in a function");
|
||||
let di_location = env.builder.get_current_debug_location().unwrap();
|
||||
|
||||
let symbol = Symbol::GENERIC_COPY_REF;
|
||||
let fn_name = layout_ids
|
||||
.get(symbol, &layout_interner.get_repr(layout))
|
||||
.to_symbol_string(symbol, &env.interns);
|
||||
|
||||
let function_value = match env.module.get_function(fn_name.as_str()) {
|
||||
Some(function_value) => function_value,
|
||||
None => {
|
||||
let arg_type = env.context.i8_type().ptr_type(AddressSpace::default());
|
||||
|
||||
let function_value = crate::llvm::refcounting::build_header_help(
|
||||
env,
|
||||
&fn_name,
|
||||
env.context.void_type().into(),
|
||||
&[arg_type.into(), arg_type.into()],
|
||||
);
|
||||
|
||||
// called from zig, must use C calling convention
|
||||
function_value.set_call_conventions(C_CALL_CONV);
|
||||
|
||||
let kind_id = Attribute::get_named_enum_kind_id("alwaysinline");
|
||||
debug_assert!(kind_id > 0);
|
||||
let attr = env.context.create_enum_attribute(kind_id, 0);
|
||||
function_value.add_attribute(AttributeLoc::Function, attr);
|
||||
|
||||
let entry = env.context.append_basic_block(function_value, "entry");
|
||||
env.builder.position_at_end(entry);
|
||||
|
||||
debug_info_init!(env, function_value);
|
||||
|
||||
let mut it = function_value.get_param_iter();
|
||||
let dst_ptr = it.next().unwrap().into_pointer_value();
|
||||
let src_ptr = it.next().unwrap().into_pointer_value();
|
||||
|
||||
dst_ptr.set_name(Symbol::ARG_1.as_str(&env.interns));
|
||||
src_ptr.set_name(Symbol::ARG_2.as_str(&env.interns));
|
||||
|
||||
let repr = layout_interner.get_repr(layout);
|
||||
let value_type = basic_type_from_layout(env, layout_interner, repr)
|
||||
.ptr_type(AddressSpace::default());
|
||||
|
||||
let dst_cast = env
|
||||
.builder
|
||||
.new_build_pointer_cast(dst_ptr, value_type, "load_opaque");
|
||||
|
||||
let src_cast = env
|
||||
.builder
|
||||
.new_build_pointer_cast(src_ptr, value_type, "load_opaque");
|
||||
|
||||
build_memcpy(env, layout_interner, repr, dst_cast, src_cast);
|
||||
|
||||
env.builder.new_build_return(None);
|
||||
|
||||
function_value
|
||||
}
|
||||
};
|
||||
|
||||
env.builder.position_at_end(block);
|
||||
env.builder.set_current_debug_location(di_location);
|
||||
|
||||
function_value
|
||||
}
|
||||
|
||||
enum BitcodeReturnValue<'ctx> {
|
||||
List(PointerValue<'ctx>),
|
||||
Str(PointerValue<'ctx>),
|
||||
|
|
|
@ -12,7 +12,7 @@ use roc_mono::layout::{
|
|||
Builtin, InLayout, Layout, LayoutIds, LayoutInterner, LayoutRepr, STLayoutInterner,
|
||||
};
|
||||
|
||||
use super::bitcode::{build_inc_wrapper, call_list_bitcode_fn, BitcodeReturns};
|
||||
use super::bitcode::{build_copy_wrapper, build_inc_wrapper, call_list_bitcode_fn, BitcodeReturns};
|
||||
use super::build::{
|
||||
create_entry_block_alloca, load_roc_value, store_roc_value, use_roc_value, BuilderExt,
|
||||
};
|
||||
|
@ -235,16 +235,19 @@ pub(crate) fn list_release_excess_capacity<'a, 'ctx>(
|
|||
pub(crate) fn list_append_unsafe<'a, 'ctx>(
|
||||
env: &Env<'a, 'ctx, '_>,
|
||||
layout_interner: &STLayoutInterner<'a>,
|
||||
layout_ids: &mut LayoutIds<'a>,
|
||||
original_wrapper: StructValue<'ctx>,
|
||||
element: BasicValueEnum<'ctx>,
|
||||
element_layout: InLayout<'a>,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
let copy_fn = build_copy_wrapper(env, layout_interner, layout_ids, element_layout);
|
||||
call_list_bitcode_fn_1(
|
||||
env,
|
||||
original_wrapper,
|
||||
&[
|
||||
pass_element_as_opaque(env, layout_interner, element, element_layout),
|
||||
layout_width(env, layout_interner, element_layout),
|
||||
copy_fn.as_global_value().as_pointer_value().into(),
|
||||
],
|
||||
bitcode::LIST_APPEND_UNSAFE,
|
||||
)
|
||||
|
@ -260,6 +263,7 @@ pub(crate) fn list_prepend<'a, 'ctx>(
|
|||
element_layout: InLayout<'a>,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
let inc_element_fn = build_inc_wrapper(env, layout_interner, layout_ids, element_layout);
|
||||
let copy_fn = build_copy_wrapper(env, layout_interner, layout_ids, element_layout);
|
||||
call_list_bitcode_fn_1(
|
||||
env,
|
||||
original_wrapper,
|
||||
|
@ -269,6 +273,7 @@ pub(crate) fn list_prepend<'a, 'ctx>(
|
|||
layout_width(env, layout_interner, element_layout),
|
||||
layout_refcounted(env, layout_interner, element_layout),
|
||||
inc_element_fn.as_global_value().as_pointer_value().into(),
|
||||
copy_fn.as_global_value().as_pointer_value().into(),
|
||||
],
|
||||
bitcode::LIST_PREPEND,
|
||||
)
|
||||
|
@ -310,6 +315,7 @@ pub(crate) fn list_swap<'a, 'ctx>(
|
|||
) -> BasicValueEnum<'ctx> {
|
||||
let inc_element_fn = build_inc_wrapper(env, layout_interner, layout_ids, element_layout);
|
||||
let dec_element_fn = build_dec_wrapper(env, layout_interner, layout_ids, element_layout);
|
||||
let copy_fn = build_copy_wrapper(env, layout_interner, layout_ids, element_layout);
|
||||
|
||||
call_list_bitcode_fn_1(
|
||||
env,
|
||||
|
@ -323,6 +329,7 @@ pub(crate) fn list_swap<'a, 'ctx>(
|
|||
inc_element_fn.as_global_value().as_pointer_value().into(),
|
||||
dec_element_fn.as_global_value().as_pointer_value().into(),
|
||||
pass_update_mode(env, update_mode),
|
||||
copy_fn.as_global_value().as_pointer_value().into(),
|
||||
],
|
||||
bitcode::LIST_SWAP,
|
||||
)
|
||||
|
@ -397,6 +404,7 @@ pub(crate) fn list_replace_unsafe<'a, 'ctx>(
|
|||
layout_interner.get_repr(element_layout),
|
||||
);
|
||||
let element_ptr = create_entry_block_alloca(env, element_type, "output_element_as_opaque");
|
||||
let copy_fn = build_copy_wrapper(env, layout_interner, layout_ids, element_layout);
|
||||
|
||||
// Assume the bounds have already been checked earlier
|
||||
// (e.g. by List.replace or List.set, which wrap List.#replaceUnsafe)
|
||||
|
@ -409,6 +417,7 @@ pub(crate) fn list_replace_unsafe<'a, 'ctx>(
|
|||
pass_element_as_opaque(env, layout_interner, element, element_layout),
|
||||
layout_width(env, layout_interner, element_layout),
|
||||
pass_as_opaque(env, element_ptr),
|
||||
copy_fn.as_global_value().as_pointer_value().into(),
|
||||
],
|
||||
bitcode::LIST_REPLACE_IN_PLACE,
|
||||
),
|
||||
|
@ -429,6 +438,7 @@ pub(crate) fn list_replace_unsafe<'a, 'ctx>(
|
|||
inc_element_fn.as_global_value().as_pointer_value().into(),
|
||||
dec_element_fn.as_global_value().as_pointer_value().into(),
|
||||
pass_as_opaque(env, element_ptr),
|
||||
copy_fn.as_global_value().as_pointer_value().into(),
|
||||
],
|
||||
bitcode::LIST_REPLACE,
|
||||
)
|
||||
|
@ -536,6 +546,7 @@ pub(crate) fn list_sort_with<'a, 'ctx>(
|
|||
) -> BasicValueEnum<'ctx> {
|
||||
let inc_element_fn = build_inc_wrapper(env, layout_interner, layout_ids, element_layout);
|
||||
let dec_element_fn = build_dec_wrapper(env, layout_interner, layout_ids, element_layout);
|
||||
let copy_fn = build_copy_wrapper(env, layout_interner, layout_ids, element_layout);
|
||||
call_list_bitcode_fn_1(
|
||||
env,
|
||||
list.into_struct_value(),
|
||||
|
@ -549,6 +560,7 @@ pub(crate) fn list_sort_with<'a, 'ctx>(
|
|||
layout_refcounted(env, layout_interner, element_layout),
|
||||
inc_element_fn.as_global_value().as_pointer_value().into(),
|
||||
dec_element_fn.as_global_value().as_pointer_value().into(),
|
||||
copy_fn.as_global_value().as_pointer_value().into(),
|
||||
],
|
||||
bitcode::LIST_SORT_WITH,
|
||||
)
|
||||
|
|
|
@ -670,7 +670,14 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
|||
let original_wrapper = scope.load_symbol(&args[0]).into_struct_value();
|
||||
let (elem, elem_layout) = scope.load_symbol_and_layout(&args[1]);
|
||||
|
||||
list_append_unsafe(env, layout_interner, original_wrapper, elem, elem_layout)
|
||||
list_append_unsafe(
|
||||
env,
|
||||
layout_interner,
|
||||
layout_ids,
|
||||
original_wrapper,
|
||||
elem,
|
||||
elem_layout,
|
||||
)
|
||||
}
|
||||
ListPrepend => {
|
||||
// List.prepend : List elem, elem -> List elem
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue