1414// /
1515// / Contains optimizations that eliminate redundant copy values.
1616// /
17+ // / FIXME: CanonicalizeOSSALifetime likely replaces everything this file.
18+ // /
1719// ===----------------------------------------------------------------------===//
1820
21+ #define DEBUG_TYPE " sil-semantic-arc-opts"
22+
1923#include " OwnershipPhiOperand.h"
2024#include " SemanticARCOptVisitor.h"
2125#include " swift/SIL/LinearLifetimeChecker.h"
@@ -61,6 +65,8 @@ using namespace swift::semanticarc;
6165// are within the borrow scope.
6266//
6367// TODO: This needs a better name.
68+ //
69+ // FIXME: CanonicalizeOSSALifetime replaces this once it supports borrows.
6470bool SemanticARCOptVisitor::performGuaranteedCopyValueOptimization (
6571 CopyValueInst *cvi) {
6672 // For now, do not run this optimization. This is just to be careful.
@@ -236,6 +242,7 @@ bool SemanticARCOptVisitor::performGuaranteedCopyValueOptimization(
236242
237243 // Otherwise, our copy must truly not be needed, o RAUW and convert to
238244 // guaranteed!
245+ LLVM_DEBUG (llvm::dbgs () << " Replace copy with guaranteed source: " << *cvi);
239246 std::move (lr).convertToGuaranteedAndRAUW (cvi->getOperand (), getCallbacks ());
240247 return true ;
241248}
@@ -246,13 +253,16 @@ bool SemanticARCOptVisitor::performGuaranteedCopyValueOptimization(
246253
247254// / If cvi only has destroy value users, then cvi is a dead live range. Lets
248255// / eliminate all such dead live ranges.
256+ // /
257+ // / FIXME: CanonicalizeOSSALifetime replaces this.
249258bool SemanticARCOptVisitor::eliminateDeadLiveRangeCopyValue (
250259 CopyValueInst *cvi) {
251260 // This is a cheap optimization generally.
252261
253262 // See if we are lucky and have a simple case.
254263 if (auto *op = cvi->getSingleUse ()) {
255264 if (auto *dvi = dyn_cast<DestroyValueInst>(op->getUser ())) {
265+ LLVM_DEBUG (llvm::dbgs () << " Erasing single-use copy: " << *cvi);
256266 eraseInstruction (dvi);
257267 eraseInstructionAndAddOperandsToWorklist (cvi);
258268 return true ;
@@ -276,6 +286,7 @@ bool SemanticARCOptVisitor::eliminateDeadLiveRangeCopyValue(
276286 }
277287
278288 // Now that we have a truly dead live range copy value, eliminate it!
289+ LLVM_DEBUG (llvm::dbgs () << " Eliminate dead copy: " << *cvi);
279290 while (!destroys.empty ()) {
280291 eraseInstruction (destroys.pop_back_val ());
281292 }
@@ -366,6 +377,8 @@ static bool tryJoinIfDestroyConsumingUseInSameBlock(
366377 SmallPtrSet<SILInstruction *, 8 > visitedInsts;
367378 if (!isUseBetweenInstAndBlockEnd (singleCVIConsumingUse->getUser (),
368379 &dvi->getAllOperands ()[0 ], &visitedInsts)) {
380+ LLVM_DEBUG (llvm::dbgs ()
381+ << " Eliminate copy with useless lifetime: " << *cvi);
369382 ctx.eraseInstruction (dvi);
370383 ctx.eraseAndRAUWSingleValueInstruction (cvi, operand);
371384 return true ;
@@ -474,6 +487,8 @@ static bool tryJoinIfDestroyConsumingUseInSameBlock(
474487 }
475488
476489 // Ok, we now know that we can eliminate this value.
490+ LLVM_DEBUG (llvm::dbgs ()
491+ << " Eliminate borrowed copy with useless lifetime: " << *cvi);
477492 ctx.eraseInstruction (dvi);
478493 ctx.eraseAndRAUWSingleValueInstruction (cvi, operand);
479494 return true ;
@@ -532,6 +547,7 @@ static bool tryJoiningIfCopyOperandHasSingleDestroyValue(
532547 // post-dominate destroy_value and can eliminate the hand off traffic.
533548 if (canJoinIfCopyDiesInFunctionExitingBlock (operand, dvi, cvi,
534549 singleCVIConsumingUse)) {
550+ LLVM_DEBUG (llvm::dbgs () << " Eliminate returned copy: " << *cvi);
535551 ctx.eraseInstruction (dvi);
536552 ctx.eraseAndRAUWSingleValueInstruction (cvi, operand);
537553 return true ;
@@ -602,6 +618,8 @@ static bool tryJoiningIfCopyOperandHasSingleDestroyValue(
602618// interior pointers (e.x. project_box) are properly guarded by
603619// begin_borrow. Because of that we can not shrink lifetimes and instead rely on
604620// SILGen's correctness.
621+ //
622+ // FIXME: CanonicalizeOSSALifetime replaces this.
605623bool SemanticARCOptVisitor::tryJoiningCopyValueLiveRangeWithOperand (
606624 CopyValueInst *cvi) {
607625 // First do a quick check if our operand is owned. If it is not owned, we can
@@ -659,6 +677,8 @@ bool SemanticARCOptVisitor::tryJoiningCopyValueLiveRangeWithOperand(
659677 // can optimize without any further analysis since we know we will not be
660678 // shrinking lifetimes of owned values.
661679 if (singleCVIConsumingUse == nullptr ) {
680+ LLVM_DEBUG (llvm::dbgs ()
681+ << " Eliminate multiply consumed live-out copy: " << *cvi);
662682 eraseInstruction (dvi);
663683 eraseAndRAUWSingleValueInstruction (cvi, operand);
664684 return true ;
@@ -668,6 +688,7 @@ bool SemanticARCOptVisitor::tryJoiningCopyValueLiveRangeWithOperand(
668688 // is not in the same block as our copy_value/destroy_value, it must be live
669689 // out of the block and thus we are not shrinking any lifetimes.
670690 if (singleCVIConsumingUse->getParentBlock () != cvi->getParent ()) {
691+ LLVM_DEBUG (llvm::dbgs () << " Eliminate non-local live-out copy: " << *cvi);
671692 eraseInstruction (dvi);
672693 eraseAndRAUWSingleValueInstruction (cvi, operand);
673694 return true ;
@@ -702,6 +723,8 @@ bool SemanticARCOptVisitor::tryJoiningCopyValueLiveRangeWithOperand(
702723
703724// / Given an owned value that is completely enclosed within its parent owned
704725// / value and is not consumed, eliminate the copy.
726+ // /
727+ // / FIXME: CanonicalizeOSSALifetime replaces this.
705728bool SemanticARCOptVisitor::tryPerformOwnedCopyValueOptimization (
706729 CopyValueInst *cvi) {
707730 if (ctx.onlyGuaranteedOpts )
0 commit comments