Skip to content

Commit f9feddf

Browse files
committed
[NFC] OSSACanOwned: Vary rewrite with def kind.
When rewriting uses, determine how that rewriting should proceed based on the kind of def whose use is being visited. Direct uses of reborrows and borrowed-froms never need to be rewritten because every such use is a use of a guaranteed value and can never require a copy.
1 parent a6dddbd commit f9feddf

File tree

1 file changed

+42
-26
lines changed

1 file changed

+42
-26
lines changed

lib/SILOptimizer/Utils/CanonicalizeOSSALifetime.cpp

Lines changed: 42 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,7 +1150,6 @@ void CanonicalizeOSSALifetime::rewriteCopies(
11501150
assert(getCurrentDef()->getOwnershipKind() == OwnershipKind::Owned);
11511151

11521152
InstructionSetVector instsToDelete(getCurrentDef()->getFunction());
1153-
defUseWorklist.clear();
11541153

11551154
// Visit each operand in the def-use chain.
11561155
//
@@ -1195,39 +1194,56 @@ void CanonicalizeOSSALifetime::rewriteCopies(
11951194
return true;
11961195
};
11971196

1197+
defUseWorklist.initialize(Def::root(getCurrentDef()));
11981198
// Perform a def-use traversal, visiting each use operand.
1199-
for (auto useIter = getCurrentDef()->use_begin(),
1200-
endIter = getCurrentDef()->use_end(); useIter != endIter;) {
1201-
Operand *use = *useIter++;
1202-
if (!visitUse(use)) {
1203-
copyLiveUse(use, getCallbacks());
1204-
}
1205-
}
12061199
while (auto def = defUseWorklist.pop()) {
1207-
SILValue value = def->getValue();
1208-
CopyValueInst *srcCopy = cast<CopyValueInst>(value);
1209-
// Recurse through copies while replacing their uses.
1210-
Operand *reusedCopyOp = nullptr;
1211-
for (auto useIter = srcCopy->use_begin(); useIter != srcCopy->use_end();) {
1212-
Operand *use = *useIter++;
1213-
if (!visitUse(use)) {
1214-
if (!reusedCopyOp && srcCopy->getParent() == use->getParentBlock()) {
1215-
reusedCopyOp = use;
1216-
} else {
1200+
switch (*def) {
1201+
case Def::Kind::BorrowedFrom:
1202+
case Def::Kind::Reborrow:
1203+
// Direct uses of these defs never need to be rewritten. Being guaranteed
1204+
// values, none of their direct uses consume an owned value.
1205+
assert(def.getValue()->getOwnershipKind() == OwnershipKind::Guaranteed);
1206+
break;
1207+
case Def::Kind::Root: {
1208+
SILValue value = def->getValue();
1209+
for (auto useIter = value->use_begin(), endIter = value->use_end();
1210+
useIter != endIter;) {
1211+
Operand *use = *useIter++;
1212+
if (!visitUse(use)) {
12171213
copyLiveUse(use, getCallbacks());
12181214
}
12191215
}
1216+
break;
12201217
}
1221-
if (!(reusedCopyOp && srcCopy->hasOneUse())) {
1222-
getCallbacks().replaceValueUsesWith(srcCopy, srcCopy->getOperand());
1223-
if (reusedCopyOp) {
1224-
reusedCopyOp->set(srcCopy);
1225-
} else {
1226-
if (instsToDelete.insert(srcCopy)) {
1227-
LLVM_DEBUG(llvm::dbgs() << " Removing " << *srcCopy);
1228-
++NumCopiesAndMovesEliminated;
1218+
case Def::Kind::Copy: {
1219+
SILValue value = def->getValue();
1220+
CopyValueInst *srcCopy = cast<CopyValueInst>(value);
1221+
// Recurse through copies while replacing their uses.
1222+
Operand *reusedCopyOp = nullptr;
1223+
for (auto useIter = srcCopy->use_begin();
1224+
useIter != srcCopy->use_end();) {
1225+
Operand *use = *useIter++;
1226+
if (!visitUse(use)) {
1227+
if (!reusedCopyOp && srcCopy->getParent() == use->getParentBlock()) {
1228+
reusedCopyOp = use;
1229+
} else {
1230+
copyLiveUse(use, getCallbacks());
1231+
}
12291232
}
12301233
}
1234+
if (!(reusedCopyOp && srcCopy->hasOneUse())) {
1235+
getCallbacks().replaceValueUsesWith(srcCopy, srcCopy->getOperand());
1236+
if (reusedCopyOp) {
1237+
reusedCopyOp->set(srcCopy);
1238+
} else {
1239+
if (instsToDelete.insert(srcCopy)) {
1240+
LLVM_DEBUG(llvm::dbgs() << " Removing " << *srcCopy);
1241+
++NumCopiesAndMovesEliminated;
1242+
}
1243+
}
1244+
}
1245+
break;
1246+
}
12311247
}
12321248
}
12331249
assert(!consumes.hasUnclaimedConsumes());

0 commit comments

Comments
 (0)