@@ -1364,7 +1364,7 @@ struct DataflowState {
13641364 bool handleSingleBlockClosure (SILArgument *address,
13651365 ClosureOperandState &state);
13661366 bool cleanupAllDestroyAddr (
1367- SILFunction *fn, SmallBitVector &destroyIndices,
1367+ SILValue address, SILFunction *fn, SmallBitVector &destroyIndices,
13681368 SmallBitVector &reinitIndices, SmallBitVector &consumingClosureIndices,
13691369 BasicBlockSet &blocksVisitedWhenProcessingNewTakes,
13701370 BasicBlockSet &blocksWithMovesThatAreNowTakes,
@@ -1383,14 +1383,14 @@ struct DataflowState {
13831383} // namespace
13841384
13851385bool DataflowState::cleanupAllDestroyAddr (
1386- SILFunction *fn, SmallBitVector &destroyIndices,
1386+ SILValue address, SILFunction *fn, SmallBitVector &destroyIndices,
13871387 SmallBitVector &reinitIndices, SmallBitVector &consumingClosureIndices,
13881388 BasicBlockSet &blocksVisitedWhenProcessingNewTakes,
13891389 BasicBlockSet &blocksWithMovesThatAreNowTakes,
13901390 SmallBlotSetVector<SILInstruction *, 8 > &postDominatingConsumingUsers) {
13911391 bool madeChange = false ;
13921392 BasicBlockWorklist worklist (fn);
1393- SILValue daiOperand;
1393+
13941394 LLVM_DEBUG (llvm::dbgs () << " Cleanup up destroy addr!\n " );
13951395 LLVM_DEBUG (llvm::dbgs () << " Visiting destroys!\n " );
13961396 LLVM_DEBUG (llvm::dbgs () << " Destroy Indices: " << destroyIndices << " \n " );
@@ -1401,9 +1401,6 @@ bool DataflowState::cleanupAllDestroyAddr(
14011401 if (!dai)
14021402 continue ;
14031403 LLVM_DEBUG (llvm::dbgs () << " Destroy: " << *dai);
1404- SILValue op = (*dai)->getOperand ();
1405- assert (daiOperand == SILValue () || op == daiOperand);
1406- daiOperand = op;
14071404 for (auto *predBlock : (*dai)->getParent ()->getPredecessorBlocks ()) {
14081405 worklist.pushIfNotVisited (predBlock);
14091406 }
@@ -1415,7 +1412,7 @@ bool DataflowState::cleanupAllDestroyAddr(
14151412 auto reinit = useState.reinits [index];
14161413 if (!reinit)
14171414 continue ;
1418- LLVM_DEBUG (llvm::dbgs () << " Reinit: " << *reinit);
1415+ LLVM_DEBUG (llvm::dbgs () << " Reinit: " << ** reinit);
14191416 for (auto *predBlock : (*reinit)->getParent ()->getPredecessorBlocks ()) {
14201417 worklist.pushIfNotVisited (predBlock);
14211418 }
@@ -1436,16 +1433,33 @@ bool DataflowState::cleanupAllDestroyAddr(
14361433 while (auto *next = worklist.pop ()) {
14371434 LLVM_DEBUG (llvm::dbgs ()
14381435 << " Looking at block: bb" << next->getDebugID () << " \n " );
1436+
14391437 // Any blocks that contained processed moves are stop points.
1440- if (blocksWithMovesThatAreNowTakes.contains (next))
1438+ if (blocksWithMovesThatAreNowTakes.contains (next)) {
1439+ LLVM_DEBUG (llvm::dbgs ()
1440+ << " Block contained a move that is now a true take.\n " );
14411441 continue ;
1442+ }
14421443
1444+ // Then if we find that we have a block that was never visited when we
1445+ // walked along successor edges from the move, then we know that we need to
1446+ // insert a destroy_addr.
1447+ //
1448+ // This is safe to do since this block lives along the dominance frontier
1449+ // and we do not allow for critical edges, so as we walk along predecessors,
1450+ // given that any such block must also have a successor that was reachable
1451+ // from our move, we know that this unprocessed block must only have one
1452+ // successor, a block reachable from our move and thus must not have any
1453+ // unhandled uses.
14431454 if (!blocksVisitedWhenProcessingNewTakes.contains (next)) {
1455+ LLVM_DEBUG (llvm::dbgs () << " Found a block that was not visited when "
1456+ " we processed takes of the given move.\n " );
14441457 // Insert a destroy_addr here since the block isn't reachable from any of
14451458 // our moves.
1446- SILBuilderWithScope builder (next->getTerminator ());
1459+ SILBuilderWithScope builder (
1460+ std::prev (next->getTerminator ()->getIterator ()));
14471461 auto *dvi = builder.createDestroyAddr (
1448- RegularLocation::getAutoGeneratedLocation (), daiOperand );
1462+ RegularLocation::getAutoGeneratedLocation (), address );
14491463 useState.destroys .insert (dvi);
14501464 continue ;
14511465 }
@@ -1538,7 +1552,7 @@ bool DataflowState::process(
15381552 return indicesOfPairedConsumingClosureUses;
15391553 };
15401554
1541- BasicBlockSet visitedByNewMove (fn);
1555+ BasicBlockSet blocksVisitedWhenProcessingNewTakes (fn);
15421556 BasicBlockSet blocksWithMovesThatAreNowTakes (fn);
15431557 bool convertedMarkMoveToTake = false ;
15441558 for (auto *mvi : markMovesThatPropagateDownwards) {
@@ -1547,12 +1561,12 @@ bool DataflowState::process(
15471561 LLVM_DEBUG (llvm::dbgs () << " Checking Multi Block Dataflow for: " << *mvi);
15481562
15491563 BasicBlockWorklist worklist (fn);
1550- BasicBlockSetVector setVector (fn);
1564+ BasicBlockSetVector visitedBlocks (fn);
15511565 for (auto *succBlock : mvi->getParent ()->getSuccessorBlocks ()) {
15521566 LLVM_DEBUG (llvm::dbgs ()
15531567 << " SuccBlocks: " << succBlock->getDebugID () << " \n " );
15541568 worklist.pushIfNotVisited (succBlock);
1555- setVector .insert (succBlock);
1569+ visitedBlocks .insert (succBlock);
15561570 }
15571571
15581572 while (auto *next = worklist.pop ()) {
@@ -1684,7 +1698,7 @@ bool DataflowState::process(
16841698 // Otherwise, add successors if we haven't visited them to the worklist.
16851699 for (auto *succBlock : next->getSuccessorBlocks ()) {
16861700 worklist.pushIfNotVisited (succBlock);
1687- setVector .insert (succBlock);
1701+ visitedBlocks .insert (succBlock);
16881702 }
16891703 }
16901704
@@ -1701,8 +1715,8 @@ bool DataflowState::process(
17011715 builder.createCopyAddr (mvi->getLoc (), mvi->getSrc (), mvi->getDest (),
17021716 IsTake, IsInitialization);
17031717 // Flush our SetVector into the visitedByNewMove.
1704- for (auto *block : setVector ) {
1705- visitedByNewMove .insert (block);
1718+ for (auto *block : visitedBlocks ) {
1719+ blocksVisitedWhenProcessingNewTakes .insert (block);
17061720 }
17071721 convertedMarkMoveToTake = true ;
17081722 }
@@ -1716,9 +1730,10 @@ bool DataflowState::process(
17161730 // Now that we have processed all of our mark_moves, eliminate all of the
17171731 // destroy_addr.
17181732 madeChange |= cleanupAllDestroyAddr (
1719- fn, getIndicesOfPairedDestroys (), getIndicesOfPairedReinits (),
1720- getIndicesOfPairedConsumingClosureUses (), visitedByNewMove,
1721- blocksWithMovesThatAreNowTakes, postDominatingConsumingUsers);
1733+ address, fn, getIndicesOfPairedDestroys (), getIndicesOfPairedReinits (),
1734+ getIndicesOfPairedConsumingClosureUses (),
1735+ blocksVisitedWhenProcessingNewTakes, blocksWithMovesThatAreNowTakes,
1736+ postDominatingConsumingUsers);
17221737
17231738 return madeChange;
17241739}
0 commit comments