@@ -1038,57 +1038,78 @@ void swift::copyLiveUse(Operand *use, InstModCallbacks &instModCallbacks) {
1038
1038
LLVM_DEBUG (llvm::dbgs () << " Copying at last use " << *copy);
1039
1039
}
1040
1040
1041
- // / Revisit the def-use chain of currentDef. Mark unneeded original
1042
- // / copies and destroys for deletion. Insert new copies for interior uses that
1043
- // / require ownership of the used operand.
1044
- void CanonicalizeOSSALifetime::rewriteCopies () {
1045
- assert (getCurrentDef ()->getOwnershipKind () == OwnershipKind::Owned);
1041
+ class CanonicalizeOSSALifetime ::RewriteCopies {
1042
+ CanonicalizeOSSALifetime &canonicalize;
1043
+ SSAPrunedLiveness &liveness;
1044
+ GraphNodeWorklist<SILValue, 8 > &defUseWorklist;
1045
+ CanonicalOSSAConsumeInfo &consumes;
1046
+ InstructionDeleter &deleter;
1047
+ InstructionSetVector instsToDelete;
1046
1048
1047
- InstructionSetVector instsToDelete ( getCurrentDef ()-> getFunction ());
1048
- defUseWorklist. clear ();
1049
+ SILValue getCurrentDef () { return canonicalize. getCurrentDef (); }
1050
+ InstModCallbacks & getCallbacks () { return deleter. getCallbacks (); }
1049
1051
1050
- // Visit each operand in the def-use chain.
1051
- //
1052
- // Return true if the operand can use the current definition. Return false if
1053
- // it requires a copy.
1054
- auto visitUse = [&](Operand *use) {
1055
- auto *user = use->getUser ();
1056
- // Recurse through copies.
1057
- if (auto *copy = dyn_cast<CopyValueInst>(user)) {
1058
- defUseWorklist.insert (copy);
1059
- return true ;
1060
- }
1061
- if (destroys.contains (user)) {
1062
- auto *destroy = cast<DestroyValueInst>(user);
1063
- // If this destroy was marked as a final destroy, ignore it; otherwise,
1064
- // delete it.
1065
- if (!consumes.claimConsume (destroy)) {
1066
- instsToDelete.insert (destroy);
1067
- LLVM_DEBUG (llvm::dbgs () << " Removing " << *destroy);
1068
- ++NumDestroysEliminated;
1069
- } else if (pruneDebugMode) {
1070
- // If this destroy was marked as a final destroy, add it to liveness so
1071
- // that we don't delete any debug instructions that occur before it.
1072
- // (Only relevant in pruneDebugMode).
1073
- liveness->updateForUse (destroy, /* lifetimeEnding*/ true );
1074
- }
1075
- return true ;
1076
- }
1052
+ public:
1053
+ RewriteCopies (CanonicalizeOSSALifetime &canonicalize)
1054
+ : canonicalize(canonicalize), liveness(*canonicalize.liveness),
1055
+ defUseWorklist (canonicalize.defUseWorklist),
1056
+ consumes(canonicalize.consumes), deleter(canonicalize.deleter),
1057
+ instsToDelete(canonicalize.getCurrentDef()->getFunction()) {}
1077
1058
1078
- // Nonconsuming uses do not need copies and cannot be marked as destroys.
1079
- // A lifetime-ending use here must be a consume because EndBorrow/Reborrow
1080
- // uses have been filtered out.
1081
- if (!use->isLifetimeEnding ())
1082
- return true ;
1059
+ void rewrite ();
1083
1060
1084
- // If this use was not marked as a final destroy *or* this is not the first
1085
- // consumed operand we visited, then it needs a copy.
1086
- if (!consumes.claimConsume (user)) {
1087
- return false ;
1061
+ private:
1062
+ bool visitUse (Operand *use);
1063
+ };
1064
+
1065
+ // Visit each operand in the def-use chain.
1066
+ //
1067
+ // Return true if the operand can use the current definition. Return false if
1068
+ // it requires a copy.
1069
+ bool CanonicalizeOSSALifetime::RewriteCopies::visitUse (Operand *use) {
1070
+ auto *user = use->getUser ();
1071
+ // Recurse through copies.
1072
+ if (auto *copy = dyn_cast<CopyValueInst>(user)) {
1073
+ defUseWorklist.insert (copy);
1074
+ return true ;
1075
+ }
1076
+ if (canonicalize.destroys .contains (user)) {
1077
+ auto *destroy = cast<DestroyValueInst>(user);
1078
+ // If this destroy was marked as a final destroy, ignore it; otherwise,
1079
+ // delete it.
1080
+ if (!consumes.claimConsume (destroy)) {
1081
+ instsToDelete.insert (destroy);
1082
+ LLVM_DEBUG (llvm::dbgs () << " Removing " << *destroy);
1083
+ ++NumDestroysEliminated;
1084
+ } else if (canonicalize.pruneDebugMode ) {
1085
+ // If this destroy was marked as a final destroy, add it to liveness so
1086
+ // that we don't delete any debug instructions that occur before it.
1087
+ // (Only relevant in pruneDebugMode).
1088
+ liveness.updateForUse (destroy, /* lifetimeEnding*/ true );
1088
1089
}
1090
+ return true ;
1091
+ }
1089
1092
1093
+ // Nonconsuming uses do not need copies and cannot be marked as destroys.
1094
+ // A lifetime-ending use here must be a consume because EndBorrow/Reborrow
1095
+ // uses have been filtered out.
1096
+ if (!use->isLifetimeEnding ())
1090
1097
return true ;
1091
- };
1098
+
1099
+ // If this use was not marked as a final destroy *or* this is not the first
1100
+ // consumed operand we visited, then it needs a copy.
1101
+ if (!consumes.claimConsume (user)) {
1102
+ return false ;
1103
+ }
1104
+
1105
+ return true ;
1106
+ }
1107
+
1108
+ // / Revisit the def-use chain of currentDef. Mark unneeded original
1109
+ // / copies and destroys for deletion. Insert new copies for interior uses that
1110
+ // / require ownership of the used operand.
1111
+ void CanonicalizeOSSALifetime::RewriteCopies::rewrite () {
1112
+ defUseWorklist.clear ();
1092
1113
1093
1114
// Perform a def-use traversal, visiting each use operand.
1094
1115
for (auto useIter = getCurrentDef ()->use_begin (),
@@ -1126,9 +1147,9 @@ void CanonicalizeOSSALifetime::rewriteCopies() {
1126
1147
}
1127
1148
assert (!consumes.hasUnclaimedConsumes ());
1128
1149
1129
- if (pruneDebugMode) {
1130
- for (auto *dvi : debugValues) {
1131
- if (!liveness-> isWithinBoundary (dvi)) {
1150
+ if (canonicalize. pruneDebugMode ) {
1151
+ for (auto *dvi : canonicalize. debugValues ) {
1152
+ if (!liveness. isWithinBoundary (dvi)) {
1132
1153
LLVM_DEBUG (llvm::dbgs () << " Removing debug_value: " << *dvi);
1133
1154
deleter.forceDelete (dvi);
1134
1155
}
@@ -1141,6 +1162,12 @@ void CanonicalizeOSSALifetime::rewriteCopies() {
1141
1162
}
1142
1163
}
1143
1164
1165
+ void CanonicalizeOSSALifetime::rewriteCopies () {
1166
+ assert (getCurrentDef ()->getOwnershipKind () == OwnershipKind::Owned);
1167
+ RewriteCopies rewriter (*this );
1168
+ rewriter.rewrite ();
1169
+ }
1170
+
1144
1171
// ===----------------------------------------------------------------------===//
1145
1172
// MARK: Top-Level API
1146
1173
// ===----------------------------------------------------------------------===//
0 commit comments