Index: lib/Transforms/Scalar/LoopDeletion.cpp =================================================================== --- lib/Transforms/Scalar/LoopDeletion.cpp +++ lib/Transforms/Scalar/LoopDeletion.cpp @@ -276,21 +276,21 @@ ++BI; } - // Update the dominator tree and remove the instructions and blocks that will - // be deleted from the reference counting scheme. - SmallVector ChildNodes; + // Update the dominator tree. Disconnect the loop by bypassing the loop body. + // + // This is a special use of the incremental API. + // We know that all of the loop nodes are dominated by the loop preheader. + // Instead of telling the DT of deleting and inserting edges as we go, we + // defer it until here. We tell the DT that we delete the edge from the + // preaheader to the header and the incremental algorithm will automatically + // disconnect the rest of the loop. + // When we tell the DT to insert an edge from the preheader to the exit, we + // are back in sync with the changes that happened to the CFG. + DT.deleteEdge(Preheader, L->getHeader()); + DT.insertEdge(Preheader, ExitBlock); + for (Loop::block_iterator LI = L->block_begin(), LE = L->block_end(); LI != LE; ++LI) { - // Move all of the block's children to be children of the Preheader, which - // allows us to remove the domtree entry for the block. - ChildNodes.insert(ChildNodes.begin(), DT[*LI]->begin(), DT[*LI]->end()); - for (DomTreeNode *ChildNode : ChildNodes) { - DT.changeImmediateDominator(ChildNode, DT[Preheader]); - } - - ChildNodes.clear(); - DT.eraseNode(*LI); - // Remove the block from the reference counting scheme, so that we can // delete it freely later. (*LI)->dropAllReferences();