@@ -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