Skip to content

Commit 4422cdc

Browse files
committed
[OwnershipUtils] Match complex nested borrows.
Recognize lexical borrows as nested when their borrowee's guaranteed reference roots are all lexical borrows. Addresses the following regressions Breadcrumbs.MutatedUTF16ToIdx.Mixed 188 882 +369.1% **0.21x** Breadcrumbs.MutatedIdxToUTF16.Mixed 230 926 +302.6% **0.25x** seen when enabling lexical lifetimes in the standard library.
1 parent 469c3ec commit 4422cdc

File tree

1 file changed

+17
-8
lines changed

1 file changed

+17
-8
lines changed

lib/SIL/Utils/OwnershipUtils.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2409,16 +2409,25 @@ void swift::visitTransitiveEndBorrows(
24092409
///
24102410
/// A begin_borrow [lexical] is nested if the borrowed value's lifetime is
24112411
/// guaranteed by another lexical scope. That happens if:
2412-
/// - the value is a guaranteed argument to the function
2413-
/// - the value is itself a begin_borrow [lexical]
2412+
/// - the non-guaranteed borrowee's value is lexical
2413+
/// - the guaranteed borrowee's value's reference roots are lexical
2414+
/// - for example, the borrowee is itself a begin_borrow [lexical]
24142415
bool swift::isNestedLexicalBeginBorrow(BeginBorrowInst *bbi) {
24152416
assert(bbi->isLexical());
24162417
auto value = bbi->getOperand();
2417-
if (auto *outerBBI = dyn_cast<BeginBorrowInst>(value)) {
2418-
return outerBBI->isLexical();
2418+
if (value->getOwnershipKind() != OwnershipKind::Guaranteed) {
2419+
return value->isLexical();
24192420
}
2420-
if (auto *arg = dyn_cast<SILFunctionArgument>(value)) {
2421-
return arg->getOwnershipKind() == OwnershipKind::Guaranteed;
2422-
}
2423-
return false;
2421+
SmallVector<SILValue, 8> roots;
2422+
findGuaranteedReferenceRoots(value, /*lookThroughNestedBorrows=*/false,
2423+
roots);
2424+
return llvm::all_of(roots, [](auto root) {
2425+
if (auto *outerBBI = dyn_cast<BeginBorrowInst>(root)) {
2426+
return outerBBI->isLexical();
2427+
}
2428+
if (auto *arg = dyn_cast<SILFunctionArgument>(root)) {
2429+
return arg->getOwnershipKind() == OwnershipKind::Guaranteed;
2430+
}
2431+
return false;
2432+
});
24242433
}

0 commit comments

Comments
 (0)