Skip to content

Commit d3cd72f

Browse files
authored
Merge pull request #71231 from jckarter/borrowing-switch-2
SILGen: Separate borrow from consume phase for destructive pattern matches.
2 parents 93b7f2c + c4bdc97 commit d3cd72f

File tree

4 files changed

+457
-25
lines changed

4 files changed

+457
-25
lines changed

lib/SILGen/Cleanup.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,14 @@ void CleanupManager::endScope(CleanupsDepth depth, CleanupLocation loc) {
142142
emitCleanups(depth, loc, NotForUnwind, /*popCleanups*/ true);
143143
}
144144

145+
/// Leave a scope, emitting all the cleanups that are currently active but leaving them on the stack so they
146+
/// can be reenabled on other pattern match branches.
147+
void CleanupManager::endNoncopyablePatternMatchBorrow(CleanupsDepth depth,
148+
CleanupLocation loc,
149+
bool popCleanups) {
150+
emitCleanups(depth, loc, NotForUnwind, popCleanups);
151+
}
152+
145153
bool CleanupManager::hasAnyActiveCleanups(CleanupsDepth from,
146154
CleanupsDepth to) {
147155
return ::hasAnyActiveCleanups(stack.find(from), stack.find(to));

lib/SILGen/Cleanup.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ typedef DiverseStackImpl<Cleanup>::stable_iterator CleanupHandle;
159159
class LLVM_LIBRARY_VISIBILITY CleanupManager {
160160
friend class Scope;
161161
friend class CleanupCloner;
162-
162+
163163
SILGenFunction &SGF;
164164

165165
/// Stack - Currently active cleanups in this scope tree.
@@ -289,6 +289,9 @@ class LLVM_LIBRARY_VISIBILITY CleanupManager {
289289
/// Verify that the given cleanup handle is valid.
290290
void checkIterator(CleanupHandle handle) const;
291291

292+
void endNoncopyablePatternMatchBorrow(CleanupsDepth depth, CleanupLocation l,
293+
bool finalEndBorrow = false);
294+
292295
private:
293296
// Look up the flags and optionally the writeback address associated with the
294297
// cleanup at \p depth. If

lib/SILGen/ManagedValue.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,9 @@ class ConsumableManagedValue {
520520

521521
/// Return a managed value that's appropriate for borrowing this
522522
/// value and promising not to consume it.
523+
///
524+
/// TODO: Should be superseded by `asBorrowedOperand2` once existing code is
525+
/// updated to tolerate address-only values being borrowed.
523526
ConsumableManagedValue asBorrowedOperand(SILGenFunction &SGF,
524527
SILLocation loc) const {
525528
if (getType().isAddress())
@@ -532,6 +535,18 @@ class ConsumableManagedValue {
532535
CastConsumptionKind::BorrowAlways};
533536
}
534537

538+
ConsumableManagedValue asBorrowedOperand2(SILGenFunction &SGF,
539+
SILLocation loc) const {
540+
if (getType().isAddress())
541+
return {asUnmanagedOwnedValue(), CastConsumptionKind::BorrowAlways};
542+
543+
if (Value.getOwnershipKind() == OwnershipKind::Guaranteed)
544+
return {Value, CastConsumptionKind::BorrowAlways};
545+
546+
return {asUnmanagedOwnedValue().borrow(SGF, loc),
547+
CastConsumptionKind::BorrowAlways};
548+
}
549+
535550
/// Return a managed value that's appropriate for copying this value and
536551
/// always consuming it.
537552
ConsumableManagedValue copy(SILGenFunction &SGF, SILLocation loc) const {

0 commit comments

Comments
 (0)