diff options
Diffstat (limited to 'lib/Transforms/Scalar/JumpThreading.cpp')
-rw-r--r-- | lib/Transforms/Scalar/JumpThreading.cpp | 93 |
1 files changed, 54 insertions, 39 deletions
diff --git a/lib/Transforms/Scalar/JumpThreading.cpp b/lib/Transforms/Scalar/JumpThreading.cpp index 48de56a02834..b86bf2fefbe5 100644 --- a/lib/Transforms/Scalar/JumpThreading.cpp +++ b/lib/Transforms/Scalar/JumpThreading.cpp @@ -1,9 +1,8 @@ //===- JumpThreading.cpp - Thread control through conditional blocks ------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -24,6 +23,7 @@ #include "llvm/Analysis/BranchProbabilityInfo.h" #include "llvm/Analysis/CFG.h" #include "llvm/Analysis/ConstantFolding.h" +#include "llvm/Analysis/DomTreeUpdater.h" #include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/GuardUtils.h" #include "llvm/Analysis/InstructionSimplify.h" @@ -38,7 +38,6 @@ #include "llvm/IR/ConstantRange.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" -#include "llvm/IR/DomTreeUpdater.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Function.h" #include "llvm/IR/InstrTypes.h" @@ -103,6 +102,12 @@ static cl::opt<bool> PrintLVIAfterJumpThreading( cl::desc("Print the LazyValueInfo cache after JumpThreading"), cl::init(false), cl::Hidden); +static cl::opt<bool> ThreadAcrossLoopHeaders( + "jump-threading-across-loop-headers", + cl::desc("Allow JumpThreading to thread across loop headers, for testing"), + cl::init(false), cl::Hidden); + + namespace { /// This pass performs 'jump threading', which looks at blocks that have @@ -369,7 +374,8 @@ bool JumpThreadingPass::runImpl(Function &F, TargetLibraryInfo *TLI_, if (!DT.isReachableFromEntry(&BB)) Unreachable.insert(&BB); - FindLoopHeaders(F); + if (!ThreadAcrossLoopHeaders) + FindLoopHeaders(F); bool EverChanged = false; bool Changed; @@ -1056,7 +1062,7 @@ bool JumpThreadingPass::ProcessBlock(BasicBlock *BB) { Condition = IB->getAddress()->stripPointerCasts(); Preference = WantBlockAddress; } else { - return false; // Must be an invoke. + return false; // Must be an invoke or callbr. } // Run constant folding to see if we can reduce the condition to a simple @@ -1092,7 +1098,7 @@ bool JumpThreadingPass::ProcessBlock(BasicBlock *BB) { << "' folding undef terminator: " << *BBTerm << '\n'); BranchInst::Create(BBTerm->getSuccessor(BestSucc), BBTerm); BBTerm->eraseFromParent(); - DTU->applyUpdates(Updates); + DTU->applyUpdatesPermissive(Updates); return true; } @@ -1143,7 +1149,9 @@ bool JumpThreadingPass::ProcessBlock(BasicBlock *BB) { unsigned ToKeep = Ret == LazyValueInfo::True ? 0 : 1; BasicBlock *ToRemoveSucc = CondBr->getSuccessor(ToRemove); ToRemoveSucc->removePredecessor(BB, true); - BranchInst::Create(CondBr->getSuccessor(ToKeep), CondBr); + BranchInst *UncondBr = + BranchInst::Create(CondBr->getSuccessor(ToKeep), CondBr); + UncondBr->setDebugLoc(CondBr->getDebugLoc()); CondBr->eraseFromParent(); if (CondCmp->use_empty()) CondCmp->eraseFromParent(); @@ -1160,7 +1168,8 @@ bool JumpThreadingPass::ProcessBlock(BasicBlock *BB) { ConstantInt::getFalse(CondCmp->getType()); ReplaceFoldableUses(CondCmp, CI); } - DTU->deleteEdgeRelaxed(BB, ToRemoveSucc); + DTU->applyUpdatesPermissive( + {{DominatorTree::Delete, BB, ToRemoveSucc}}); return true; } @@ -1172,7 +1181,8 @@ bool JumpThreadingPass::ProcessBlock(BasicBlock *BB) { } if (SwitchInst *SI = dyn_cast<SwitchInst>(BB->getTerminator())) - TryToUnfoldSelect(SI, BB); + if (TryToUnfoldSelect(SI, BB)) + return true; // Check for some cases that are worth simplifying. Right now we want to look // for loads that are used by a switch or by the condition for the branch. If @@ -1245,9 +1255,10 @@ bool JumpThreadingPass::ProcessImpliedCondition(BasicBlock *BB) { BasicBlock *KeepSucc = BI->getSuccessor(*Implication ? 0 : 1); BasicBlock *RemoveSucc = BI->getSuccessor(*Implication ? 1 : 0); RemoveSucc->removePredecessor(BB); - BranchInst::Create(KeepSucc, BI); + BranchInst *UncondBI = BranchInst::Create(KeepSucc, BI); + UncondBI->setDebugLoc(BI->getDebugLoc()); BI->eraseFromParent(); - DTU->deleteEdgeRelaxed(BB, RemoveSucc); + DTU->applyUpdatesPermissive({{DominatorTree::Delete, BB, RemoveSucc}}); return true; } CurrentBB = CurrentPred; @@ -1429,7 +1440,9 @@ bool JumpThreadingPass::SimplifyPartiallyRedundantLoad(LoadInst *LoadI) { // Add all the unavailable predecessors to the PredsToSplit list. for (BasicBlock *P : predecessors(LoadBB)) { // If the predecessor is an indirect goto, we can't split the edge. - if (isa<IndirectBrInst>(P->getTerminator())) + // Same for CallBr. + if (isa<IndirectBrInst>(P->getTerminator()) || + isa<CallBrInst>(P->getTerminator())) return false; if (!AvailablePredSet.count(P)) @@ -1446,11 +1459,11 @@ bool JumpThreadingPass::SimplifyPartiallyRedundantLoad(LoadInst *LoadI) { if (UnavailablePred) { assert(UnavailablePred->getTerminator()->getNumSuccessors() == 1 && "Can't handle critical edge here!"); - LoadInst *NewVal = - new LoadInst(LoadedPtr->DoPHITranslation(LoadBB, UnavailablePred), - LoadI->getName() + ".pr", false, LoadI->getAlignment(), - LoadI->getOrdering(), LoadI->getSyncScopeID(), - UnavailablePred->getTerminator()); + LoadInst *NewVal = new LoadInst( + LoadI->getType(), LoadedPtr->DoPHITranslation(LoadBB, UnavailablePred), + LoadI->getName() + ".pr", false, LoadI->getAlignment(), + LoadI->getOrdering(), LoadI->getSyncScopeID(), + UnavailablePred->getTerminator()); NewVal->setDebugLoc(LoadI->getDebugLoc()); if (AATags) NewVal->setAAMetadata(AATags); @@ -1474,8 +1487,7 @@ bool JumpThreadingPass::SimplifyPartiallyRedundantLoad(LoadInst *LoadI) { for (pred_iterator PI = PB; PI != PE; ++PI) { BasicBlock *P = *PI; AvailablePredsTy::iterator I = - std::lower_bound(AvailablePreds.begin(), AvailablePreds.end(), - std::make_pair(P, (Value*)nullptr)); + llvm::lower_bound(AvailablePreds, std::make_pair(P, (Value *)nullptr)); assert(I != AvailablePreds.end() && I->first == P && "Didn't find entry for predecessor!"); @@ -1601,7 +1613,6 @@ bool JumpThreadingPass::ProcessThreadableEdges(Value *Cond, BasicBlock *BB, Constant *OnlyVal = nullptr; Constant *MultipleVal = (Constant *)(intptr_t)~0ULL; - unsigned PredWithKnownDest = 0; for (const auto &PredValue : PredValues) { BasicBlock *Pred = PredValue.second; if (!SeenPreds.insert(Pred).second) @@ -1638,12 +1649,10 @@ bool JumpThreadingPass::ProcessThreadableEdges(Value *Cond, BasicBlock *BB, OnlyVal = MultipleVal; } - // We know where this predecessor is going. - ++PredWithKnownDest; - // If the predecessor ends with an indirect goto, we can't change its - // destination. - if (isa<IndirectBrInst>(Pred->getTerminator())) + // destination. Same for CallBr. + if (isa<IndirectBrInst>(Pred->getTerminator()) || + isa<CallBrInst>(Pred->getTerminator())) continue; PredToDestList.push_back(std::make_pair(Pred, DestBB)); @@ -1657,7 +1666,7 @@ bool JumpThreadingPass::ProcessThreadableEdges(Value *Cond, BasicBlock *BB, // not thread. By doing so, we do not need to duplicate the current block and // also miss potential opportunities in case we dont/cant duplicate. if (OnlyDest && OnlyDest != MultipleDestSentinel) { - if (PredWithKnownDest == (size_t)pred_size(BB)) { + if (BB->hasNPredecessors(PredToDestList.size())) { bool SeenFirstBranchToOnlyDest = false; std::vector <DominatorTree::UpdateType> Updates; Updates.reserve(BB->getTerminator()->getNumSuccessors() - 1); @@ -1674,7 +1683,7 @@ bool JumpThreadingPass::ProcessThreadableEdges(Value *Cond, BasicBlock *BB, Instruction *Term = BB->getTerminator(); BranchInst::Create(OnlyDest, Term); Term->eraseFromParent(); - DTU->applyUpdates(Updates); + DTU->applyUpdatesPermissive(Updates); // If the condition is now dead due to the removal of the old terminator, // erase it. @@ -1976,8 +1985,14 @@ bool JumpThreadingPass::ThreadEdge(BasicBlock *BB, } BasicBlock::iterator BI = BB->begin(); - for (; PHINode *PN = dyn_cast<PHINode>(BI); ++BI) - ValueMapping[PN] = PN->getIncomingValueForBlock(PredBB); + // Clone the phi nodes of BB into NewBB. The resulting phi nodes are trivial, + // since NewBB only has one predecessor, but SSAUpdater might need to rewrite + // the operand of the cloned phi. + for (; PHINode *PN = dyn_cast<PHINode>(BI); ++BI) { + PHINode *NewPN = PHINode::Create(PN->getType(), 1, PN->getName(), NewBB); + NewPN->addIncoming(PN->getIncomingValueForBlock(PredBB), PredBB); + ValueMapping[PN] = NewPN; + } // Clone the non-phi instructions of BB into NewBB, keeping track of the // mapping and using it to remap operands in the cloned instructions. @@ -2016,9 +2031,9 @@ bool JumpThreadingPass::ThreadEdge(BasicBlock *BB, } // Enqueue required DT updates. - DTU->applyUpdates({{DominatorTree::Insert, NewBB, SuccBB}, - {DominatorTree::Insert, PredBB, NewBB}, - {DominatorTree::Delete, PredBB, BB}}); + DTU->applyUpdatesPermissive({{DominatorTree::Insert, NewBB, SuccBB}, + {DominatorTree::Insert, PredBB, NewBB}, + {DominatorTree::Delete, PredBB, BB}}); // If there were values defined in BB that are used outside the block, then we // now have to update all uses of the value to use either the original value, @@ -2112,7 +2127,7 @@ BasicBlock *JumpThreadingPass::SplitBlockPreds(BasicBlock *BB, BFI->setBlockFreq(NewBB, NewBBFreq.getFrequency()); } - DTU->applyUpdates(Updates); + DTU->applyUpdatesPermissive(Updates); return NewBBs[0]; } @@ -2385,7 +2400,7 @@ bool JumpThreadingPass::DuplicateCondBranchOnPHIIntoPred( // Remove the unconditional branch at the end of the PredBB block. OldPredBranch->eraseFromParent(); - DTU->applyUpdates(Updates); + DTU->applyUpdatesPermissive(Updates); ++NumDupes; return true; @@ -2421,8 +2436,8 @@ void JumpThreadingPass::UnfoldSelectInstr(BasicBlock *Pred, BasicBlock *BB, // The select is now dead. SI->eraseFromParent(); - DTU->applyUpdates({{DominatorTree::Insert, NewBB, BB}, - {DominatorTree::Insert, Pred, NewBB}}); + DTU->applyUpdatesPermissive({{DominatorTree::Insert, NewBB, BB}, + {DominatorTree::Insert, Pred, NewBB}}); // Update any other PHI nodes in BB. for (BasicBlock::iterator BI = BB->begin(); @@ -2599,7 +2614,7 @@ bool JumpThreadingPass::TryToUnfoldSelectInCurrBB(BasicBlock *BB) { Updates.push_back({DominatorTree::Delete, BB, Succ}); Updates.push_back({DominatorTree::Insert, SplitBB, Succ}); } - DTU->applyUpdates(Updates); + DTU->applyUpdatesPermissive(Updates); return true; } return false; |