@@ -94,20 +94,22 @@ SILValue CanonicalizeOSSALifetime::getCanonicalCopiedDef(SILValue v) {
94
94
// / The lifetime extends beyond given consuming use. Copy the value.
95
95
// /
96
96
// / 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 ) {
98
98
SILInstruction *user = use->getUser ();
99
- SILBuilderWithScope B (user->getIterator ());
99
+ SILBuilderWithScope builder (user->getIterator ());
100
100
101
101
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);
104
105
105
106
++NumCopiesGenerated;
106
107
LLVM_DEBUG (llvm::dbgs () << " Copying at last use " << *copy);
107
108
}
108
109
109
110
// 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) {
111
113
if (!hasOneNonDebugUse (extract))
112
114
return nullptr ;
113
115
@@ -123,12 +125,20 @@ SILValue swift::convertExtractToDestructure(StructExtractInst *extract) {
123
125
auto loc = extract->getLoc ();
124
126
auto *copy = builder.createCopyValue (loc, extract->getOperand ());
125
127
auto *destructure = builder.createDestructureStruct (loc, copy);
128
+ if (callbacks) {
129
+ callbacks->createdNewInst (copy);
130
+ callbacks->createdNewInst (destructure);
131
+ }
126
132
127
133
SILValue nonTrivialResult = destructure->getResult (extract->getFieldIndex ());
128
134
assert (!nonTrivialResult->getType ().isTrivial (*destructure->getFunction ())
129
135
&& " field idx mismatch" );
130
136
131
- extractCopy->replaceAllUsesWith (nonTrivialResult);
137
+ if (callbacks) {
138
+ callbacks->replaceValueUsesWith (extractCopy, nonTrivialResult);
139
+ } else {
140
+ extractCopy->replaceAllUsesWith (nonTrivialResult);
141
+ }
132
142
return nonTrivialResult;
133
143
}
134
144
@@ -176,11 +186,13 @@ bool CanonicalizeOSSALifetime::computeBorrowLiveness() {
176
186
// To use an existing outer copy, we could find its earliest consume. But the
177
187
// new copy will immediately canonicalized and a canonical begin_borrow scope
178
188
// 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);
181
192
182
193
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);
184
196
185
197
++NumCopiesGenerated;
186
198
LLVM_DEBUG (llvm::dbgs () << " Outer copy " << *copy);
@@ -346,7 +358,7 @@ void CanonicalizeOSSALifetime::rewriteOuterBorrowUsesAndFindConsumes(
346
358
347
359
auto rewriteOuterUse = [&](Operand *use) {
348
360
LLVM_DEBUG (llvm::dbgs () << " Use of outer copy " << *use->getUser ());
349
- use-> set ( newIncomingValue);
361
+ instModCallbacks. setUseValue (use, newIncomingValue);
350
362
currentOuterUseInsts.push_back (use->getUser ());
351
363
outerUseInsts.insert (incomingValue->getDefiningInstruction ());
352
364
if (use->isLifetimeEnding ()) {
@@ -444,18 +456,19 @@ void CanonicalizeOSSALifetime::rewriteOuterBorrowUsesAndFindConsumes(
444
456
for (auto *boundaryEdge : boundary.boundaryEdges ) {
445
457
if (DeadEndBlocks::triviallyEndsInUnreachable (boundaryEdge))
446
458
continue ;
447
-
448
459
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);
451
463
}
452
464
453
465
for (SILInstruction *lastUser : boundary.lastUsers ) {
454
466
if (unclaimedConsumingUsers.erase (lastUser))
455
467
continue ;
456
468
457
469
SILBuilderWithScope::insertAfter (lastUser, [&](SILBuilder &b) {
458
- b.createDestroyValue (lastUser->getLoc (), newIncomingValue);
470
+ auto *dvi = b.createDestroyValue (lastUser->getLoc (), newIncomingValue);
471
+ instModCallbacks.createdNewInst (dvi);
459
472
});
460
473
}
461
474
// Add copies for consuming users of newIncomingValue.
@@ -466,7 +479,7 @@ void CanonicalizeOSSALifetime::rewriteOuterBorrowUsesAndFindConsumes(
466
479
// unclaimedConsumingUsers set after skipping the first copy.
467
480
auto iterAndInserted = unclaimedConsumingUsers.insert (use->getUser ());
468
481
if (!iterAndInserted.second ) {
469
- copyLiveUse (use);
482
+ copyLiveUse (use, instModCallbacks );
470
483
}
471
484
}
472
485
}
@@ -496,7 +509,8 @@ bool CanonicalizeOSSALifetime::consolidateBorrowScope() {
496
509
if (outerUseInsts.empty ()) {
497
510
return true ;
498
511
}
499
- this ->outerCopy = createOuterCopy (cast<BeginBorrowInst>(currentDef));
512
+ this ->outerCopy =
513
+ createOuterCopy (cast<BeginBorrowInst>(currentDef), instModCallbacks);
500
514
501
515
defUseWorklist.clear ();
502
516
rewriteOuterBorrowUsesAndFindConsumes (currentDef, outerUseInsts);
@@ -761,6 +775,7 @@ void CanonicalizeOSSALifetime::insertDestroyOnCFGEdge(
761
775
SILBuilderWithScope builder (pos);
762
776
auto loc = RegularLocation::getAutoGeneratedLocation (pos->getLoc ());
763
777
auto *di = builder.createDestroyValue (loc, currentDef, needsPoison);
778
+ instModCallbacks.createdNewInst (di);
764
779
765
780
consumes.recordFinalConsume (di);
766
781
@@ -772,9 +787,10 @@ void CanonicalizeOSSALifetime::insertDestroyOnCFGEdge(
772
787
// /
773
788
// / Create a final destroy, immediately after `pos`.
774
789
static 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) {
778
794
if (existingDestroy) {
779
795
for (; pos != existingDestroy->getIterator (); ++pos) {
780
796
if (auto *debugVal = dyn_cast<DebugValueInst>(&*pos)) {
@@ -791,6 +807,7 @@ static void insertDestroyAtInst(SILBasicBlock::iterator pos,
791
807
SILBuilderWithScope builder (pos);
792
808
auto loc = RegularLocation::getAutoGeneratedLocation ((*pos).getLoc ());
793
809
auto *di = builder.createDestroyValue (loc, def, needsPoison);
810
+ callbacks.createdNewInst (di);
794
811
consumes.recordFinalConsume (di);
795
812
796
813
++NumDestroysGenerated;
@@ -837,7 +854,7 @@ void CanonicalizeOSSALifetime::findOrInsertDestroyInBlock(SILBasicBlock *bb) {
837
854
needsPoison = existingDestroyNeedsPoison;
838
855
}
839
856
insertDestroyAtInst (std::next (instIter), existingDestroy, currentDef,
840
- needsPoison, consumes);
857
+ needsPoison, consumes, instModCallbacks );
841
858
setChanged ();
842
859
}
843
860
return ;
@@ -889,7 +906,7 @@ void CanonicalizeOSSALifetime::findOrInsertDestroyInBlock(SILBasicBlock *bb) {
889
906
needsPoison = existingDestroyNeedsPoison;
890
907
}
891
908
insertDestroyAtInst (instIter, existingDestroy, currentDef, needsPoison,
892
- consumes);
909
+ consumes, instModCallbacks );
893
910
setChanged ();
894
911
return ;
895
912
}
@@ -901,7 +918,7 @@ void CanonicalizeOSSALifetime::findOrInsertDestroyInBlock(SILBasicBlock *bb) {
901
918
needsPoison = existingDestroyNeedsPoison;
902
919
}
903
920
insertDestroyAtInst (std::next (instIter), existingDestroy, currentDef,
904
- needsPoison, consumes);
921
+ needsPoison, consumes, instModCallbacks );
905
922
setChanged ();
906
923
return ;
907
924
}
@@ -1033,7 +1050,7 @@ void CanonicalizeOSSALifetime::rewriteCopies() {
1033
1050
continue ;
1034
1051
}
1035
1052
if (!visitUse (use)) {
1036
- copyLiveUse (use);
1053
+ copyLiveUse (use, instModCallbacks );
1037
1054
setChanged ();
1038
1055
}
1039
1056
}
@@ -1047,16 +1064,16 @@ void CanonicalizeOSSALifetime::rewriteCopies() {
1047
1064
if (!reusedCopyOp && srcCopy->getParent () == use->getParentBlock ()) {
1048
1065
reusedCopyOp = use;
1049
1066
} else {
1050
- copyLiveUse (use);
1067
+ copyLiveUse (use, instModCallbacks );
1051
1068
setChanged ();
1052
1069
}
1053
1070
}
1054
1071
}
1055
1072
if (!(reusedCopyOp && srcCopy->hasOneUse ())) {
1056
1073
setChanged ();
1057
- srcCopy-> replaceAllUsesWith ( srcCopy->getOperand ());
1074
+ instModCallbacks. replaceValueUsesWith (srcCopy, srcCopy->getOperand ());
1058
1075
if (reusedCopyOp) {
1059
- reusedCopyOp-> set ( srcCopy);
1076
+ instModCallbacks. setUseValue (reusedCopyOp, srcCopy);
1060
1077
} else {
1061
1078
if (instsToDelete.insert (srcCopy)) {
1062
1079
LLVM_DEBUG (llvm::dbgs () << " Removing " << *srcCopy);
@@ -1081,7 +1098,7 @@ void CanonicalizeOSSALifetime::rewriteCopies() {
1081
1098
// Remove any dead, non-recovered debug_values.
1082
1099
for (auto *dvi : consumes.getDebugInstsAfterConsume ()) {
1083
1100
LLVM_DEBUG (llvm::dbgs () << " Removing debug_value: " << *dvi);
1084
- dvi-> eraseFromParent ( );
1101
+ instModCallbacks. deleteInst (dvi );
1085
1102
}
1086
1103
1087
1104
// Remove the leftover copy_value and destroy_value instructions.
@@ -1100,7 +1117,7 @@ void CanonicalizeOSSALifetime::injectPoison() {
1100
1117
builder.getInsertionPoint ()->getLoc ());
1101
1118
auto *di = builder.createDestroyValue (loc, currentDef,
1102
1119
/* needsPoison*/ true );
1103
-
1120
+ instModCallbacks. createdNewInst (di);
1104
1121
++NumDestroysGenerated;
1105
1122
LLVM_DEBUG (llvm::dbgs () << " Destroy at last use " << *di);
1106
1123
};
0 commit comments