Skip to content

Commit 0011b07

Browse files
Merge pull request #41387 from nate-chandler/lexical_lifetimes/destroy_hoisting/add
Hoist destroys of owned lexical values.
2 parents feaab31 + 62dc05f commit 0011b07

14 files changed

+900
-70
lines changed

include/swift/SILOptimizer/Utils/CanonicalizeBorrowScope.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,13 @@ bool shrinkBorrowScope(
151151
BeginBorrowInst const &bbi, InstructionDeleter &deleter,
152152
SmallVectorImpl<CopyValueInst *> &modifiedCopyValueInsts);
153153

154-
bool foldDestroysOfCopiedLexicalBorrow(BeginBorrowInst *bbi,
155-
DominanceInfo &dominanceTree,
156-
InstructionDeleter &deleter);
154+
MoveValueInst *foldDestroysOfCopiedLexicalBorrow(BeginBorrowInst *bbi,
155+
DominanceInfo &dominanceTree,
156+
InstructionDeleter &deleter);
157+
158+
bool hoistDestroysOfOwnedLexicalValue(SILValue const value,
159+
SILFunction &function,
160+
InstructionDeleter &deleter);
157161

158162
} // namespace swift
159163

lib/SIL/Utils/OwnershipUtils.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ bool swift::findUsesOfSimpleValue(SILValue value,
318318
if (end->getOperandOwnership() == OperandOwnership::Reborrow) {
319319
return false;
320320
}
321-
usePoints->push_back(use);
321+
usePoints->push_back(end);
322322
return true;
323323
})) {
324324
return false;

lib/SILOptimizer/Transforms/CopyPropagation.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -471,11 +471,17 @@ void CopyPropagation::run() {
471471
auto folded = foldDestroysOfCopiedLexicalBorrow(bbi, *domTree, deleter);
472472
if (!folded)
473473
break;
474-
// We don't add the produced move_value instruction to the worklist
475-
// because it can't handle propagation.
474+
auto hoisted = hoistDestroysOfOwnedLexicalValue(folded, *f, deleter);
475+
// Keep running even if the new move's destroys can't be hoisted.
476+
(void)hoisted;
476477
firstRun = false;
477478
}
478479
}
480+
for (auto *argument : f->getArguments()) {
481+
if (argument->getOwnershipKind() == OwnershipKind::Owned) {
482+
hoistDestroysOfOwnedLexicalValue(argument, *f, deleter);
483+
}
484+
}
479485
deleter.cleanupDeadInstructions();
480486

481487
// For now, only modify forwarding instructions

lib/SILOptimizer/Utils/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ target_sources(swiftSILOptimizer PRIVATE
1919
InstOptUtils.cpp
2020
KeyPathProjector.cpp
2121
LexicalDestroyFolding.cpp
22+
LexicalDestroyHoisting.cpp
2223
LoadStoreOptUtils.cpp
2324
LoopUtils.cpp
2425
OptimizerStatsUtils.cpp

lib/SILOptimizer/Utils/LexicalDestroyFolding.cpp

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ struct Context final {
140140
};
141141

142142
/// Fold within the specified context.
143-
bool run(Context &);
143+
MoveValueInst *run(Context &);
144144

145145
/// The consuming use pattern we are trying to match and transform.
146146
struct Match final {
@@ -358,6 +358,11 @@ class Rewriter final {
358358
Context &context;
359359
Candidates const &candidates;
360360

361+
// The move_value [lexical] instruction that was added during the run.
362+
//
363+
// Defined during createMove.
364+
MoveValueInst *mvi = nullptr;
365+
361366
public:
362367
Rewriter(Context &context, Candidates const &candidates)
363368
: context(context), candidates(candidates){};
@@ -379,7 +384,7 @@ class Rewriter final {
379384
/// ...
380385
/// - update SSA now that a second def has been introduced for
381386
/// %borrowee
382-
void run();
387+
MoveValueInst *run();
383388

384389
private:
385390
/// Add the new move_value [lexical] above the begin_borrow [lexical].
@@ -407,11 +412,6 @@ class Rewriter final {
407412
/// (2) hoist the end_borrow
408413
/// (3) delete the destroy_value
409414
void fold(Match, ArrayRef<int> rewritableArgumentIndices);
410-
411-
// The move_value [lexical] instruction that was added during the run.
412-
//
413-
// Defined during createMove.
414-
MoveValueInst *mvi = nullptr;
415415
};
416416

417417
//===----------------------------------------------------------------------===//
@@ -421,45 +421,43 @@ class Rewriter final {
421421
/// Perform any possible folding.
422422
///
423423
/// Returns whether any change was made.
424-
bool run(Context &context) {
424+
MoveValueInst *run(Context &context) {
425425
Candidates candidates;
426426

427427
// Do a cheap search for scope ending instructions that could potentially be
428428
// candidates for folding.
429429
if (!FindCandidates(context).run(candidates))
430-
return false;
430+
return nullptr;
431431

432432
// At least one full match was found and more expensive checks on the matches
433433
// are in order.
434434

435435
BorroweeUsage borroweeUsage;
436436
if (!findBorroweeUsage(context, borroweeUsage))
437-
return false;
437+
return nullptr;
438438
IntroducerUsage introducerUsage;
439439
if (!findIntroducerUsage(context, introducerUsage))
440-
return false;
440+
return nullptr;
441441

442442
// Now, filter the candidates using those values.
443443
if (!FilterCandidates(context, introducerUsage, borroweeUsage)
444444
.run(candidates))
445-
return false;
445+
return nullptr;
446446

447447
// Finally, check that %borrowee has no uses within %lifetime's
448448
// borrow scope.
449449
if (borroweeHasUsesWithinBorrowScope(context, borroweeUsage))
450-
return false;
450+
return nullptr;
451451

452452
// It is safe to rewrite the viable candidates. Do so.
453-
Rewriter(context, candidates).run();
454-
455-
return true;
453+
return Rewriter(context, candidates).run();
456454
}
457455

458456
//===----------------------------------------------------------------------===//
459457
// MARK: Rewriting
460458
//===----------------------------------------------------------------------===//
461459

462-
void Rewriter::run() {
460+
MoveValueInst *Rewriter::run() {
463461
bool foldedAny = false;
464462
(void)foldedAny;
465463
auto size = candidates.vector.size();
@@ -487,6 +485,7 @@ void Rewriter::run() {
487485
#endif
488486
}
489487
assert(foldedAny && "rewriting without anything to rewrite!?");
488+
return mvi;
490489
}
491490

492491
bool Rewriter::createMove() {
@@ -779,15 +778,16 @@ bool FilterCandidates::rewritableArgumentIndicesForApply(
779778
//===----------------------------------------------------------------------===//
780779

781780
/// The entry point.
782-
bool swift::foldDestroysOfCopiedLexicalBorrow(BeginBorrowInst *bbi,
783-
DominanceInfo &dominanceTree,
784-
InstructionDeleter &deleter) {
781+
MoveValueInst *
782+
swift::foldDestroysOfCopiedLexicalBorrow(BeginBorrowInst *bbi,
783+
DominanceInfo &dominanceTree,
784+
InstructionDeleter &deleter) {
785785
if (!bbi->isLexical())
786-
return false;
786+
return nullptr;
787787
if (bbi->getOperand()->getOwnershipKind() != OwnershipKind::Owned)
788-
return false;
788+
return nullptr;
789789
if (!dominanceTree.isReachableFromEntry(bbi->getParentBlock()))
790-
return false;
790+
return nullptr;
791791

792792
auto context = LexicalDestroyFolding::Context(bbi, dominanceTree, deleter);
793793
return LexicalDestroyFolding::run(context);

0 commit comments

Comments
 (0)