Index: include/llvm/Transforms/Utils/Local.h =================================================================== --- include/llvm/Transforms/Utils/Local.h +++ include/llvm/Transforms/Utils/Local.h @@ -117,7 +117,8 @@ /// conditions and indirectbr addresses this might make dead if /// DeleteDeadConditions is true. bool ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions = false, - const TargetLibraryInfo *TLI = nullptr); + const TargetLibraryInfo *TLI = nullptr, + DominatorTree *DT = nullptr); //===----------------------------------------------------------------------===// // Local dead code elimination. Index: lib/Transforms/Utils/Local.cpp =================================================================== --- lib/Transforms/Utils/Local.cpp +++ lib/Transforms/Utils/Local.cpp @@ -100,7 +100,8 @@ /// conditions and indirectbr addresses this might make dead if /// DeleteDeadConditions is true. bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions, - const TargetLibraryInfo *TLI) { + const TargetLibraryInfo *TLI, + DominatorTree *DT) { TerminatorInst *T = BB->getTerminator(); IRBuilder<> Builder(T); @@ -123,6 +124,9 @@ // Replace the conditional branch with an unconditional one. Builder.CreateBr(Destination); BI->eraseFromParent(); + + if (DT) + DT->deleteEdge(BB, OldDest); return true; } @@ -159,6 +163,8 @@ TheOnlyDest = SI->case_begin()->getCaseSuccessor(); } + SmallVector Updates; + // Figure out which case it goes to. for (auto i = SI->case_begin(), e = SI->case_end(); i != e;) { // Found case matching a constant operand? @@ -194,6 +200,12 @@ } // Remove this entry. DefaultDest->removePredecessor(SI->getParent()); + + if (DT) { + Updates.push_back({DominatorTree::Delete, SI->getParent(), + DefaultDest}); + } + i = SI->removeCase(i); e = SI->case_end(); continue; @@ -222,18 +234,26 @@ Builder.CreateBr(TheOnlyDest); BasicBlock *BB = SI->getParent(); + // Remove entries from PHI nodes which we no longer branch to... for (BasicBlock *Succ : SI->successors()) { // Found case matching a constant operand? if (Succ == TheOnlyDest) TheOnlyDest = nullptr; // Don't modify the first branch to TheOnlyDest - else + else { Succ->removePredecessor(BB); + + if (DT) + Updates.push_back({DominatorTree::Delete, BB, Succ}); + } } // Delete the old switch. Value *Cond = SI->getCondition(); SI->eraseFromParent(); + + if (DT) + DT->applyUpdates(Updates); if (DeleteDeadConditions) RecursivelyDeleteTriviallyDeadInstructions(Cond, TLI); return true;