diff --git a/compiler/gen/src/llvm/bitcode.rs b/compiler/gen/src/llvm/bitcode.rs index 5c4d266194..12374acf8f 100644 --- a/compiler/gen/src/llvm/bitcode.rs +++ b/compiler/gen/src/llvm/bitcode.rs @@ -453,7 +453,7 @@ pub fn build_rc_wrapper<'a, 'ctx, 'env>( match rc_operation { Mode::Inc => { // we hardcode the 1 here - let n = 1; + let n = env.ptr_int().const_int(1, false); increment_refcount_layout(env, function_value, layout_ids, n, value, layout); } Mode::Dec => { diff --git a/compiler/gen/src/llvm/build.rs b/compiler/gen/src/llvm/build.rs index 7dd9a2d1cb..90d47d06a9 100644 --- a/compiler/gen/src/llvm/build.rs +++ b/compiler/gen/src/llvm/build.rs @@ -2263,14 +2263,22 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>( let layout = *layout; if layout.contains_refcounted() { - increment_refcount_layout( - env, - parent, - layout_ids, - *inc_amount, - value, - &layout, - ); + let amount = env.ptr_int().const_int(*inc_amount, false); + increment_refcount_layout(env, parent, layout_ids, amount, value, &layout); + } + + build_exp_stmt(env, layout_ids, scope, parent, cont) + } + IncUnknown { + to_increment, + amount: amount_symbol, + } => { + let (value, layout) = load_symbol_and_layout(scope, to_increment); + let layout = *layout; + + if layout.contains_refcounted() { + let amount = load_symbol(scope, amount_symbol).into_int_value(); + increment_refcount_layout(env, parent, layout_ids, amount, value, &layout); } build_exp_stmt(env, layout_ids, scope, parent, cont) diff --git a/compiler/gen/src/llvm/build_list.rs b/compiler/gen/src/llvm/build_list.rs index fd4eb110be..99ad333be8 100644 --- a/compiler/gen/src/llvm/build_list.rs +++ b/compiler/gen/src/llvm/build_list.rs @@ -289,7 +289,8 @@ pub fn list_get_unsafe<'a, 'ctx, 'env>( let result = builder.build_load(elem_ptr, "List.get"); - increment_refcount_layout(env, parent, layout_ids, 1, result, elem_layout); + let n = env.ptr_int().const_int(1, false); + increment_refcount_layout(env, parent, layout_ids, n, result, elem_layout); result } diff --git a/compiler/gen/src/llvm/refcounting.rs b/compiler/gen/src/llvm/refcounting.rs index 7af7a0fe8f..a0bb3d0cd5 100644 --- a/compiler/gen/src/llvm/refcounting.rs +++ b/compiler/gen/src/llvm/refcounting.rs @@ -423,16 +423,15 @@ pub fn increment_refcount_layout<'a, 'ctx, 'env>( env: &Env<'a, 'ctx, 'env>, parent: FunctionValue<'ctx>, layout_ids: &mut LayoutIds<'a>, - inc_amount: u64, + inc_amount: IntValue<'ctx>, value: BasicValueEnum<'ctx>, layout: &Layout<'a>, ) { - let amount = env.ptr_int().const_int(inc_amount, false); modify_refcount_layout( env, parent, layout_ids, - CallMode::Inc(amount), + CallMode::Inc(inc_amount), value, layout, ); diff --git a/compiler/mono/src/expand_rc.rs b/compiler/mono/src/expand_rc.rs index c329a503b5..557c41a312 100644 --- a/compiler/mono/src/expand_rc.rs +++ b/compiler/mono/src/expand_rc.rs @@ -575,6 +575,17 @@ fn expand_and_cancel<'a>(env: &mut Env<'a, '_>, stmt: &'a Stmt<'a>) -> &'a Stmt< expand_and_cancel(env, cont) } + Refcounting( + ModifyRc::IncUnknown { + to_increment: _, + amount: _, + }, + cont, + ) => { + // TODO + expand_and_cancel(env, cont) + } + Refcounting(ModifyRc::Inc(symbol, inc_amount), cont) => { let count = env.deferred.inc_dec_map.entry(*symbol).or_insert(0); *count += *inc_amount as i64; diff --git a/compiler/mono/src/inc_dec.rs b/compiler/mono/src/inc_dec.rs index fe70d8e26b..c1df450e84 100644 --- a/compiler/mono/src/inc_dec.rs +++ b/compiler/mono/src/inc_dec.rs @@ -468,7 +468,16 @@ impl<'a> Context<'a> { arguments, }); - &*self.arena.alloc(Stmt::Let(z, v, l, b)) + let mut b = Stmt::Let(z, v, l, b); + + if !ps[1].borrow { + b = Stmt::Refcounting( + ModifyRc::Inc(arguments[2], 2), + self.arena.alloc(b), + ) + } + + &*self.arena.alloc(b) } None => unreachable!(), } diff --git a/compiler/mono/src/ir.rs b/compiler/mono/src/ir.rs index 5cd3c6925a..7c8f62980a 100644 --- a/compiler/mono/src/ir.rs +++ b/compiler/mono/src/ir.rs @@ -902,6 +902,10 @@ impl<'a> BranchInfo<'a> { #[derive(Clone, Copy, Debug, PartialEq)] pub enum ModifyRc { Inc(Symbol, u64), + IncUnknown { + to_increment: Symbol, + amount: Symbol, + }, Dec(Symbol), DecRef(Symbol), } @@ -925,6 +929,15 @@ impl ModifyRc { .append(alloc.text(format!("{}", n))) .append(symbol_to_doc(alloc, *symbol)) .append(";"), + IncUnknown { + to_increment, + amount, + } => alloc + .text("inc ") + .append(symbol_to_doc(alloc, *to_increment)) + .append(" by ") + .append(symbol_to_doc(alloc, *amount)) + .append(";"), Dec(symbol) => alloc .text("dec ") .append(symbol_to_doc(alloc, *symbol)) @@ -941,6 +954,7 @@ impl ModifyRc { match self { Inc(symbol, _) => *symbol, + IncUnknown { to_increment, .. } => *to_increment, Dec(symbol) => *symbol, DecRef(symbol) => *symbol, }