diff --git a/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h b/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h --- a/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h +++ b/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h @@ -91,11 +91,16 @@ /// if BB's Pred has a branch to BB and to AnotherBB, and BB has a single /// successor Sing. In this case the branch will be updated with Sing instead of /// BB, and BB will still be merged into its predecessor and removed. +/// +/// Pass True to SkipRedundantDebugValElimination in order to skip redundant +/// debug val elimination. This elimination has O(#instructions) time +/// complexity, and may result in unreasonably long compile times. bool MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU = nullptr, LoopInfo *LI = nullptr, MemorySSAUpdater *MSSAU = nullptr, MemoryDependenceResults *MemDep = nullptr, - bool PredecessorWithTwoSuccessors = false); + bool PredecessorWithTwoSuccessors = false, + bool SkipRedundantDebugValElimination = false); /// Merge block(s) sucessors, if possible. Return true if at least two /// of the blocks were merged together. diff --git a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp --- a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp +++ b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp @@ -172,7 +172,8 @@ bool llvm::MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU, LoopInfo *LI, MemorySSAUpdater *MSSAU, MemoryDependenceResults *MemDep, - bool PredecessorWithTwoSuccessors) { + bool PredecessorWithTwoSuccessors, + bool SkipRedundantDebugValElimination) { if (BB->hasAddressTaken()) return false; @@ -285,10 +286,12 @@ // Add unreachable to now empty BB. new UnreachableInst(BB->getContext(), BB); - // Eliminate duplicate/redundant dbg.values. This seems to be a good place to - // do that since we might end up with redundant dbg.values describing the - // entry PHI node post-splice. - RemoveRedundantDbgInstrs(PredBB); + if (!SkipRedundantDebugValElimination) { + // Eliminate duplicate/redundant dbg.values. This seems to be a good place + // to do that since we might end up with redundant dbg.values describing the + // entry PHI node post-splice. + RemoveRedundantDbgInstrs(PredBB); + } // Inherit predecessors name if it exists. if (!PredBB->hasName()) diff --git a/llvm/lib/Transforms/Utils/LoopUnroll.cpp b/llvm/lib/Transforms/Utils/LoopUnroll.cpp --- a/llvm/lib/Transforms/Utils/LoopUnroll.cpp +++ b/llvm/lib/Transforms/Utils/LoopUnroll.cpp @@ -234,6 +234,7 @@ if (isInstructionTriviallyDead(Inst)) BB->getInstList().erase(Inst); } + RemoveRedundantDbgInstrs(BB); } // TODO: after peeling or unrolling, previously loop variant conditions are @@ -862,7 +863,10 @@ if (Term && Term->isUnconditional()) { BasicBlock *Dest = Term->getSuccessor(0); BasicBlock *Fold = Dest->getUniquePredecessor(); - if (MergeBlockIntoPredecessor(Dest, &DTU, LI)) { + // Deferring redundant debug value elimination. For sufficiently + // complicated loop bodies, this can result in multi-minute compile times. + if (MergeBlockIntoPredecessor(Dest, &DTU, LI, nullptr, nullptr, false, + true)) { // Dest has been folded into Fold. Update our worklists accordingly. std::replace(Latches.begin(), Latches.end(), Dest, Fold); UnrolledLoopBlocks.erase(std::remove(UnrolledLoopBlocks.begin(),