From 353e161f77ec11ccb7e3d4dbde86b167071e3c35 Mon Sep 17 00:00:00 2001 From: Folkert Date: Sun, 16 May 2021 21:25:47 +0200 Subject: [PATCH] expose support for multi-increment --- compiler/gen/src/llvm/bitcode.rs | 38 ++++++++++++++++++++++------ compiler/gen/src/llvm/refcounting.rs | 11 ++++++++ 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/compiler/gen/src/llvm/bitcode.rs b/compiler/gen/src/llvm/bitcode.rs index 5f9eb5d387..c54b458db5 100644 --- a/compiler/gen/src/llvm/bitcode.rs +++ b/compiler/gen/src/llvm/bitcode.rs @@ -2,7 +2,9 @@ use crate::debug_info_init; use crate::llvm::build::{set_name, Env, C_CALL_CONV, FAST_CALL_CONV}; use crate::llvm::convert::basic_type_from_layout; -use crate::llvm::refcounting::{decrement_refcount_layout, increment_refcount_layout, Mode}; +use crate::llvm::refcounting::{ + decrement_refcount_layout, increment_n_refcount_layout, increment_refcount_layout, +}; use inkwell::attributes::{Attribute, AttributeLoc}; use inkwell::types::{BasicType, BasicTypeEnum}; use inkwell::values::{BasicValueEnum, CallSiteValue, FunctionValue, InstructionValue}; @@ -204,6 +206,12 @@ fn build_transform_caller_help<'a, 'ctx, 'env>( function_value } +enum Mode { + Inc, + IncN, + Dec, +} + /// a functin that accepts two arguments: the value to increment, and an amount to increment by pub fn build_inc_n_wrapper<'a, 'ctx, 'env>( env: &Env<'a, 'ctx, 'env>, @@ -245,6 +253,7 @@ pub fn build_rc_wrapper<'a, 'ctx, 'env>( .to_symbol_string(symbol, &env.interns); let fn_name = match rc_operation { + Mode::IncN => format!("{}_inc_n", fn_name), Mode::Inc => format!("{}_inc", fn_name), Mode::Dec => format!("{}_dec", fn_name), }; @@ -254,12 +263,20 @@ pub fn build_rc_wrapper<'a, 'ctx, 'env>( None => { let arg_type = env.context.i8_type().ptr_type(AddressSpace::Generic); - let function_value = crate::llvm::refcounting::build_header_help( - env, - &fn_name, - env.context.void_type().into(), - &[arg_type.into()], - ); + let function_value = match rc_operation { + Mode::Inc | Mode::Dec => crate::llvm::refcounting::build_header_help( + env, + &fn_name, + env.context.void_type().into(), + &[arg_type.into()], + ), + Mode::IncN => crate::llvm::refcounting::build_header_help( + env, + &fn_name, + env.context.void_type().into(), + &[arg_type.into(), env.ptr_int().into()], + ), + }; let kind_id = Attribute::get_named_enum_kind_id("alwaysinline"); debug_assert!(kind_id > 0); @@ -287,10 +304,15 @@ pub fn build_rc_wrapper<'a, 'ctx, 'env>( match rc_operation { Mode::Inc => { - // we hardcode the 1 here let n = 1; increment_refcount_layout(env, function_value, layout_ids, n, value, layout); } + Mode::IncN => { + let n = it.next().unwrap().into_int_value(); + set_name(n.into(), Symbol::ARG_2.ident_string(&env.interns)); + + increment_n_refcount_layout(env, function_value, layout_ids, n, value, layout); + } Mode::Dec => { decrement_refcount_layout(env, function_value, layout_ids, value, layout); } diff --git a/compiler/gen/src/llvm/refcounting.rs b/compiler/gen/src/llvm/refcounting.rs index 2cf26f6934..a03398322e 100644 --- a/compiler/gen/src/llvm/refcounting.rs +++ b/compiler/gen/src/llvm/refcounting.rs @@ -426,6 +426,17 @@ pub fn increment_refcount_layout<'a, 'ctx, 'env>( layout: &Layout<'a>, ) { let amount = env.ptr_int().const_int(inc_amount, false); + increment_n_refcount_layout(env, parent, layout_ids, amount, value, layout); +} + +pub fn increment_n_refcount_layout<'a, 'ctx, 'env>( + env: &Env<'a, 'ctx, 'env>, + parent: FunctionValue<'ctx>, + layout_ids: &mut LayoutIds<'a>, + amount: IntValue<'ctx>, + value: BasicValueEnum<'ctx>, + layout: &Layout<'a>, +) { modify_refcount_layout( env, parent,