Skip to content

Commit 46632f2

Browse files
committed
[NFC] CanOSSALifetime: Break up rewriteCopies.
Add a helper class and promote a lambda to member of it.
1 parent 026aad4 commit 46632f2

File tree

2 files changed

+76
-47
lines changed

2 files changed

+76
-47
lines changed

include/swift/SILOptimizer/Utils/CanonicalizeOSSALifetime.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,8 @@ class CanonicalizeOSSALifetime final {
452452
void insertDestroysOnBoundary(PrunedLivenessBoundary const &boundary);
453453

454454
void rewriteCopies();
455+
class RewriteCopies;
456+
friend class RewriteCopies;
455457
};
456458

457459
} // end namespace swift

lib/SILOptimizer/Utils/CanonicalizeOSSALifetime.cpp

Lines changed: 74 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,57 +1038,78 @@ void swift::copyLiveUse(Operand *use, InstModCallbacks &instModCallbacks) {
10381038
LLVM_DEBUG(llvm::dbgs() << " Copying at last use " << *copy);
10391039
}
10401040

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;
10461048

1047-
InstructionSetVector instsToDelete(getCurrentDef()->getFunction());
1048-
defUseWorklist.clear();
1049+
SILValue getCurrentDef() { return canonicalize.getCurrentDef(); }
1050+
InstModCallbacks &getCallbacks() { return deleter.getCallbacks(); }
10491051

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()) {}
10771058

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();
10831060

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);
10881089
}
1090+
return true;
1091+
}
10891092

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())
10901097
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();
10921113

10931114
// Perform a def-use traversal, visiting each use operand.
10941115
for (auto useIter = getCurrentDef()->use_begin(),
@@ -1126,9 +1147,9 @@ void CanonicalizeOSSALifetime::rewriteCopies() {
11261147
}
11271148
assert(!consumes.hasUnclaimedConsumes());
11281149

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)) {
11321153
LLVM_DEBUG(llvm::dbgs() << " Removing debug_value: " << *dvi);
11331154
deleter.forceDelete(dvi);
11341155
}
@@ -1141,6 +1162,12 @@ void CanonicalizeOSSALifetime::rewriteCopies() {
11411162
}
11421163
}
11431164

1165+
void CanonicalizeOSSALifetime::rewriteCopies() {
1166+
assert(getCurrentDef()->getOwnershipKind() == OwnershipKind::Owned);
1167+
RewriteCopies rewriter(*this);
1168+
rewriter.rewrite();
1169+
}
1170+
11441171
//===----------------------------------------------------------------------===//
11451172
// MARK: Top-Level API
11461173
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)