[llvm] r314435 - [JumpThreading] Preserve DT and LVI across the pass

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 29 08:51:24 PDT 2017


The commit I was thinking of was 309355.  What's the interaction here?


On 09/29/2017 08:29 AM, Philip Reames wrote:
> Er, have you checked the history here?  I thought this preservation 
> was removed relatively recently to avoid a correctness bug.
>
> Philip
>
>
> On 09/28/2017 10:24 AM, Evandro Menezes via llvm-commits wrote:
>> Author: evandro
>> Date: Thu Sep 28 10:24:40 2017
>> New Revision: 314435
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=314435&view=rev
>> Log:
>> [JumpThreading] Preserve DT and LVI across the pass
>>
>> JumpThreading now preserves dominance and lazy value information 
>> across the
>> entire pass.  The pass manager is also informed of this preservation 
>> with
>> the goal of DT and LVI being recalculated fewer times overall during
>> compilation.
>>
>> This change prepares JumpThreading for enhanced opportunities; 
>> particularly
>> those across loop boundaries.
>>
>> Patch by: Brian Rzycki <b.rzycki at samsung.com>,
>>            Sebastian Pop <s.pop at samsung.com>
>>
>> Differential revision: https://reviews.llvm.org/D37528
>>
>> Modified:
>>      llvm/trunk/include/llvm/Transforms/Scalar/JumpThreading.h
>>      llvm/trunk/include/llvm/Transforms/Utils/Local.h
>> llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
>>      llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp
>>      llvm/trunk/lib/Transforms/Utils/Local.cpp
>> llvm/trunk/test/Analysis/LazyValueAnalysis/lvi-after-jumpthreading.ll
>>
>> Modified: llvm/trunk/include/llvm/Transforms/Scalar/JumpThreading.h
>> URL: 
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar/JumpThreading.h?rev=314435&r1=314434&r2=314435&view=diff
>> ============================================================================== 
>>
>> --- llvm/trunk/include/llvm/Transforms/Scalar/JumpThreading.h (original)
>> +++ llvm/trunk/include/llvm/Transforms/Scalar/JumpThreading.h Thu Sep 
>> 28 10:24:40 2017
>> @@ -34,6 +34,7 @@ class BinaryOperator;
>>   class BranchInst;
>>   class CmpInst;
>>   class Constant;
>> +class DominatorTree;
>>   class Function;
>>   class Instruction;
>>   class IntrinsicInst;
>> @@ -77,6 +78,7 @@ class JumpThreadingPass : public PassInf
>>     TargetLibraryInfo *TLI;
>>     LazyValueInfo *LVI;
>>     AliasAnalysis *AA;
>> +  DominatorTree *DT;
>>     std::unique_ptr<BlockFrequencyInfo> BFI;
>>     std::unique_ptr<BranchProbabilityInfo> BPI;
>>     bool HasProfileData = false;
>> @@ -107,7 +109,7 @@ public:
>>       // Glue for old PM.
>>     bool runImpl(Function &F, TargetLibraryInfo *TLI_, LazyValueInfo 
>> *LVI_,
>> -               AliasAnalysis *AA_, bool HasProfileData_,
>> +               AliasAnalysis *AA_, DominatorTree *DT_, bool 
>> HasProfileData_,
>>                  std::unique_ptr<BlockFrequencyInfo> BFI_,
>>                  std::unique_ptr<BranchProbabilityInfo> BPI_);
>>
>> Modified: llvm/trunk/include/llvm/Transforms/Utils/Local.h
>> URL: 
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Local.h?rev=314435&r1=314434&r2=314435&view=diff
>> ============================================================================== 
>>
>> --- llvm/trunk/include/llvm/Transforms/Utils/Local.h (original)
>> +++ llvm/trunk/include/llvm/Transforms/Utils/Local.h Thu Sep 28 
>> 10:24:40 2017
>> @@ -79,7 +79,8 @@ struct SimplifyCFGOptions {
>>   /// 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.
>> @@ -133,7 +134,8 @@ bool SimplifyInstructionsInBlock(BasicBl
>>   ///
>>   /// .. and delete the predecessor corresponding to the '1', this 
>> will attempt to
>>   /// recursively fold the 'and' to 0.
>> -void RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred);
>> +void RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred,
>> +                                  DominatorTree *DT = nullptr);
>>     /// BB is a block with one predecessor and its predecessor is 
>> known to have one
>>   /// successor (BB!). Eliminate the edge between them, moving the 
>> instructions in
>> @@ -144,7 +146,8 @@ void MergeBasicBlockIntoOnlyPred(BasicBl
>>   /// other than PHI nodes, potential debug intrinsics and the 
>> branch. If
>>   /// possible, eliminate BB by rewriting all the predecessors to 
>> branch to the
>>   /// successor block and return true. If we can't transform, return 
>> false.
>> -bool TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB);
>> +bool TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB,
>> +                                             DominatorTree *DT = 
>> nullptr);
>>     /// Check for and eliminate duplicate PHI nodes in this block. 
>> This doesn't try
>>   /// to be clever about PHI nodes which differ only in the order of 
>> the incoming
>> @@ -342,7 +345,8 @@ unsigned removeAllNonTerminatorAndEHPadI
>>   /// Insert an unreachable instruction before the specified
>>   /// instruction, making it and the rest of the code in the block dead.
>>   unsigned changeToUnreachable(Instruction *I, bool UseLLVMTrap,
>> -                             bool PreserveLCSSA = false);
>> +                             bool PreserveLCSSA = false,
>> +                             DominatorTree *DT = nullptr);
>>     /// Convert the CallInst to InvokeInst with the specified unwind 
>> edge basic
>>   /// block.  This also splits the basic block where CI is located, 
>> because
>> @@ -357,12 +361,13 @@ BasicBlock *changeToInvokeAndSplitBasicB
>>   ///
>>   /// \param BB  Block whose terminator will be replaced.  Its 
>> terminator must
>>   ///            have an unwind successor.
>> -void removeUnwindEdge(BasicBlock *BB);
>> +void removeUnwindEdge(BasicBlock *BB, DominatorTree *DT = nullptr);
>>     /// Remove all blocks that can not be reached from the function's 
>> entry.
>>   ///
>>   /// Returns true if any basic block was removed.
>> -bool removeUnreachableBlocks(Function &F, LazyValueInfo *LVI = 
>> nullptr);
>> +bool removeUnreachableBlocks(Function &F, LazyValueInfo *LVI = nullptr,
>> +                             DominatorTree *DT = nullptr);
>>     /// Combine the metadata of two instructions so that K can replace J
>>   ///
>>
>> Modified: 
>> llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
>> URL: 
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp?rev=314435&r1=314434&r2=314435&view=diff
>> ============================================================================== 
>>
>> --- llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp 
>> (original)
>> +++ llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp 
>> Thu Sep 28 10:24:40 2017
>> @@ -55,6 +55,7 @@ namespace {
>>       bool runOnFunction(Function &F) override;
>>         void getAnalysisUsage(AnalysisUsage &AU) const override {
>> +      AU.addRequired<DominatorTreeWrapperPass>();
>>         AU.addRequired<LazyValueInfoWrapperPass>();
>>         AU.addPreserved<GlobalsAAWrapperPass>();
>>       }
>> @@ -64,6 +65,7 @@ namespace {
>>   char CorrelatedValuePropagation::ID = 0;
>>   INITIALIZE_PASS_BEGIN(CorrelatedValuePropagation, 
>> "correlated-propagation",
>>                   "Value Propagation", false, false)
>> +INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
>>   INITIALIZE_PASS_DEPENDENCY(LazyValueInfoWrapperPass)
>>   INITIALIZE_PASS_END(CorrelatedValuePropagation, 
>> "correlated-propagation",
>>                   "Value Propagation", false, false)
>>
>> Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp
>> URL: 
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=314435&r1=314434&r2=314435&view=diff
>> ============================================================================== 
>>
>> --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original)
>> +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Thu Sep 28 
>> 10:24:40 2017
>> @@ -131,10 +131,11 @@ namespace {
>>       bool runOnFunction(Function &F) override;
>>         void getAnalysisUsage(AnalysisUsage &AU) const override {
>> -      if (PrintLVIAfterJumpThreading)
>> -        AU.addRequired<DominatorTreeWrapperPass>();
>> +      AU.addRequired<DominatorTreeWrapperPass>();
>> +      AU.addPreserved<DominatorTreeWrapperPass>();
>>         AU.addRequired<AAResultsWrapperPass>();
>>         AU.addRequired<LazyValueInfoWrapperPass>();
>> +      AU.addPreserved<LazyValueInfoWrapperPass>();
>>         AU.addPreserved<GlobalsAAWrapperPass>();
>>         AU.addRequired<TargetLibraryInfoWrapperPass>();
>>       }
>> @@ -148,6 +149,7 @@ char JumpThreading::ID = 0;
>>     INITIALIZE_PASS_BEGIN(JumpThreading, "jump-threading",
>>                   "Jump Threading", false, false)
>> +INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
>>   INITIALIZE_PASS_DEPENDENCY(LazyValueInfoWrapperPass)
>>   INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
>>   INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
>> @@ -277,6 +279,9 @@ bool JumpThreading::runOnFunction(Functi
>>     if (skipFunction(F))
>>       return false;
>>     auto TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
>> +  // Get DT analysis before LVI. When LVI is initialized it 
>> conditionally adds
>> +  // DT if it's available.
>> +  auto DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
>>     auto LVI = &getAnalysis<LazyValueInfoWrapperPass>().getLVI();
>>     auto AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
>>     std::unique_ptr<BlockFrequencyInfo> BFI;
>> @@ -288,12 +293,11 @@ bool JumpThreading::runOnFunction(Functi
>>       BFI.reset(new BlockFrequencyInfo(F, *BPI, LI));
>>     }
>>   -  bool Changed = Impl.runImpl(F, TLI, LVI, AA, HasProfileData, 
>> std::move(BFI),
>> -                              std::move(BPI));
>> +  bool Changed = Impl.runImpl(F, TLI, LVI, AA, DT, HasProfileData,
>> +                              std::move(BFI), std::move(BPI));
>>     if (PrintLVIAfterJumpThreading) {
>>       dbgs() << "LVI for function '" << F.getName() << "':\n";
>> -    LVI->printLVI(F, 
>> getAnalysis<DominatorTreeWrapperPass>().getDomTree(),
>> -                  dbgs());
>> +    LVI->printLVI(F, *DT, dbgs());
>>     }
>>     return Changed;
>>   }
>> @@ -301,6 +305,9 @@ bool JumpThreading::runOnFunction(Functi
>>   PreservedAnalyses JumpThreadingPass::run(Function &F,
>> FunctionAnalysisManager &AM) {
>>     auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
>> +  // Get DT analysis before LVI. When LVI is initialized it 
>> conditionally adds
>> +  // DT if it's available.
>> +  auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
>>     auto &LVI = AM.getResult<LazyValueAnalysis>(F);
>>     auto &AA = AM.getResult<AAManager>(F);
>>   @@ -313,25 +320,28 @@ PreservedAnalyses JumpThreadingPass::run
>>       BFI.reset(new BlockFrequencyInfo(F, *BPI, LI));
>>     }
>>   -  bool Changed = runImpl(F, &TLI, &LVI, &AA, HasProfileData, 
>> std::move(BFI),
>> -                         std::move(BPI));
>> +  bool Changed = runImpl(F, &TLI, &LVI, &AA, &DT, HasProfileData,
>> +                         std::move(BFI), std::move(BPI));
>>       if (!Changed)
>>       return PreservedAnalyses::all();
>>     PreservedAnalyses PA;
>>     PA.preserve<GlobalsAA>();
>> +  PA.preserve<DominatorTreeAnalysis>();
>> +  PA.preserve<LazyValueAnalysis>();
>>     return PA;
>>   }
>>     bool JumpThreadingPass::runImpl(Function &F, TargetLibraryInfo 
>> *TLI_,
>>                                   LazyValueInfo *LVI_, AliasAnalysis 
>> *AA_,
>> -                                bool HasProfileData_,
>> +                                DominatorTree *DT_, bool 
>> HasProfileData_,
>> std::unique_ptr<BlockFrequencyInfo> BFI_,
>> std::unique_ptr<BranchProbabilityInfo> BPI_) {
>>     DEBUG(dbgs() << "Jump threading on function '" << F.getName() << 
>> "'\n");
>>     TLI = TLI_;
>>     LVI = LVI_;
>>     AA = AA_;
>> +  DT = DT_;
>>     BFI.reset();
>>     BPI.reset();
>>     // When profile data is available, we need to update edge weights 
>> after
>> @@ -353,8 +363,7 @@ bool JumpThreadingPass::runImpl(Function
>>     // back edges. This works for normal cases but not for 
>> unreachable blocks as
>>     // they may have cycle with no back edge.
>>     bool EverChanged = false;
>> -  EverChanged |= removeUnreachableBlocks(F, LVI);
>> -
>> +  EverChanged |= removeUnreachableBlocks(F, LVI, DT);
>>     FindLoopHeaders(F);
>>       bool Changed;
>> @@ -400,7 +409,7 @@ bool JumpThreadingPass::runImpl(Function
>>           // awesome, but it allows us to use AssertingVH to prevent 
>> nasty
>>           // dangling pointer issues within LazyValueInfo.
>>           LVI->eraseBlock(BB);
>> -        if (TryToSimplifyUncondBranchFromEmptyBlock(BB))
>> +        if (TryToSimplifyUncondBranchFromEmptyBlock(BB, DT))
>>             Changed = true;
>>         }
>>       }
>> @@ -948,7 +957,7 @@ bool JumpThreadingPass::ProcessBlock(Bas
>>           LoopHeaders.insert(BB);
>>           LVI->eraseBlock(SinglePred);
>> -      MergeBasicBlockIntoOnlyPred(BB);
>> +      MergeBasicBlockIntoOnlyPred(BB, DT);
>>           // Now that BB is merged into SinglePred (i.e. SinglePred 
>> Code followed by
>>         // BB code within one basic block `BB`), we need to 
>> invalidate the LVI
>> @@ -1031,18 +1040,27 @@ bool JumpThreadingPass::ProcessBlock(Bas
>>     // successors to branch to.  Let GetBestDestForJumpOnUndef decide.
>>     if (isa<UndefValue>(Condition)) {
>>       unsigned BestSucc = GetBestDestForJumpOnUndef(BB);
>> +    std::vector<DominatorTree::UpdateType> Updates;
>>         // Fold the branch/switch.
>>       TerminatorInst *BBTerm = BB->getTerminator();
>>       for (unsigned i = 0, e = BBTerm->getNumSuccessors(); i != e; 
>> ++i) {
>>         if (i == BestSucc) continue;
>> -      BBTerm->getSuccessor(i)->removePredecessor(BB, true);
>> +      BasicBlock *Succ = BBTerm->getSuccessor(i);
>> +      Succ->removePredecessor(BB, true);
>> +      if (Succ == BB)
>> +        continue;
>> +      DominatorTree::UpdateType UT = {DominatorTree::Delete, BB, Succ};
>> +      // Make sure to remove a DT edge exactly once and not an edge 
>> to itself.
>> +      if (std::find(Updates.begin(), Updates.end(), UT) == 
>> Updates.end())
>> +        Updates.push_back(UT);
>>       }
>>         DEBUG(dbgs() << "  In block '" << BB->getName()
>>             << "' folding undef terminator: " << *BBTerm << '\n');
>>       BranchInst::Create(BBTerm->getSuccessor(BestSucc), BBTerm);
>>       BBTerm->eraseFromParent();
>> +    DT->applyUpdates(Updates);
>>       return true;
>>     }
>>   @@ -1053,7 +1071,7 @@ bool JumpThreadingPass::ProcessBlock(Bas
>>       DEBUG(dbgs() << "  In block '" << BB->getName()
>>             << "' folding terminator: " << *BB->getTerminator() << 
>> '\n');
>>       ++NumFolds;
>> -    ConstantFoldTerminator(BB, true);
>> +    ConstantFoldTerminator(BB, true, nullptr, DT);
>>       return true;
>>     }
>>   @@ -1086,9 +1104,12 @@ bool JumpThreadingPass::ProcessBlock(Bas
>>         if (Ret != LazyValueInfo::Unknown) {
>>           unsigned ToRemove = Ret == LazyValueInfo::True ? 1 : 0;
>>           unsigned ToKeep = Ret == LazyValueInfo::True ? 0 : 1;
>> - CondBr->getSuccessor(ToRemove)->removePredecessor(BB, true);
>> +        BasicBlock *ToRemoveSucc = CondBr->getSuccessor(ToRemove);
>> +        ToRemoveSucc->removePredecessor(BB, true);
>>           BranchInst::Create(CondBr->getSuccessor(ToKeep), CondBr);
>>           CondBr->eraseFromParent();
>> +        if (BB != ToRemoveSucc)
>> +          DT->deleteEdge(BB, ToRemoveSucc);
>>           if (CondCmp->use_empty())
>>             CondCmp->eraseFromParent();
>>           // We can safely replace *some* uses of the CondInst if it has
>> @@ -1182,9 +1203,12 @@ bool JumpThreadingPass::ProcessImpliedCo
>>       Optional<bool> Implication =
>>           isImpliedCondition(PBI->getCondition(), Cond, DL, CondIsTrue);
>>       if (Implication) {
>> -      BI->getSuccessor(*Implication ? 1 : 0)->removePredecessor(BB);
>> +      BasicBlock *RemoveSucc = BI->getSuccessor(*Implication ? 1 : 0);
>> +      RemoveSucc->removePredecessor(BB);
>>         BranchInst::Create(BI->getSuccessor(*Implication ? 0 : 1), BI);
>>         BI->eraseFromParent();
>> +      if (BB != RemoveSucc)
>> +        DT->deleteEdge(BB, RemoveSucc);
>>         return true;
>>       }
>>       CurrentBB = CurrentPred;
>> @@ -1576,18 +1600,27 @@ bool JumpThreadingPass::ProcessThreadabl
>>     if (OnlyDest && OnlyDest != MultipleDestSentinel) {
>>       if (PredWithKnownDest ==
>>           (size_t)std::distance(pred_begin(BB), pred_end(BB))) {
>> +      std::vector<DominatorTree::UpdateType> Updates;
>>         bool SeenFirstBranchToOnlyDest = false;
>>         for (BasicBlock *SuccBB : successors(BB)) {
>> -        if (SuccBB == OnlyDest && !SeenFirstBranchToOnlyDest)
>> +        if (SuccBB == OnlyDest && !SeenFirstBranchToOnlyDest) {
>>             SeenFirstBranchToOnlyDest = true; // Don't modify the 
>> first branch.
>> -        else
>> +        } else {
>>             SuccBB->removePredecessor(BB, true); // This is 
>> unreachable successor.
>> +          if (SuccBB != OnlyDest && SuccBB != BB) {
>> +            DominatorTree::UpdateType UT = {DominatorTree::Delete, 
>> BB, SuccBB};
>> +            // Make sure to remove a DT edge exactly once.
>> +            if (std::find(Updates.begin(), Updates.end(), UT) == 
>> Updates.end())
>> +              Updates.push_back(UT);
>> +          }
>> +        }
>>         }
>>           // Finally update the terminator.
>>         TerminatorInst *Term = BB->getTerminator();
>>         BranchInst::Create(OnlyDest, Term);
>>         Term->eraseFromParent();
>> +      DT->applyUpdates(Updates);
>>           // If the condition is now dead due to the removal of the 
>> old terminator,
>>         // erase it.
>> @@ -1922,7 +1955,6 @@ bool JumpThreadingPass::ThreadEdge(Basic
>>           UsesToRename.push_back(&U);
>>       }
>> -
>>       // If there are no uses outside the block, we're done with this 
>> instruction.
>>       if (UsesToRename.empty())
>>         continue;
>> @@ -1951,6 +1983,10 @@ bool JumpThreadingPass::ThreadEdge(Basic
>>         PredTerm->setSuccessor(i, NewBB);
>>       }
>>   +  DT->applyUpdates({{DominatorTree::Insert, NewBB, SuccBB},
>> +                    {DominatorTree::Insert, PredBB, NewBB},
>> +                    {DominatorTree::Delete, PredBB, BB}});
>> +
>>     // At this point, the IR is fully up to date and consistent.  Do 
>> a quick scan
>>     // over the new instructions and zap any that are constants or 
>> dead.  This
>>     // frequently happens because of phi translation.
>> @@ -1977,7 +2013,7 @@ BasicBlock *JumpThreadingPass::SplitBloc
>>       for (auto Pred : Preds)
>>         PredBBFreq += BFI->getBlockFreq(Pred) * 
>> BPI->getEdgeProbability(Pred, BB);
>>   -  BasicBlock *PredBB = SplitBlockPredecessors(BB, Preds, Suffix);
>> +  BasicBlock *PredBB = SplitBlockPredecessors(BB, Preds, Suffix, DT);
>>       // Set the block frequency of the newly created PredBB, which 
>> is the sum of
>>     // frequencies of Preds.
>> @@ -2147,7 +2183,7 @@ bool JumpThreadingPass::DuplicateCondBra
>>     BranchInst *OldPredBranch = 
>> dyn_cast<BranchInst>(PredBB->getTerminator());
>>       if (!OldPredBranch || !OldPredBranch->isUnconditional()) {
>> -    PredBB = SplitEdge(PredBB, BB);
>> +    PredBB = SplitEdge(PredBB, BB, DT);
>>       OldPredBranch = cast<BranchInst>(PredBB->getTerminator());
>>     }
>>   @@ -2244,6 +2280,8 @@ bool JumpThreadingPass::DuplicateCondBra
>>       // Remove the unconditional branch at the end of the PredBB block.
>>     OldPredBranch->eraseFromParent();
>> +  if (BB != PredBB)
>> +    DT->deleteEdge(PredBB, BB);
>>       ++NumDupes;
>>     return true;
>> @@ -2309,6 +2347,7 @@ bool JumpThreadingPass::TryToUnfoldSelec
>>         // Move the unconditional branch to NewBB.
>>         PredTerm->removeFromParent();
>>         NewBB->getInstList().insert(NewBB->end(), PredTerm);
>> +      DT->insertEdge(NewBB, BB);
>>         // Create a conditional branch and update PHI nodes.
>>         BranchInst::Create(NewBB, BB, SI->getCondition(), Pred);
>>         CondLHS->setIncomingValue(I, SI->getFalseValue());
>> @@ -2316,6 +2355,7 @@ bool JumpThreadingPass::TryToUnfoldSelec
>>         // The select is now dead.
>>         SI->eraseFromParent();
>>   +      DT->insertEdge(Pred, NewBB);
>>         // Update any other PHI nodes in BB.
>>         for (BasicBlock::iterator BI = BB->begin();
>>              PHINode *Phi = dyn_cast<PHINode>(BI); ++BI)
>> @@ -2393,7 +2433,7 @@ bool JumpThreadingPass::TryToUnfoldSelec
>>         continue;
>>       // Expand the select.
>>       TerminatorInst *Term =
>> -        SplitBlockAndInsertIfThen(SI->getCondition(), SI, false);
>> +        SplitBlockAndInsertIfThen(SI->getCondition(), SI, false, 
>> nullptr, DT);
>>       PHINode *NewPN = PHINode::Create(SI->getType(), 2, "", SI);
>>       NewPN->addIncoming(SI->getTrueValue(), Term->getParent());
>>       NewPN->addIncoming(SI->getFalseValue(), BB);
>> @@ -2485,8 +2525,8 @@ bool JumpThreadingPass::ThreadGuard(Basi
>>     if (!TrueDestIsSafe && !FalseDestIsSafe)
>>       return false;
>>   -  BasicBlock *UnguardedBlock = TrueDestIsSafe ? TrueDest : FalseDest;
>> -  BasicBlock *GuardedBlock = FalseDestIsSafe ? TrueDest : FalseDest;
>> +  BasicBlock *PredUnguardedBlock = TrueDestIsSafe ? TrueDest : 
>> FalseDest;
>> +  BasicBlock *PredGuardedBlock = FalseDestIsSafe ? TrueDest : 
>> FalseDest;
>>       ValueToValueMapTy UnguardedMapping, GuardedMapping;
>>     Instruction *AfterGuard = Guard->getNextNode();
>> @@ -2495,17 +2535,28 @@ bool JumpThreadingPass::ThreadGuard(Basi
>>       return false;
>>     // Duplicate all instructions before the guard and the guard 
>> itself to the
>>     // branch where implication is not proved.
>> -  GuardedBlock = DuplicateInstructionsInSplitBetween(
>> -      BB, GuardedBlock, AfterGuard, GuardedMapping);
>> +  BasicBlock *GuardedBlock = DuplicateInstructionsInSplitBetween(
>> +      BB, PredGuardedBlock, AfterGuard, GuardedMapping);
>>     assert(GuardedBlock && "Could not create the guarded block?");
>>     // Duplicate all instructions before the guard in the unguarded 
>> branch.
>>     // Since we have successfully duplicated the guarded block and 
>> this block
>>     // has fewer instructions, we expect it to succeed.
>> -  UnguardedBlock = DuplicateInstructionsInSplitBetween(BB, 
>> UnguardedBlock,
>> -                                                       Guard, 
>> UnguardedMapping);
>> +  BasicBlock *UnguardedBlock = DuplicateInstructionsInSplitBetween(
>> +      BB, PredUnguardedBlock, Guard, UnguardedMapping);
>>     assert(UnguardedBlock && "Could not create the unguarded block?");
>>     DEBUG(dbgs() << "Moved guard " << *Guard << " to block "
>>                  << GuardedBlock->getName() << "\n");
>> +  // DuplicateInstructionsInSplitBetween inserts a new block, 
>> BB.split, between
>> +  // PredBB and BB. We need to perform two inserts and one delete in 
>> DT for each
>> +  // of the above calls.
>> +  DT->applyUpdates({// Guarded block split.
>> +                    {DominatorTree::Delete, PredGuardedBlock, BB},
>> +                    {DominatorTree::Insert, PredGuardedBlock, 
>> GuardedBlock},
>> +                    {DominatorTree::Insert, GuardedBlock, BB},
>> +                    // Unguarded block split.
>> +                    {DominatorTree::Delete, PredUnguardedBlock, BB},
>> +                    {DominatorTree::Insert, PredUnguardedBlock, 
>> UnguardedBlock},
>> +                    {DominatorTree::Insert, UnguardedBlock, BB}});
>>       // Some instructions before the guard may still have uses. For 
>> them, we need
>>     // to create Phi nodes merging their copies in both guarded and 
>> unguarded
>>
>> Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp
>> URL: 
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=314435&r1=314434&r2=314435&view=diff
>> ============================================================================== 
>>
>> --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original)
>> +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Thu Sep 28 10:24:40 2017
>> @@ -68,7 +68,8 @@ STATISTIC(NumRemoved, "Number of unreach
>>   /// 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);
>>   @@ -95,6 +96,8 @@ bool llvm::ConstantFoldTerminator(BasicB
>>         // Replace the conditional branch with an unconditional one.
>>         Builder.CreateBr(Destination);
>>         BI->eraseFromParent();
>> +      if (DT && OldDest != Destination && OldDest != BB)
>> +        DT->deleteEdge(BB, OldDest);
>>         return true;
>>       }
>>   @@ -165,9 +168,17 @@ bool llvm::ConstantFoldTerminator(BasicB
>>                             createBranchWeights(Weights));
>>           }
>>           // Remove this entry.
>> -        DefaultDest->removePredecessor(SI->getParent());
>> +        BasicBlock *ParentBB = SI->getParent();
>> +        DefaultDest->removePredecessor(ParentBB);
>>           i = SI->removeCase(i);
>>           e = SI->case_end();
>> +        if (DT && DefaultDest != ParentBB) {
>> +          // DefaultDest may still be a successor of a non-default 
>> case.
>> +          if (none_of(successors(ParentBB), [DefaultDest](BasicBlock 
>> *S) {
>> +                return S == DefaultDest;
>> +              }))
>> +            DT->deleteEdge(ParentBB, DefaultDest);
>> +        }
>>           continue;
>>         }
>>   @@ -193,19 +204,29 @@ bool llvm::ConstantFoldTerminator(BasicB
>>         // Insert the new branch.
>>         Builder.CreateBr(TheOnlyDest);
>>         BasicBlock *BB = SI->getParent();
>> +      BasicBlock *TheOnlyDestCheck = TheOnlyDest;
>> +      std::vector<DominatorTree::UpdateType> Updates;
>>           // 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)
>> +        if (Succ == TheOnlyDest) {
>>             TheOnlyDest = nullptr; // Don't modify the first branch 
>> to TheOnlyDest
>> -        else
>> +        } else {
>>             Succ->removePredecessor(BB);
>> +          if (DT && Succ != TheOnlyDestCheck && Succ != BB) {
>> +            DominatorTree::UpdateType UT = {DominatorTree::Delete, 
>> BB, Succ};
>> +            if (std::find(Updates.begin(), Updates.end(), UT) == 
>> Updates.end())
>> +              Updates.push_back(UT);
>> +          }
>> +        }
>>         }
>>           // Delete the old switch.
>>         Value *Cond = SI->getCondition();
>>         SI->eraseFromParent();
>> +      if (DT && !Updates.empty())
>> +        DT->applyUpdates(Updates);
>>         if (DeleteDeadConditions)
>>           RecursivelyDeleteTriviallyDeadInstructions(Cond, TLI);
>>         return true;
>> @@ -253,17 +274,30 @@ bool llvm::ConstantFoldTerminator(BasicB
>>       if (BlockAddress *BA =
>> dyn_cast<BlockAddress>(IBI->getAddress()->stripPointerCasts())) {
>>         BasicBlock *TheOnlyDest = BA->getBasicBlock();
>> +      BasicBlock *TheOnlyDestCheck = TheOnlyDest;
>> +      std::vector<DominatorTree::UpdateType> Updates;
>>         // Insert the new branch.
>>         Builder.CreateBr(TheOnlyDest);
>>           for (unsigned i = 0, e = IBI->getNumDestinations(); i != e; 
>> ++i) {
>> -        if (IBI->getDestination(i) == TheOnlyDest)
>> +        if (IBI->getDestination(i) == TheOnlyDest) {
>>             TheOnlyDest = nullptr;
>> -        else
>> - IBI->getDestination(i)->removePredecessor(IBI->getParent());
>> +        } else {
>> +          BasicBlock *ParentBB = IBI->getParent();
>> +          BasicBlock *DestBB = IBI->getDestination(i);
>> +          DestBB->removePredecessor(ParentBB);
>> +          if (DT && DestBB != TheOnlyDestCheck && DestBB != ParentBB) {
>> +            DominatorTree::UpdateType UT = {DominatorTree::Delete, 
>> ParentBB,
>> +                                            DestBB};
>> +            if (std::find(Updates.begin(), Updates.end(), UT) == 
>> Updates.end())
>> +              Updates.push_back(UT);
>> +          }
>> +        }
>>         }
>>         Value *Address = IBI->getAddress();
>>         IBI->eraseFromParent();
>> +      if (DT && !Updates.empty())
>> +        DT->applyUpdates(Updates);
>>         if (DeleteDeadConditions)
>>           RecursivelyDeleteTriviallyDeadInstructions(Address, TLI);
>>   @@ -553,7 +587,8 @@ bool llvm::SimplifyInstructionsInBlock(B
>>   ///
>>   /// .. and delete the predecessor corresponding to the '1', this 
>> will attempt to
>>   /// recursively fold the and to 0.
>> -void llvm::RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock 
>> *Pred) {
>> +void llvm::RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock 
>> *Pred,
>> +                                        DominatorTree *DT) {
>>     // This only adjusts blocks with PHI nodes.
>>     if (!isa<PHINode>(BB->begin()))
>>       return;
>> @@ -576,6 +611,8 @@ void llvm::RemovePredecessorAndSimplify(
>>       // of the block.
>>       if (PhiIt != OldPhiIt) PhiIt = &BB->front();
>>     }
>> +  if (DT && BB != Pred)
>> +    DT->deleteEdge(Pred, BB);
>>   }
>>     @@ -597,6 +634,23 @@ void llvm::MergeBasicBlockIntoOnlyPred(B
>>     BasicBlock *PredBB = DestBB->getSinglePredecessor();
>>     assert(PredBB && "Block doesn't have a single predecessor!");
>>   +  // Collect all the edges that enter PredBB, discarding edges to 
>> itself and
>> +  // duplicates. These dominator edges will be redirected to DestBB.
>> +  std::vector<DominatorTree::UpdateType> Updates;
>> +  if (DT)
>> +    for (pred_iterator PI = pred_begin(PredBB), E = 
>> pred_end(PredBB); PI != E;
>> +         ++PI) {
>> +      if (*PI == PredBB)
>> +        continue;
>> +      DominatorTree::UpdateType UT = {DominatorTree::Delete, *PI, 
>> PredBB};
>> +      if (std::find(Updates.begin(), Updates.end(), UT) == 
>> Updates.end()) {
>> +        Updates.push_back(UT);
>> +        // DestBB cannot dominate itself.
>> +        if (*PI != DestBB)
>> +          Updates.push_back({DominatorTree::Insert, *PI, DestBB});
>> +      }
>> +    }
>> +
>>     // Zap anything that took the address of DestBB.  Not doing this 
>> will give the
>>     // address an invalid value.
>>     if (DestBB->hasAddressTaken()) {
>> @@ -617,16 +671,25 @@ void llvm::MergeBasicBlockIntoOnlyPred(B
>>       // If the PredBB is the entry block of the function, move 
>> DestBB up to
>>     // become the entry block after we erase PredBB.
>> -  if (PredBB == &DestBB->getParent()->getEntryBlock())
>> +  bool ReplacedEntryBB = false;
>> +  if (PredBB == &DestBB->getParent()->getEntryBlock()) {
>>       DestBB->moveAfter(PredBB);
>> +    ReplacedEntryBB = true;
>> +  }
>>   -  if (DT) {
>> -    BasicBlock *PredBBIDom = 
>> DT->getNode(PredBB)->getIDom()->getBlock();
>> -    DT->changeImmediateDominator(DestBB, PredBBIDom);
>> -    DT->eraseNode(PredBB);
>> +  if (DT && !ReplacedEntryBB) {
>> +    Updates.push_back({DominatorTree::Delete, PredBB, DestBB});
>> +    DT->applyUpdates(Updates);
>>     }
>> +
>>     // Nuke BB.
>>     PredBB->eraseFromParent();
>> +
>> +  // The entry block was removed and there is no external interface 
>> for the
>> +  // dominator tree to be notified of this change. In this 
>> corner-case we
>> +  // recalculate the entire tree.
>> +  if (DT && ReplacedEntryBB)
>> +    DT->recalculate(*(DestBB->getParent()));
>>   }
>>     /// CanMergeValues - Return true if we can choose one of these 
>> values to use
>> @@ -834,7 +897,8 @@ static void redirectValuesFromPredecesso
>>   /// potential side-effect free intrinsics and the branch.  If 
>> possible,
>>   /// eliminate BB by rewriting all the predecessors to branch to the 
>> successor
>>   /// block and return true.  If we can't transform, return false.
>> -bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB) {
>> +bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB,
>> + DominatorTree *DT) {
>>     assert(BB != &BB->getParent()->getEntryBlock() &&
>>            "TryToSimplifyUncondBranchFromEmptyBlock called on entry 
>> block!");
>>   @@ -875,6 +939,20 @@ bool llvm::TryToSimplifyUncondBranchFrom
>>       DEBUG(dbgs() << "Killing Trivial BB: \n" << *BB);
>>   +  // Collect all the edges that enter BB, discarding edges to 
>> itself and
>> +  // duplicates. These dominator edges will be redirected to Succ.
>> +  std::vector<DominatorTree::UpdateType> Updates;
>> +  if (DT)
>> +    for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != 
>> E; ++PI) {
>> +      if (*PI == BB)
>> +        continue;
>> +      DominatorTree::UpdateType UT = {DominatorTree::Delete, *PI, BB};
>> +      if (std::find(Updates.begin(), Updates.end(), UT) == 
>> Updates.end()) {
>> +        Updates.push_back(UT);
>> +        Updates.push_back({DominatorTree::Insert, *PI, Succ});
>> +      }
>> +    }
>> +
>>     if (isa<PHINode>(Succ->begin())) {
>>       // If there is more than one pred of succ, and there are PHI 
>> nodes in
>>       // the successor, then we need to add incoming edges for the 
>> PHI nodes
>> @@ -909,16 +987,27 @@ bool llvm::TryToSimplifyUncondBranchFrom
>>     // add the metadata to the branch instructions in the predecessors.
>>     unsigned LoopMDKind = BB->getContext().getMDKindID("llvm.loop");
>>     Instruction *TI = BB->getTerminator();
>> -  if (TI)
>> +  if (TI) {
>>       if (MDNode *LoopMD = TI->getMetadata(LoopMDKind))
>>         for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI 
>> != E; ++PI) {
>>           BasicBlock *Pred = *PI;
>>           Pred->getTerminator()->setMetadata(LoopMDKind, LoopMD);
>>         }
>> +    // Replace the terminator instruction with unreachable to ensure 
>> the CFG is
>> +    // consistent. This is necessary for dominance to be correctly 
>> calculated.
>> +    new UnreachableInst(BB->getContext(), TI);
>> +    TI->eraseFromParent();
>> +  }
>>       // Everything that jumped to BB now goes to Succ.
>>     BB->replaceAllUsesWith(Succ);
>>     if (!Succ->hasName()) Succ->takeName(BB);
>> +
>> +  if (DT) {
>> +    Updates.push_back({DominatorTree::Delete, BB, Succ});
>> +    DT->applyUpdates(Updates);
>> +  }
>> +
>>     BB->eraseFromParent();              // Delete the old basic block.
>>     return true;
>>   }
>> @@ -1399,13 +1488,19 @@ unsigned llvm::removeAllNonTerminatorAnd
>>   }
>>     unsigned llvm::changeToUnreachable(Instruction *I, bool UseLLVMTrap,
>> -                                   bool PreserveLCSSA) {
>> +                                   bool PreserveLCSSA, DominatorTree 
>> *DT) {
>>     BasicBlock *BB = I->getParent();
>> +  std::vector<DominatorTree::UpdateType> Updates;
>>     // Loop over all of the successors, removing BB's entry from any PHI
>>     // nodes.
>> -  for (BasicBlock *Successor : successors(BB))
>> +  for (BasicBlock *Successor : successors(BB)) {
>>       Successor->removePredecessor(BB, PreserveLCSSA);
>> -
>> +    if (DT && BB != Successor) {
>> +      DominatorTree::UpdateType UT = {DominatorTree::Delete, BB, 
>> Successor};
>> +      if (std::find(Updates.begin(), Updates.end(), UT) == 
>> Updates.end())
>> +        Updates.push_back(UT);
>> +    }
>> +  }
>>     // Insert a call to llvm.trap right before this.  This turns the 
>> undefined
>>     // behavior into a hard fail instead of falling through into 
>> random code.
>>     if (UseLLVMTrap) {
>> @@ -1425,11 +1520,13 @@ unsigned llvm::changeToUnreachable(Instr
>>       BB->getInstList().erase(BBI++);
>>       ++NumInstrsRemoved;
>>     }
>> +  if (DT && !Updates.empty())
>> +    DT->applyUpdates(Updates);
>>     return NumInstrsRemoved;
>>   }
>>     /// changeToCall - Convert the specified invoke into a normal call.
>> -static void changeToCall(InvokeInst *II) {
>> +static void changeToCall(InvokeInst *II, DominatorTree *DT = nullptr) {
>>     SmallVector<Value*, 8> Args(II->arg_begin(), II->arg_end());
>>     SmallVector<OperandBundleDef, 1> OpBundles;
>>     II->getOperandBundlesAsDefs(OpBundles);
>> @@ -1442,11 +1539,16 @@ static void changeToCall(InvokeInst *II)
>>     II->replaceAllUsesWith(NewCall);
>>       // Follow the call by a branch to the normal destination.
>> -  BranchInst::Create(II->getNormalDest(), II);
>> +  BasicBlock *NormalDestBB = II->getNormalDest();
>> +  BranchInst::Create(NormalDestBB, II);
>>       // Update PHI nodes in the unwind destination
>> - II->getUnwindDest()->removePredecessor(II->getParent());
>> +  BasicBlock *BB = II->getParent();
>> +  BasicBlock *UnwindDestBB = II->getUnwindDest();
>> +  UnwindDestBB->removePredecessor(BB);
>>     II->eraseFromParent();
>> +  if (DT && BB != UnwindDestBB && NormalDestBB != UnwindDestBB)
>> +    DT->deleteEdge(BB, UnwindDestBB);
>>   }
>>     BasicBlock *llvm::changeToInvokeAndSplitBasicBlock(CallInst *CI,
>> @@ -1487,7 +1589,8 @@ BasicBlock *llvm::changeToInvokeAndSplit
>>   }
>>     static bool markAliveBlocks(Function &F,
>> -                            SmallPtrSetImpl<BasicBlock*> &Reachable) {
>> +                            SmallPtrSetImpl<BasicBlock *> &Reachable,
>> +                            DominatorTree *DT = nullptr) {
>>       SmallVector<BasicBlock*, 128> Worklist;
>>     BasicBlock *BB = &F.front();
>> @@ -1508,7 +1611,7 @@ static bool markAliveBlocks(Function &F,
>>           if (II->getIntrinsicID() == Intrinsic::assume) {
>>             if (match(II->getArgOperand(0), m_CombineOr(m_Zero(), 
>> m_Undef()))) {
>>               // Don't insert a call to llvm.trap right before the 
>> unreachable.
>> -            changeToUnreachable(II, false);
>> +            changeToUnreachable(II, false, false, DT);
>>               Changed = true;
>>               break;
>>             }
>> @@ -1525,7 +1628,8 @@ static bool markAliveBlocks(Function &F,
>>             // still be useful for widening.
>>             if (match(II->getArgOperand(0), m_Zero()))
>>               if (!isa<UnreachableInst>(II->getNextNode())) {
>> -              changeToUnreachable(II->getNextNode(), 
>> /*UseLLVMTrap=*/ false);
>> +              changeToUnreachable(II->getNextNode(), 
>> /*UseLLVMTrap=*/false,
>> +                                  false, DT);
>>                 Changed = true;
>>                 break;
>>               }
>> @@ -1535,7 +1639,7 @@ static bool markAliveBlocks(Function &F,
>>         if (auto *CI = dyn_cast<CallInst>(&I)) {
>>           Value *Callee = CI->getCalledValue();
>>           if (isa<ConstantPointerNull>(Callee) || 
>> isa<UndefValue>(Callee)) {
>> -          changeToUnreachable(CI, /*UseLLVMTrap=*/false);
>> +          changeToUnreachable(CI, /*UseLLVMTrap=*/false, false, DT);
>>             Changed = true;
>>             break;
>>           }
>> @@ -1545,7 +1649,7 @@ static bool markAliveBlocks(Function &F,
>>             // though.
>>             if (!isa<UnreachableInst>(CI->getNextNode())) {
>>               // Don't insert a call to llvm.trap right before the 
>> unreachable.
>> -            changeToUnreachable(CI->getNextNode(), false);
>> +            changeToUnreachable(CI->getNextNode(), false, false, DT);
>>               Changed = true;
>>             }
>>             break;
>> @@ -1564,7 +1668,7 @@ static bool markAliveBlocks(Function &F,
>>           if (isa<UndefValue>(Ptr) ||
>>               (isa<ConstantPointerNull>(Ptr) &&
>>                SI->getPointerAddressSpace() == 0)) {
>> -          changeToUnreachable(SI, true);
>> +          changeToUnreachable(SI, true, false, DT);
>>             Changed = true;
>>             break;
>>           }
>> @@ -1576,16 +1680,19 @@ static bool markAliveBlocks(Function &F,
>>         // Turn invokes that call 'nounwind' functions into ordinary 
>> calls.
>>         Value *Callee = II->getCalledValue();
>>         if (isa<ConstantPointerNull>(Callee) || 
>> isa<UndefValue>(Callee)) {
>> -        changeToUnreachable(II, true);
>> +        changeToUnreachable(II, true, false, DT);
>>           Changed = true;
>>         } else if (II->doesNotThrow() && 
>> canSimplifyInvokeNoUnwind(&F)) {
>>           if (II->use_empty() && II->onlyReadsMemory()) {
>>             // jump to the normal destination branch.
>> +          BasicBlock *UnwindDestBB = II->getUnwindDest();
>>             BranchInst::Create(II->getNormalDest(), II);
>> - II->getUnwindDest()->removePredecessor(II->getParent());
>> + UnwindDestBB->removePredecessor(II->getParent());
>>             II->eraseFromParent();
>> +          if (DT && BB != UnwindDestBB)
>> +            DT->deleteEdge(BB, UnwindDestBB);
>>           } else
>> -          changeToCall(II);
>> +          changeToCall(II, DT);
>>           Changed = true;
>>         }
>>       } else if (auto *CatchSwitch = 
>> dyn_cast<CatchSwitchInst>(Terminator)) {
>> @@ -1628,7 +1735,7 @@ static bool markAliveBlocks(Function &F,
>>         }
>>       }
>>   -    Changed |= ConstantFoldTerminator(BB, true);
>> +    Changed |= ConstantFoldTerminator(BB, true, nullptr, DT);
>>       for (BasicBlock *Successor : successors(BB))
>>         if (Reachable.insert(Successor).second)
>>           Worklist.push_back(Successor);
>> @@ -1636,11 +1743,11 @@ static bool markAliveBlocks(Function &F,
>>     return Changed;
>>   }
>>   -void llvm::removeUnwindEdge(BasicBlock *BB) {
>> +void llvm::removeUnwindEdge(BasicBlock *BB, DominatorTree *DT) {
>>     TerminatorInst *TI = BB->getTerminator();
>>       if (auto *II = dyn_cast<InvokeInst>(TI)) {
>> -    changeToCall(II);
>> +    changeToCall(II, DT);
>>       return;
>>     }
>>   @@ -1668,15 +1775,19 @@ void llvm::removeUnwindEdge(BasicBlock *
>>     UnwindDest->removePredecessor(BB);
>>     TI->replaceAllUsesWith(NewTI);
>>     TI->eraseFromParent();
>> +  if (DT && BB != UnwindDest)
>> +    DT->deleteEdge(BB, UnwindDest);
>>   }
>>     /// removeUnreachableBlocks - Remove blocks that are not 
>> reachable, even
>>   /// if they are in a dead cycle.  Return true if a change was made, 
>> false
>>   /// otherwise. If `LVI` is passed, this function preserves 
>> LazyValueInfo
>>   /// after modifying the CFG.
>> -bool llvm::removeUnreachableBlocks(Function &F, LazyValueInfo *LVI) {
>> +bool llvm::removeUnreachableBlocks(Function &F, LazyValueInfo *LVI,
>> +                                   DominatorTree *DT) {
>>     SmallPtrSet<BasicBlock*, 16> Reachable;
>> -  bool Changed = markAliveBlocks(F, Reachable);
>> +  bool Changed = markAliveBlocks(F, Reachable, DT);
>> +  std::vector<DominatorTree::UpdateType> Updates;
>>       // If there are unreachable blocks in the CFG...
>>     if (Reachable.size() == F.size())
>> @@ -1685,6 +1796,8 @@ bool llvm::removeUnreachableBlocks(Funct
>>     assert(Reachable.size() < F.size());
>>     NumRemoved += F.size()-Reachable.size();
>>   +  SmallPtrSet<TerminatorInst *, 4> TIRemoved;
>> +
>>     // Loop over all of the basic blocks that are not reachable, 
>> dropping all of
>>     // their internal references...
>>     for (Function::iterator BB = ++F.begin(), E = F.end(); BB != E; 
>> ++BB) {
>> @@ -1692,13 +1805,35 @@ bool llvm::removeUnreachableBlocks(Funct
>>         continue;
>>         for (BasicBlock *Successor : successors(&*BB))
>> -      if (Reachable.count(Successor))
>> +      if (Reachable.count(Successor)) {
>>           Successor->removePredecessor(&*BB);
>> +        if (DT && &*BB != Successor) {
>> +          DominatorTree::UpdateType UT = {DominatorTree::Delete, &*BB,
>> +                                          Successor};
>> +          if (std::find(Updates.begin(), Updates.end(), UT) == 
>> Updates.end())
>> +            Updates.push_back(UT);
>> +        }
>> +      }
>> +
>>       if (LVI)
>>         LVI->eraseBlock(&*BB);
>> +
>> +    TerminatorInst *TI = BB->getTerminator();
>> +    TIRemoved.insert(TI);
>> +    new UnreachableInst(BB->getContext(), TI);
>> +
>>       BB->dropAllReferences();
>>     }
>>   +  // Remove all the terminator instructions after dropping all 
>> references. This
>> +  // keeps the state of the CFG consistent and prevents asserts from 
>> circular
>> +  // use counts in groups of unreachable basic blocks.
>> +  for (TerminatorInst *TI : TIRemoved)
>> +    TI->eraseFromParent();
>> +
>> +  if (DT && !Updates.empty())
>> +    DT->applyUpdates(Updates);
>> +
>>     for (Function::iterator I = ++F.begin(); I != F.end();)
>>       if (!Reachable.count(&*I))
>>         I = F.getBasicBlockList().erase(I);
>>
>> Modified: 
>> llvm/trunk/test/Analysis/LazyValueAnalysis/lvi-after-jumpthreading.ll
>> URL: 
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/LazyValueAnalysis/lvi-after-jumpthreading.ll?rev=314435&r1=314434&r2=314435&view=diff
>> ============================================================================== 
>>
>> --- 
>> llvm/trunk/test/Analysis/LazyValueAnalysis/lvi-after-jumpthreading.ll 
>> (original)
>> +++ 
>> llvm/trunk/test/Analysis/LazyValueAnalysis/lvi-after-jumpthreading.ll 
>> Thu Sep 28 10:24:40 2017
>> @@ -19,10 +19,13 @@ entry:
>>   ; CHECK-NEXT:     ; LatticeVal for: 'i32 %a' is: overdefined
>>   ; CHECK-NEXT:     ; LatticeVal for: 'i32 %length' is: overdefined
>>   ; CHECK-NEXT:     ; LatticeVal for: '  %iv = phi i32 [ 0, %entry ], 
>> [ %iv.next, %backedge ]' in BB: '%backedge' is: constantrange<0, 400>
>> +; CHECK-NEXT:     ; LatticeVal for: '  %iv = phi i32 [ 0, %entry ], 
>> [ %iv.next, %backedge ]' in BB: '%exit' is: constantrange<399, 400>
>>   ; CHECK-NEXT:  %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
>>   ; CHECK-NEXT:     ; LatticeVal for: '  %iv.next = add nsw i32 %iv, 
>> 1' in BB: '%backedge' is: constantrange<1, 401>
>> +; CHECK-NEXT:     ; LatticeVal for: '  %iv.next = add nsw i32 %iv, 
>> 1' in BB: '%exit' is: constantrange<400, 401>
>>   ; CHECK-NEXT:  %iv.next = add nsw i32 %iv, 1
>>   ; CHECK-NEXT:     ; LatticeVal for: '  %cont = icmp slt i32 
>> %iv.next, 400' in BB: '%backedge' is: overdefined
>> +; CHECK-NEXT:     ; LatticeVal for: '  %cont = icmp slt i32 
>> %iv.next, 400' in BB: '%exit' is: constantrange<0, -1>
>>   ; CHECK-NEXT:  %cont = icmp slt i32 %iv.next, 400
>>   ; CHECK-NOT: loop
>>   loop:
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>



More information about the llvm-commits mailing list