mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-21 07:49:17 +03:00
rework refcount code gen to accept unknown inc values
This commit is contained in:
parent
7c58c775d9
commit
febb578773
@ -204,13 +204,14 @@ fn build_transform_caller_help<'a, 'ctx, 'env>(
|
||||
function_value
|
||||
}
|
||||
|
||||
pub fn build_inc_n_wrapper<'a, 'ctx, 'env>(
|
||||
fn build_inc_n_wrapper<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
layout_ids: &mut LayoutIds<'a>,
|
||||
layout: &Layout<'a>,
|
||||
n: u64,
|
||||
) -> FunctionValue<'ctx> {
|
||||
build_rc_wrapper(env, layout_ids, layout, Mode::Inc(n))
|
||||
// build_rc_wrapper(env, layout_ids, layout, Mode::Inc(n))
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn build_inc_wrapper<'a, 'ctx, 'env>(
|
||||
@ -218,7 +219,7 @@ pub fn build_inc_wrapper<'a, 'ctx, 'env>(
|
||||
layout_ids: &mut LayoutIds<'a>,
|
||||
layout: &Layout<'a>,
|
||||
) -> FunctionValue<'ctx> {
|
||||
build_rc_wrapper(env, layout_ids, layout, Mode::Inc(1))
|
||||
build_rc_wrapper(env, layout_ids, layout, Mode::Inc)
|
||||
}
|
||||
|
||||
pub fn build_dec_wrapper<'a, 'ctx, 'env>(
|
||||
@ -244,7 +245,7 @@ pub fn build_rc_wrapper<'a, 'ctx, 'env>(
|
||||
.to_symbol_string(symbol, &env.interns);
|
||||
|
||||
let fn_name = match rc_operation {
|
||||
Mode::Inc(n) => format!("{}_inc_{}", fn_name, n),
|
||||
Mode::Inc => format!("{}_inc", fn_name),
|
||||
Mode::Dec => format!("{}_dec", fn_name),
|
||||
};
|
||||
|
||||
@ -285,7 +286,9 @@ pub fn build_rc_wrapper<'a, 'ctx, 'env>(
|
||||
let value = env.builder.build_load(value_cast, "load_opaque");
|
||||
|
||||
match rc_operation {
|
||||
Mode::Inc(n) => {
|
||||
Mode::Inc => {
|
||||
// we hardcode the 1 here
|
||||
let n = 1;
|
||||
increment_refcount_layout(env, function_value, layout_ids, n, value, layout);
|
||||
}
|
||||
Mode::Dec => {
|
||||
|
@ -109,7 +109,7 @@ impl<'ctx> PointerToRefcount<'ctx> {
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
) {
|
||||
match mode {
|
||||
CallMode::Inc(_, inc_amount) => self.increment(inc_amount, env),
|
||||
CallMode::Inc(inc_amount) => self.increment(inc_amount, env),
|
||||
CallMode::Dec => self.decrement(env, layout),
|
||||
}
|
||||
}
|
||||
@ -318,11 +318,84 @@ fn modify_refcount_struct<'a, 'ctx, 'env>(
|
||||
parent: FunctionValue<'ctx>,
|
||||
layout_ids: &mut LayoutIds<'a>,
|
||||
value: BasicValueEnum<'ctx>,
|
||||
layouts: &[Layout<'a>],
|
||||
layouts: &'a [Layout<'a>],
|
||||
mode: Mode,
|
||||
when_recursive: &WhenRecursive<'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 layout = Layout::Struct(layouts);
|
||||
|
||||
let (call_name, fn_name) = function_name_from_mode(
|
||||
layout_ids,
|
||||
&env.interns,
|
||||
"increment_struct",
|
||||
"decrement_struct",
|
||||
&layout,
|
||||
mode,
|
||||
);
|
||||
|
||||
let function = match env.module.get_function(fn_name.as_str()) {
|
||||
Some(function_value) => function_value,
|
||||
None => {
|
||||
let basic_type = basic_type_from_layout(env, &layout);
|
||||
let function_value = build_header(env, basic_type, mode, &fn_name);
|
||||
|
||||
modify_refcount_struct_help(
|
||||
env,
|
||||
layout_ids,
|
||||
mode,
|
||||
when_recursive,
|
||||
layouts,
|
||||
function_value,
|
||||
);
|
||||
|
||||
function_value
|
||||
}
|
||||
};
|
||||
|
||||
env.builder.position_at_end(block);
|
||||
env.builder
|
||||
.set_current_debug_location(env.context, di_location);
|
||||
|
||||
function
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn modify_refcount_struct_help<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
layout_ids: &mut LayoutIds<'a>,
|
||||
mode: Mode,
|
||||
when_recursive: &WhenRecursive<'a>,
|
||||
layouts: &[Layout<'a>],
|
||||
fn_val: FunctionValue<'ctx>,
|
||||
) {
|
||||
let wrapper_struct = value.into_struct_value();
|
||||
debug_assert_eq!(
|
||||
when_recursive,
|
||||
&WhenRecursive::Unreachable,
|
||||
"TODO pipe when_recursive through the dict key/value inc/dec"
|
||||
);
|
||||
|
||||
let builder = env.builder;
|
||||
let ctx = env.context;
|
||||
|
||||
// Add a basic block for the entry point
|
||||
let entry = ctx.append_basic_block(fn_val, "entry");
|
||||
|
||||
builder.position_at_end(entry);
|
||||
|
||||
debug_info_init!(env, fn_val);
|
||||
|
||||
// Add args to scope
|
||||
let arg_symbol = Symbol::ARG_1;
|
||||
let arg_val = fn_val.get_param_iter().next().unwrap();
|
||||
|
||||
set_name(arg_val, arg_symbol.ident_string(&env.interns));
|
||||
|
||||
let parent = fn_val;
|
||||
|
||||
let wrapper_struct = arg_val.into_struct_value();
|
||||
|
||||
for (i, field_layout) in layouts.iter().enumerate() {
|
||||
if field_layout.contains_refcounted() {
|
||||
@ -335,13 +408,15 @@ fn modify_refcount_struct<'a, 'ctx, 'env>(
|
||||
env,
|
||||
parent,
|
||||
layout_ids,
|
||||
mode,
|
||||
mode.to_call_mode(fn_val),
|
||||
when_recursive,
|
||||
field_ptr,
|
||||
field_layout,
|
||||
);
|
||||
}
|
||||
}
|
||||
// this function returns void
|
||||
builder.build_return(None);
|
||||
}
|
||||
|
||||
pub fn increment_refcount_layout<'a, 'ctx, 'env>(
|
||||
@ -352,11 +427,12 @@ pub fn increment_refcount_layout<'a, 'ctx, 'env>(
|
||||
value: BasicValueEnum<'ctx>,
|
||||
layout: &Layout<'a>,
|
||||
) {
|
||||
let amount = env.ptr_int().const_int(inc_amount, false);
|
||||
modify_refcount_layout(
|
||||
env,
|
||||
parent,
|
||||
layout_ids,
|
||||
Mode::Inc(inc_amount),
|
||||
CallMode::Inc(amount),
|
||||
value,
|
||||
layout,
|
||||
);
|
||||
@ -369,7 +445,7 @@ pub fn decrement_refcount_layout<'a, 'ctx, 'env>(
|
||||
value: BasicValueEnum<'ctx>,
|
||||
layout: &Layout<'a>,
|
||||
) {
|
||||
modify_refcount_layout(env, parent, layout_ids, Mode::Dec, value, layout);
|
||||
modify_refcount_layout(env, parent, layout_ids, CallMode::Dec, value, layout);
|
||||
}
|
||||
|
||||
fn modify_refcount_builtin<'a, 'ctx, 'env>(
|
||||
@ -380,7 +456,7 @@ fn modify_refcount_builtin<'a, 'ctx, 'env>(
|
||||
value: BasicValueEnum<'ctx>,
|
||||
layout: &Layout<'a>,
|
||||
builtin: &Builtin<'a>,
|
||||
) {
|
||||
) -> Option<FunctionValue<'ctx>> {
|
||||
use Builtin::*;
|
||||
|
||||
match builtin {
|
||||
@ -388,7 +464,7 @@ fn modify_refcount_builtin<'a, 'ctx, 'env>(
|
||||
let wrapper_struct = value.into_struct_value();
|
||||
|
||||
if let MemoryMode::Refcounted = memory_mode {
|
||||
modify_refcount_list(
|
||||
let function = modify_refcount_list(
|
||||
env,
|
||||
layout_ids,
|
||||
mode,
|
||||
@ -397,17 +473,19 @@ fn modify_refcount_builtin<'a, 'ctx, 'env>(
|
||||
element_layout,
|
||||
wrapper_struct,
|
||||
);
|
||||
|
||||
Some(function)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
Set(element_layout) => {
|
||||
if element_layout.contains_refcounted() {
|
||||
// TODO decrement all values
|
||||
}
|
||||
todo!();
|
||||
}
|
||||
Dict(key_layout, value_layout) => {
|
||||
let wrapper_struct = value.into_struct_value();
|
||||
modify_refcount_dict(
|
||||
|
||||
let key_layout = &Layout::Struct(&[]);
|
||||
let value_layout = element_layout;
|
||||
|
||||
let function = modify_refcount_dict(
|
||||
env,
|
||||
layout_ids,
|
||||
mode,
|
||||
@ -417,14 +495,34 @@ fn modify_refcount_builtin<'a, 'ctx, 'env>(
|
||||
value_layout,
|
||||
wrapper_struct,
|
||||
);
|
||||
|
||||
Some(function)
|
||||
}
|
||||
Dict(key_layout, value_layout) => {
|
||||
let wrapper_struct = value.into_struct_value();
|
||||
let function = modify_refcount_dict(
|
||||
env,
|
||||
layout_ids,
|
||||
mode,
|
||||
when_recursive,
|
||||
layout,
|
||||
key_layout,
|
||||
value_layout,
|
||||
wrapper_struct,
|
||||
);
|
||||
|
||||
Some(function)
|
||||
}
|
||||
|
||||
Str => {
|
||||
let wrapper_struct = value.into_struct_value();
|
||||
modify_refcount_str(env, layout_ids, mode, layout, wrapper_struct);
|
||||
let function = modify_refcount_str(env, layout_ids, mode, layout, wrapper_struct);
|
||||
|
||||
Some(function)
|
||||
}
|
||||
_ => {
|
||||
debug_assert!(!builtin.is_refcounted());
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -433,7 +531,7 @@ fn modify_refcount_layout<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
parent: FunctionValue<'ctx>,
|
||||
layout_ids: &mut LayoutIds<'a>,
|
||||
mode: Mode,
|
||||
call_mode: CallMode<'ctx>,
|
||||
value: BasicValueEnum<'ctx>,
|
||||
layout: &Layout<'a>,
|
||||
) {
|
||||
@ -441,7 +539,7 @@ fn modify_refcount_layout<'a, 'ctx, 'env>(
|
||||
env,
|
||||
parent,
|
||||
layout_ids,
|
||||
mode,
|
||||
call_mode,
|
||||
&WhenRecursive::Unreachable,
|
||||
value,
|
||||
layout,
|
||||
@ -458,11 +556,60 @@ fn modify_refcount_layout_help<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
parent: FunctionValue<'ctx>,
|
||||
layout_ids: &mut LayoutIds<'a>,
|
||||
mode: Mode,
|
||||
call_mode: CallMode<'ctx>,
|
||||
when_recursive: &WhenRecursive<'a>,
|
||||
value: BasicValueEnum<'ctx>,
|
||||
layout: &Layout<'a>,
|
||||
) {
|
||||
let mode = match call_mode {
|
||||
CallMode::Inc(_) => Mode::Inc,
|
||||
CallMode::Dec => Mode::Dec,
|
||||
};
|
||||
|
||||
let function = match modify_refcount_layout_build_function(
|
||||
env,
|
||||
parent,
|
||||
layout_ids,
|
||||
mode,
|
||||
when_recursive,
|
||||
value,
|
||||
layout,
|
||||
) {
|
||||
Some(f) => f,
|
||||
None => return,
|
||||
};
|
||||
|
||||
call_help(env, function, call_mode, value);
|
||||
}
|
||||
|
||||
fn call_help<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
function: FunctionValue<'ctx>,
|
||||
call_mode: CallMode<'ctx>,
|
||||
value: BasicValueEnum<'ctx>,
|
||||
) -> inkwell::values::CallSiteValue<'ctx> {
|
||||
let call = match call_mode {
|
||||
CallMode::Inc(inc_amount) => {
|
||||
env.builder
|
||||
.build_call(function, &[value, inc_amount.into()], "increment")
|
||||
}
|
||||
CallMode::Dec => env.builder.build_call(function, &[value], "decrement"),
|
||||
};
|
||||
|
||||
call.set_call_convention(FAST_CALL_CONV);
|
||||
|
||||
call
|
||||
}
|
||||
|
||||
fn modify_refcount_layout_build_function<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
parent: FunctionValue<'ctx>,
|
||||
layout_ids: &mut LayoutIds<'a>,
|
||||
mode: Mode,
|
||||
when_recursive: &WhenRecursive<'a>,
|
||||
value: BasicValueEnum<'ctx>,
|
||||
layout: &Layout<'a>,
|
||||
) -> Option<FunctionValue<'ctx>> {
|
||||
use Layout::*;
|
||||
|
||||
match layout {
|
||||
@ -485,7 +632,7 @@ fn modify_refcount_layout_help<'a, 'ctx, 'env>(
|
||||
} => {
|
||||
debug_assert!(value.is_pointer_value());
|
||||
|
||||
build_rec_union(
|
||||
let function = build_rec_union(
|
||||
env,
|
||||
layout_ids,
|
||||
mode,
|
||||
@ -494,6 +641,8 @@ fn modify_refcount_layout_help<'a, 'ctx, 'env>(
|
||||
value.into_pointer_value(),
|
||||
true,
|
||||
);
|
||||
|
||||
Some(function)
|
||||
}
|
||||
|
||||
NullableUnwrapped { other_fields, .. } => {
|
||||
@ -501,7 +650,7 @@ fn modify_refcount_layout_help<'a, 'ctx, 'env>(
|
||||
|
||||
let other_fields = &other_fields[1..];
|
||||
|
||||
build_rec_union(
|
||||
let function = build_rec_union(
|
||||
env,
|
||||
layout_ids,
|
||||
mode,
|
||||
@ -510,12 +659,14 @@ fn modify_refcount_layout_help<'a, 'ctx, 'env>(
|
||||
value.into_pointer_value(),
|
||||
true,
|
||||
);
|
||||
|
||||
Some(function)
|
||||
}
|
||||
|
||||
NonNullableUnwrapped(fields) => {
|
||||
debug_assert!(value.is_pointer_value());
|
||||
|
||||
build_rec_union(
|
||||
let function = build_rec_union(
|
||||
env,
|
||||
layout_ids,
|
||||
mode,
|
||||
@ -524,11 +675,12 @@ fn modify_refcount_layout_help<'a, 'ctx, 'env>(
|
||||
value.into_pointer_value(),
|
||||
true,
|
||||
);
|
||||
Some(function)
|
||||
}
|
||||
|
||||
Recursive(tags) => {
|
||||
debug_assert!(value.is_pointer_value());
|
||||
build_rec_union(
|
||||
let function = build_rec_union(
|
||||
env,
|
||||
layout_ids,
|
||||
mode,
|
||||
@ -537,10 +689,14 @@ fn modify_refcount_layout_help<'a, 'ctx, 'env>(
|
||||
value.into_pointer_value(),
|
||||
false,
|
||||
);
|
||||
Some(function)
|
||||
}
|
||||
|
||||
NonRecursive(tags) => {
|
||||
modify_refcount_union(env, layout_ids, mode, when_recursive, tags, value)
|
||||
let function =
|
||||
modify_refcount_union(env, layout_ids, mode, when_recursive, tags, value);
|
||||
|
||||
Some(function)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -553,7 +709,7 @@ fn modify_refcount_layout_help<'a, 'ctx, 'env>(
|
||||
.build_extract_value(wrapper_struct, 1, "modify_rc_closure_data")
|
||||
.unwrap();
|
||||
|
||||
modify_refcount_layout_help(
|
||||
let function = modify_refcount_layout_build_function(
|
||||
env,
|
||||
parent,
|
||||
layout_ids,
|
||||
@ -561,12 +717,16 @@ fn modify_refcount_layout_help<'a, 'ctx, 'env>(
|
||||
when_recursive,
|
||||
field_ptr,
|
||||
&closure_layout.as_block_of_memory_layout(),
|
||||
)
|
||||
)?;
|
||||
|
||||
Some(function)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
Struct(layouts) => {
|
||||
modify_refcount_struct(
|
||||
let function = modify_refcount_struct(
|
||||
env,
|
||||
parent,
|
||||
layout_ids,
|
||||
@ -575,9 +735,11 @@ fn modify_refcount_layout_help<'a, 'ctx, 'env>(
|
||||
mode,
|
||||
when_recursive,
|
||||
);
|
||||
|
||||
Some(function)
|
||||
}
|
||||
|
||||
PhantomEmptyStruct => {}
|
||||
PhantomEmptyStruct => None,
|
||||
|
||||
Layout::RecursivePointer => match when_recursive {
|
||||
WhenRecursive::Unreachable => {
|
||||
@ -594,7 +756,7 @@ fn modify_refcount_layout_help<'a, 'ctx, 'env>(
|
||||
.build_bitcast(value, bt, "i64_to_opaque")
|
||||
.into_pointer_value();
|
||||
|
||||
modify_refcount_layout_help(
|
||||
let function = modify_refcount_layout_build_function(
|
||||
env,
|
||||
parent,
|
||||
layout_ids,
|
||||
@ -602,11 +764,13 @@ fn modify_refcount_layout_help<'a, 'ctx, 'env>(
|
||||
when_recursive,
|
||||
field_cast.into(),
|
||||
&layout,
|
||||
)
|
||||
)?;
|
||||
|
||||
Some(function)
|
||||
}
|
||||
},
|
||||
|
||||
FunctionPointer(_, _) | Pointer(_) => {}
|
||||
FunctionPointer(_, _) | Pointer(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -618,7 +782,7 @@ fn modify_refcount_list<'a, 'ctx, 'env>(
|
||||
layout: &Layout<'a>,
|
||||
element_layout: &Layout<'a>,
|
||||
original_wrapper: StructValue<'ctx>,
|
||||
) {
|
||||
) -> 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();
|
||||
|
||||
@ -655,13 +819,13 @@ fn modify_refcount_list<'a, 'ctx, 'env>(
|
||||
env.builder
|
||||
.set_current_debug_location(env.context, di_location);
|
||||
|
||||
call_help(env, function, mode, original_wrapper.into(), call_name);
|
||||
function
|
||||
}
|
||||
|
||||
fn mode_to_call_mode(function: FunctionValue<'_>, mode: Mode) -> CallMode<'_> {
|
||||
match mode {
|
||||
Mode::Dec => CallMode::Dec,
|
||||
Mode::Inc(num) => CallMode::Inc(num, function.get_nth_param(1).unwrap().into_int_value()),
|
||||
Mode::Inc => CallMode::Inc(function.get_nth_param(1).unwrap().into_int_value()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -720,7 +884,7 @@ fn modify_refcount_list_help<'a, 'ctx, 'env>(
|
||||
env,
|
||||
parent,
|
||||
layout_ids,
|
||||
mode,
|
||||
mode.to_call_mode(fn_val),
|
||||
when_recursive,
|
||||
element,
|
||||
element_layout,
|
||||
@ -756,7 +920,7 @@ fn modify_refcount_str<'a, 'ctx, 'env>(
|
||||
mode: Mode,
|
||||
layout: &Layout<'a>,
|
||||
original_wrapper: StructValue<'ctx>,
|
||||
) {
|
||||
) -> 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();
|
||||
|
||||
@ -785,7 +949,7 @@ fn modify_refcount_str<'a, 'ctx, 'env>(
|
||||
env.builder
|
||||
.set_current_debug_location(env.context, di_location);
|
||||
|
||||
call_help(env, function, mode, original_wrapper.into(), call_name);
|
||||
function
|
||||
}
|
||||
|
||||
fn modify_refcount_str_help<'a, 'ctx, 'env>(
|
||||
@ -856,7 +1020,7 @@ fn modify_refcount_dict<'a, 'ctx, 'env>(
|
||||
key_layout: &Layout<'a>,
|
||||
value_layout: &Layout<'a>,
|
||||
original_wrapper: StructValue<'ctx>,
|
||||
) {
|
||||
) -> 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();
|
||||
|
||||
@ -894,7 +1058,7 @@ fn modify_refcount_dict<'a, 'ctx, 'env>(
|
||||
env.builder
|
||||
.set_current_debug_location(env.context, di_location);
|
||||
|
||||
call_help(env, function, mode, original_wrapper.into(), call_name);
|
||||
function
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
@ -990,7 +1154,7 @@ fn build_header<'a, 'ctx, 'env>(
|
||||
fn_name: &str,
|
||||
) -> FunctionValue<'ctx> {
|
||||
match mode {
|
||||
Mode::Inc(_) => build_header_help(
|
||||
Mode::Inc => build_header_help(
|
||||
env,
|
||||
fn_name,
|
||||
env.context.void_type().into(),
|
||||
@ -1036,13 +1200,26 @@ pub fn build_header_help<'a, 'ctx, 'env>(
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum Mode {
|
||||
Inc(u64),
|
||||
Inc,
|
||||
Dec,
|
||||
}
|
||||
|
||||
impl Mode {
|
||||
fn to_call_mode<'ctx>(&self, function: FunctionValue<'ctx>) -> CallMode<'ctx> {
|
||||
match self {
|
||||
Mode::Inc => {
|
||||
let amount = function.get_nth_param(1).unwrap().into_int_value();
|
||||
|
||||
CallMode::Inc(amount)
|
||||
}
|
||||
Mode::Dec => CallMode::Dec,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum CallMode<'ctx> {
|
||||
Inc(u64, IntValue<'ctx>),
|
||||
Inc(IntValue<'ctx>),
|
||||
Dec,
|
||||
}
|
||||
|
||||
@ -1054,7 +1231,7 @@ fn build_rec_union<'a, 'ctx, 'env>(
|
||||
fields: &'a [&'a [Layout<'a>]],
|
||||
value: PointerValue<'ctx>,
|
||||
is_nullable: bool,
|
||||
) {
|
||||
) -> FunctionValue<'ctx> {
|
||||
let layout = Layout::Union(UnionLayout::Recursive(fields));
|
||||
|
||||
let (call_name, fn_name) = function_name_from_mode(
|
||||
@ -1095,7 +1272,7 @@ fn build_rec_union<'a, 'ctx, 'env>(
|
||||
}
|
||||
};
|
||||
|
||||
call_help(env, function, mode, value.into(), call_name);
|
||||
function
|
||||
}
|
||||
|
||||
fn build_rec_union_help<'a, 'ctx, 'env>(
|
||||
@ -1112,7 +1289,7 @@ fn build_rec_union_help<'a, 'ctx, 'env>(
|
||||
let context = &env.context;
|
||||
let builder = env.builder;
|
||||
|
||||
let pick = |a, b| if let Mode::Inc(_) = mode { a } else { b };
|
||||
let pick = |a, b| if let Mode::Inc = mode { a } else { b };
|
||||
|
||||
// Add a basic block for the entry point
|
||||
let entry = context.append_basic_block(fn_val, "entry");
|
||||
@ -1258,7 +1435,7 @@ fn build_rec_union_help<'a, 'ctx, 'env>(
|
||||
env,
|
||||
parent,
|
||||
layout_ids,
|
||||
mode,
|
||||
mode.to_call_mode(fn_val),
|
||||
when_recursive,
|
||||
field,
|
||||
field_layout,
|
||||
@ -1268,7 +1445,7 @@ fn build_rec_union_help<'a, 'ctx, 'env>(
|
||||
let call_name = pick("recursive_tag_increment", "recursive_tag_decrement");
|
||||
for ptr in deferred_rec {
|
||||
// recursively decrement the field
|
||||
let call = call_help(env, fn_val, mode, ptr, call_name);
|
||||
let call = call_help(env, fn_val, mode.to_call_mode(fn_val), ptr);
|
||||
call.set_tail_call(true);
|
||||
}
|
||||
|
||||
@ -1331,28 +1508,6 @@ fn rec_union_read_tag<'a, 'ctx, 'env>(
|
||||
.into_int_value()
|
||||
}
|
||||
|
||||
fn call_help<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
function: FunctionValue<'ctx>,
|
||||
mode: Mode,
|
||||
value: BasicValueEnum<'ctx>,
|
||||
call_name: &str,
|
||||
) -> inkwell::values::CallSiteValue<'ctx> {
|
||||
let call = match mode {
|
||||
Mode::Inc(inc_amount) => {
|
||||
let rc_increment = ptr_int(env.context, env.ptr_bytes).const_int(inc_amount, false);
|
||||
|
||||
env.builder
|
||||
.build_call(function, &[value, rc_increment.into()], call_name)
|
||||
}
|
||||
Mode::Dec => env.builder.build_call(function, &[value], call_name),
|
||||
};
|
||||
|
||||
call.set_call_convention(FAST_CALL_CONV);
|
||||
|
||||
call
|
||||
}
|
||||
|
||||
fn function_name_from_mode<'a>(
|
||||
layout_ids: &mut LayoutIds<'a>,
|
||||
interns: &Interns,
|
||||
@ -1368,7 +1523,7 @@ fn function_name_from_mode<'a>(
|
||||
// rather confusing, so now `inc_x` always corresponds to `dec_x`
|
||||
let layout_id = layout_ids.get(Symbol::DEC, layout);
|
||||
match mode {
|
||||
Mode::Inc(_) => (if_inc, layout_id.to_symbol_string(Symbol::INC, interns)),
|
||||
Mode::Inc => (if_inc, layout_id.to_symbol_string(Symbol::INC, interns)),
|
||||
Mode::Dec => (if_dec, layout_id.to_symbol_string(Symbol::DEC, interns)),
|
||||
}
|
||||
}
|
||||
@ -1380,7 +1535,7 @@ fn modify_refcount_union<'a, 'ctx, 'env>(
|
||||
when_recursive: &WhenRecursive<'a>,
|
||||
fields: &'a [&'a [Layout<'a>]],
|
||||
value: BasicValueEnum<'ctx>,
|
||||
) {
|
||||
) -> FunctionValue<'ctx> {
|
||||
let layout = Layout::Union(UnionLayout::NonRecursive(fields));
|
||||
|
||||
let block = env.builder.get_insert_block().expect("to be in a function");
|
||||
@ -1418,7 +1573,7 @@ fn modify_refcount_union<'a, 'ctx, 'env>(
|
||||
env.builder
|
||||
.set_current_debug_location(env.context, di_location);
|
||||
|
||||
call_help(env, function, mode, value, call_name);
|
||||
function
|
||||
}
|
||||
|
||||
fn modify_refcount_union_help<'a, 'ctx, 'env>(
|
||||
@ -1509,7 +1664,7 @@ fn modify_refcount_union_help<'a, 'ctx, 'env>(
|
||||
env,
|
||||
parent,
|
||||
layout_ids,
|
||||
mode,
|
||||
mode.to_call_mode(fn_val),
|
||||
when_recursive,
|
||||
field_ptr,
|
||||
field_layout,
|
||||
|
Loading…
Reference in New Issue
Block a user