use borrow borrow signature

This commit is contained in:
J.Teeuwissen 2023-04-06 10:38:51 +02:00
parent c44da622e5
commit d806ddd190
No known key found for this signature in database
GPG key ID: DB5F7A1ED8D478AD
2 changed files with 12 additions and 124 deletions

View file

@ -12,9 +12,6 @@ use roc_collections::ReferenceMatrix;
use roc_module::low_level::LowLevel;
use roc_module::symbol::Symbol;
pub(crate) const OWNED: bool = false;
pub(crate) const BORROWED: bool = true;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Ownership {
Owned,
@ -471,11 +468,11 @@ impl<'a> BorrowInfState<'a> {
/// This looks at an application `f x1 x2 x3`
/// If the parameter (based on the definition of `f`) is owned,
/// then the argument must also be owned
fn own_args_using_bools(&mut self, xs: &[Symbol], ps: &[bool]) {
fn own_args_using_bools(&mut self, xs: &[Symbol], ps: &[Ownership]) {
debug_assert_eq!(xs.len(), ps.len());
for (x, borrow) in xs.iter().zip(ps.iter()) {
if !borrow {
for (x, ownership) in xs.iter().zip(ps.iter()) {
if matches!(ownership, Ownership::Owned) {
self.own_var(*x);
}
}
@ -926,22 +923,22 @@ impl<'a> BorrowInfState<'a> {
}
}
pub fn foreign_borrow_signature(arena: &Bump, arity: usize) -> &[bool] {
pub fn foreign_borrow_signature(arena: &Bump, arity: usize) -> &[Ownership] {
// NOTE this means that Roc is responsible for cleaning up resources;
// the host cannot (currently) take ownership
let all = bumpalo::vec![in arena; BORROWED; arity];
let all = bumpalo::vec![in arena; Ownership::Borrowed; arity];
all.into_bump_slice()
}
pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] {
pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[Ownership] {
use LowLevel::*;
// TODO is true or false more efficient for non-refcounted layouts?
let irrelevant = OWNED;
let irrelevant = Ownership::Owned;
let function = irrelevant;
let closure_data = irrelevant;
let owned = OWNED;
let borrowed = BORROWED;
let owned = Ownership::Owned;
let borrowed = Ownership::Borrowed;
// Here we define the borrow signature of low-level operations
//

View file

@ -7,10 +7,10 @@ use std::{collections::HashMap, hash::BuildHasherDefault, iter};
use bumpalo::collections::Vec;
use bumpalo::Bump;
use roc_collections::{all::WyHash, MutMap, MutSet};
use roc_module::{low_level::LowLevel, symbol::Symbol};
use roc_module::symbol::Symbol;
use crate::{
borrow::Ownership,
borrow::{lowlevel_borrow_signature, Ownership},
ir::{
BranchInfo, Call, CallType, Expr, HigherOrderLowLevel, JoinPointId, ListLiteralElement,
ModifyRc, Param, Proc, ProcLayout, Stmt,
@ -914,7 +914,7 @@ fn insert_refcount_operations_binding<'a>(
op: operator,
update_mode: _,
} => {
let borrow_signature = lowlevel_borrow_signature(arena, operator);
let borrow_signature = lowlevel_borrow_signature(arena, *operator);
let arguments_with_borrow_signature = arguments
.iter()
.copied()
@ -1199,112 +1199,3 @@ fn insert_dec_stmt<'a, 's>(
) -> &'a Stmt<'a> {
arena.alloc(Stmt::Refcounting(ModifyRc::Dec(symbol), continuation))
}
/**
Taken from the original inc_dec borrow implementation.
*/
fn lowlevel_borrow_signature<'a>(arena: &'a Bump, op: &LowLevel) -> &'a [Ownership] {
use LowLevel::*;
let irrelevant = Ownership::Owned;
let function = irrelevant;
let closure_data = irrelevant;
let owned = Ownership::Owned;
let borrowed = Ownership::Borrowed;
// Here we define the borrow signature of low-level operations
//
// - arguments with non-refcounted layouts (ints, floats) are `irrelevant`
// - arguments that we may want to update destructively must be Owned
// - other refcounted arguments are Borrowed
match op {
Unreachable => arena.alloc_slice_copy(&[irrelevant]),
ListLen | StrIsEmpty | StrToScalars | StrCountGraphemes | StrGraphemes
| StrCountUtf8Bytes | StrGetCapacity | ListGetCapacity => {
arena.alloc_slice_copy(&[borrowed])
}
ListWithCapacity | StrWithCapacity => arena.alloc_slice_copy(&[irrelevant]),
ListReplaceUnsafe => arena.alloc_slice_copy(&[owned, irrelevant, irrelevant]),
StrGetUnsafe | ListGetUnsafe => arena.alloc_slice_copy(&[borrowed, irrelevant]),
ListConcat => arena.alloc_slice_copy(&[owned, owned]),
StrConcat => arena.alloc_slice_copy(&[owned, borrowed]),
StrSubstringUnsafe => arena.alloc_slice_copy(&[borrowed, irrelevant, irrelevant]),
StrReserve => arena.alloc_slice_copy(&[owned, irrelevant]),
StrAppendScalar => arena.alloc_slice_copy(&[owned, irrelevant]),
StrGetScalarUnsafe => arena.alloc_slice_copy(&[borrowed, irrelevant]),
StrTrim => arena.alloc_slice_copy(&[owned]),
StrTrimLeft => arena.alloc_slice_copy(&[owned]),
StrTrimRight => arena.alloc_slice_copy(&[owned]),
StrSplit => arena.alloc_slice_copy(&[borrowed, borrowed]),
StrToNum => arena.alloc_slice_copy(&[borrowed]),
ListPrepend => arena.alloc_slice_copy(&[owned, owned]),
StrJoinWith => arena.alloc_slice_copy(&[borrowed, borrowed]),
ListMap => arena.alloc_slice_copy(&[owned, function, closure_data]),
ListMap2 => arena.alloc_slice_copy(&[owned, owned, function, closure_data]),
ListMap3 => arena.alloc_slice_copy(&[owned, owned, owned, function, closure_data]),
ListMap4 => arena.alloc_slice_copy(&[owned, owned, owned, owned, function, closure_data]),
ListSortWith => arena.alloc_slice_copy(&[owned, function, closure_data]),
ListAppendUnsafe => arena.alloc_slice_copy(&[owned, owned]),
ListReserve => arena.alloc_slice_copy(&[owned, irrelevant]),
ListSublist => arena.alloc_slice_copy(&[owned, irrelevant, irrelevant]),
ListDropAt => arena.alloc_slice_copy(&[owned, irrelevant]),
ListSwap => arena.alloc_slice_copy(&[owned, irrelevant, irrelevant]),
ListReleaseExcessCapacity => arena.alloc_slice_copy(&[owned]),
StrReleaseExcessCapacity => arena.alloc_slice_copy(&[owned]),
Eq | NotEq => arena.alloc_slice_copy(&[borrowed, borrowed]),
And | Or | NumAdd | NumAddWrap | NumAddChecked | NumAddSaturated | NumSub | NumSubWrap
| NumSubChecked | NumSubSaturated | NumMul | NumMulWrap | NumMulSaturated
| NumMulChecked | NumGt | NumGte | NumLt | NumLte | NumCompare | NumDivFrac
| NumDivTruncUnchecked | NumDivCeilUnchecked | NumRemUnchecked | NumIsMultipleOf
| NumPow | NumPowInt | NumBitwiseAnd | NumBitwiseXor | NumBitwiseOr | NumShiftLeftBy
| NumShiftRightBy | NumShiftRightZfBy => arena.alloc_slice_copy(&[irrelevant, irrelevant]),
NumToStr
| NumAbs
| NumNeg
| NumSin
| NumCos
| NumSqrtUnchecked
| NumLogUnchecked
| NumRound
| NumCeiling
| NumFloor
| NumToFrac
| Not
| NumIsFinite
| NumAtan
| NumAcos
| NumAsin
| NumIntCast
| NumToIntChecked
| NumToFloatCast
| NumToFloatChecked
| NumCountLeadingZeroBits
| NumCountTrailingZeroBits
| NumCountOneBits => arena.alloc_slice_copy(&[irrelevant]),
NumBytesToU16 => arena.alloc_slice_copy(&[borrowed, irrelevant]),
NumBytesToU32 => arena.alloc_slice_copy(&[borrowed, irrelevant]),
NumBytesToU64 => arena.alloc_slice_copy(&[borrowed, irrelevant]),
NumBytesToU128 => arena.alloc_slice_copy(&[borrowed, irrelevant]),
StrStartsWith | StrEndsWith => arena.alloc_slice_copy(&[borrowed, borrowed]),
StrStartsWithScalar => arena.alloc_slice_copy(&[borrowed, irrelevant]),
StrFromUtf8Range => arena.alloc_slice_copy(&[owned, irrelevant, irrelevant]),
StrToUtf8 => arena.alloc_slice_copy(&[owned]),
StrRepeat => arena.alloc_slice_copy(&[borrowed, irrelevant]),
StrFromInt | StrFromFloat => arena.alloc_slice_copy(&[irrelevant]),
Hash => arena.alloc_slice_copy(&[borrowed, irrelevant]),
ListIsUnique => arena.alloc_slice_copy(&[borrowed]),
BoxExpr | UnboxExpr => {
unreachable!("These lowlevel operations are turned into mono Expr's")
}
PtrCast | RefCountInc | RefCountDec => {
unreachable!("Only inserted *after* borrow checking: {:?}", op);
}
}
}