@@ -94,20 +94,22 @@ SILValue CanonicalizeOSSALifetime::getCanonicalCopiedDef(SILValue v) {
9494// / The lifetime extends beyond given consuming use. Copy the value.
9595// /
9696// / This can set the operand value, but cannot invalidate the use iterator.
97- static void copyLiveUse (Operand *use) {
97+ static void copyLiveUse (Operand *use, InstModCallbacks &instModCallbacks ) {
9898 SILInstruction *user = use->getUser ();
99- SILBuilderWithScope B (user->getIterator ());
99+ SILBuilderWithScope builder (user->getIterator ());
100100
101101 auto loc = RegularLocation::getAutoGeneratedLocation (user->getLoc ());
102- auto *copy = B.createCopyValue (loc, use->get ());
103- use->set (copy);
102+ auto *copy = builder.createCopyValue (loc, use->get ());
103+ instModCallbacks.createdNewInst (copy);
104+ instModCallbacks.setUseValue (use, copy);
104105
105106 ++NumCopiesGenerated;
106107 LLVM_DEBUG (llvm::dbgs () << " Copying at last use " << *copy);
107108}
108109
109110// TODO: generalize this to handle multiple nondebug uses of the struct_extract.
110- SILValue swift::convertExtractToDestructure (StructExtractInst *extract) {
111+ SILValue swift::convertExtractToDestructure (StructExtractInst *extract,
112+ InstModCallbacks *callbacks) {
111113 if (!hasOneNonDebugUse (extract))
112114 return nullptr ;
113115
@@ -123,12 +125,20 @@ SILValue swift::convertExtractToDestructure(StructExtractInst *extract) {
123125 auto loc = extract->getLoc ();
124126 auto *copy = builder.createCopyValue (loc, extract->getOperand ());
125127 auto *destructure = builder.createDestructureStruct (loc, copy);
128+ if (callbacks) {
129+ callbacks->createdNewInst (copy);
130+ callbacks->createdNewInst (destructure);
131+ }
126132
127133 SILValue nonTrivialResult = destructure->getResult (extract->getFieldIndex ());
128134 assert (!nonTrivialResult->getType ().isTrivial (*destructure->getFunction ())
129135 && " field idx mismatch" );
130136
131- extractCopy->replaceAllUsesWith (nonTrivialResult);
137+ if (callbacks) {
138+ callbacks->replaceValueUsesWith (extractCopy, nonTrivialResult);
139+ } else {
140+ extractCopy->replaceAllUsesWith (nonTrivialResult);
141+ }
132142 return nonTrivialResult;
133143}
134144
@@ -176,11 +186,13 @@ bool CanonicalizeOSSALifetime::computeBorrowLiveness() {
176186// To use an existing outer copy, we could find its earliest consume. But the
177187// new copy will immediately canonicalized and a canonical begin_borrow scope
178188// have no outer uses of its first block.
179- static CopyValueInst *createOuterCopy (BeginBorrowInst *beginBorrow) {
180- SILBuilderWithScope B (beginBorrow);
189+ static CopyValueInst *createOuterCopy (BeginBorrowInst *beginBorrow,
190+ InstModCallbacks &instModCallbacks) {
191+ SILBuilderWithScope builder (beginBorrow);
181192
182193 auto loc = RegularLocation::getAutoGeneratedLocation (beginBorrow->getLoc ());
183- auto *copy = B.createCopyValue (loc, beginBorrow->getOperand ());
194+ auto *copy = builder.createCopyValue (loc, beginBorrow->getOperand ());
195+ instModCallbacks.createdNewInst (copy);
184196
185197 ++NumCopiesGenerated;
186198 LLVM_DEBUG (llvm::dbgs () << " Outer copy " << *copy);
@@ -346,7 +358,7 @@ void CanonicalizeOSSALifetime::rewriteOuterBorrowUsesAndFindConsumes(
346358
347359 auto rewriteOuterUse = [&](Operand *use) {
348360 LLVM_DEBUG (llvm::dbgs () << " Use of outer copy " << *use->getUser ());
349- use-> set ( newIncomingValue);
361+ instModCallbacks. setUseValue (use, newIncomingValue);
350362 currentOuterUseInsts.push_back (use->getUser ());
351363 outerUseInsts.insert (incomingValue->getDefiningInstruction ());
352364 if (use->isLifetimeEnding ()) {
@@ -444,18 +456,19 @@ void CanonicalizeOSSALifetime::rewriteOuterBorrowUsesAndFindConsumes(
444456 for (auto *boundaryEdge : boundary.boundaryEdges ) {
445457 if (DeadEndBlocks::triviallyEndsInUnreachable (boundaryEdge))
446458 continue ;
447-
448459 auto insertPt = boundaryEdge->begin ();
449- auto loc = insertPt->getLoc ();
450- SILBuilderWithScope (insertPt).createDestroyValue (loc, newIncomingValue);
460+ auto *dvi = SILBuilderWithScope (insertPt).createDestroyValue (
461+ insertPt->getLoc (), newIncomingValue);
462+ instModCallbacks.createdNewInst (dvi);
451463 }
452464
453465 for (SILInstruction *lastUser : boundary.lastUsers ) {
454466 if (unclaimedConsumingUsers.erase (lastUser))
455467 continue ;
456468
457469 SILBuilderWithScope::insertAfter (lastUser, [&](SILBuilder &b) {
458- b.createDestroyValue (lastUser->getLoc (), newIncomingValue);
470+ auto *dvi = b.createDestroyValue (lastUser->getLoc (), newIncomingValue);
471+ instModCallbacks.createdNewInst (dvi);
459472 });
460473 }
461474 // Add copies for consuming users of newIncomingValue.
@@ -466,7 +479,7 @@ void CanonicalizeOSSALifetime::rewriteOuterBorrowUsesAndFindConsumes(
466479 // unclaimedConsumingUsers set after skipping the first copy.
467480 auto iterAndInserted = unclaimedConsumingUsers.insert (use->getUser ());
468481 if (!iterAndInserted.second ) {
469- copyLiveUse (use);
482+ copyLiveUse (use, instModCallbacks );
470483 }
471484 }
472485}
@@ -496,7 +509,8 @@ bool CanonicalizeOSSALifetime::consolidateBorrowScope() {
496509 if (outerUseInsts.empty ()) {
497510 return true ;
498511 }
499- this ->outerCopy = createOuterCopy (cast<BeginBorrowInst>(currentDef));
512+ this ->outerCopy =
513+ createOuterCopy (cast<BeginBorrowInst>(currentDef), instModCallbacks);
500514
501515 defUseWorklist.clear ();
502516 rewriteOuterBorrowUsesAndFindConsumes (currentDef, outerUseInsts);
@@ -761,6 +775,7 @@ void CanonicalizeOSSALifetime::insertDestroyOnCFGEdge(
761775 SILBuilderWithScope builder (pos);
762776 auto loc = RegularLocation::getAutoGeneratedLocation (pos->getLoc ());
763777 auto *di = builder.createDestroyValue (loc, currentDef, needsPoison);
778+ instModCallbacks.createdNewInst (di);
764779
765780 consumes.recordFinalConsume (di);
766781
@@ -772,9 +787,10 @@ void CanonicalizeOSSALifetime::insertDestroyOnCFGEdge(
772787// /
773788// / Create a final destroy, immediately after `pos`.
774789static void insertDestroyAtInst (SILBasicBlock::iterator pos,
775- DestroyValueInst *existingDestroy,
776- SILValue def, bool needsPoison,
777- CanonicalOSSAConsumeInfo &consumes) {
790+ DestroyValueInst *existingDestroy, SILValue def,
791+ bool needsPoison,
792+ CanonicalOSSAConsumeInfo &consumes,
793+ InstModCallbacks &callbacks) {
778794 if (existingDestroy) {
779795 for (; pos != existingDestroy->getIterator (); ++pos) {
780796 if (auto *debugVal = dyn_cast<DebugValueInst>(&*pos)) {
@@ -791,6 +807,7 @@ static void insertDestroyAtInst(SILBasicBlock::iterator pos,
791807 SILBuilderWithScope builder (pos);
792808 auto loc = RegularLocation::getAutoGeneratedLocation ((*pos).getLoc ());
793809 auto *di = builder.createDestroyValue (loc, def, needsPoison);
810+ callbacks.createdNewInst (di);
794811 consumes.recordFinalConsume (di);
795812
796813 ++NumDestroysGenerated;
@@ -837,7 +854,7 @@ void CanonicalizeOSSALifetime::findOrInsertDestroyInBlock(SILBasicBlock *bb) {
837854 needsPoison = existingDestroyNeedsPoison;
838855 }
839856 insertDestroyAtInst (std::next (instIter), existingDestroy, currentDef,
840- needsPoison, consumes);
857+ needsPoison, consumes, instModCallbacks );
841858 setChanged ();
842859 }
843860 return ;
@@ -889,7 +906,7 @@ void CanonicalizeOSSALifetime::findOrInsertDestroyInBlock(SILBasicBlock *bb) {
889906 needsPoison = existingDestroyNeedsPoison;
890907 }
891908 insertDestroyAtInst (instIter, existingDestroy, currentDef, needsPoison,
892- consumes);
909+ consumes, instModCallbacks );
893910 setChanged ();
894911 return ;
895912 }
@@ -901,7 +918,7 @@ void CanonicalizeOSSALifetime::findOrInsertDestroyInBlock(SILBasicBlock *bb) {
901918 needsPoison = existingDestroyNeedsPoison;
902919 }
903920 insertDestroyAtInst (std::next (instIter), existingDestroy, currentDef,
904- needsPoison, consumes);
921+ needsPoison, consumes, instModCallbacks );
905922 setChanged ();
906923 return ;
907924 }
@@ -1033,7 +1050,7 @@ void CanonicalizeOSSALifetime::rewriteCopies() {
10331050 continue ;
10341051 }
10351052 if (!visitUse (use)) {
1036- copyLiveUse (use);
1053+ copyLiveUse (use, instModCallbacks );
10371054 setChanged ();
10381055 }
10391056 }
@@ -1047,16 +1064,16 @@ void CanonicalizeOSSALifetime::rewriteCopies() {
10471064 if (!reusedCopyOp && srcCopy->getParent () == use->getParentBlock ()) {
10481065 reusedCopyOp = use;
10491066 } else {
1050- copyLiveUse (use);
1067+ copyLiveUse (use, instModCallbacks );
10511068 setChanged ();
10521069 }
10531070 }
10541071 }
10551072 if (!(reusedCopyOp && srcCopy->hasOneUse ())) {
10561073 setChanged ();
1057- srcCopy-> replaceAllUsesWith ( srcCopy->getOperand ());
1074+ instModCallbacks. replaceValueUsesWith (srcCopy, srcCopy->getOperand ());
10581075 if (reusedCopyOp) {
1059- reusedCopyOp-> set ( srcCopy);
1076+ instModCallbacks. setUseValue (reusedCopyOp, srcCopy);
10601077 } else {
10611078 if (instsToDelete.insert (srcCopy)) {
10621079 LLVM_DEBUG (llvm::dbgs () << " Removing " << *srcCopy);
@@ -1081,7 +1098,7 @@ void CanonicalizeOSSALifetime::rewriteCopies() {
10811098 // Remove any dead, non-recovered debug_values.
10821099 for (auto *dvi : consumes.getDebugInstsAfterConsume ()) {
10831100 LLVM_DEBUG (llvm::dbgs () << " Removing debug_value: " << *dvi);
1084- dvi-> eraseFromParent ( );
1101+ instModCallbacks. deleteInst (dvi );
10851102 }
10861103
10871104 // Remove the leftover copy_value and destroy_value instructions.
@@ -1100,7 +1117,7 @@ void CanonicalizeOSSALifetime::injectPoison() {
11001117 builder.getInsertionPoint ()->getLoc ());
11011118 auto *di = builder.createDestroyValue (loc, currentDef,
11021119 /* needsPoison*/ true );
1103-
1120+ instModCallbacks. createdNewInst (di);
11041121 ++NumDestroysGenerated;
11051122 LLVM_DEBUG (llvm::dbgs () << " Destroy at last use " << *di);
11061123 };
0 commit comments