[llvm] r347256 - [IR] Add hasNPredecessors, hasNPredecessorsOrMore to BasicBlock
Vedant Kumar via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 19 11:54:27 PST 2018
Author: vedantk
Date: Mon Nov 19 11:54:27 2018
New Revision: 347256
URL: http://llvm.org/viewvc/llvm-project?rev=347256&view=rev
Log:
[IR] Add hasNPredecessors, hasNPredecessorsOrMore to BasicBlock
Add methods to BasicBlock which make it easier to efficiently check
whether a block has N (or more) predecessors.
This can be more efficient than using pred_size(), which is a linear
time operation.
We might consider adding similar methods for successors. I haven't done
so in this patch because succ_size() is already O(1).
With this patch applied, I measured a 0.065% compile-time reduction in
user time for running `opt -O3` on the sqlite3 amalgamation (30 trials).
The change in mergeStoreIntoSuccessor alone saves 45 million linked list
iterations in a stage2 Release build of llc.
See llvm.org/PR39702 for a harder but more general way of achieving
similar results.
Differential Revision: https://reviews.llvm.org/D54686
Modified:
llvm/trunk/include/llvm/ADT/STLExtras.h
llvm/trunk/include/llvm/IR/BasicBlock.h
llvm/trunk/include/llvm/IR/CFG.h
llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp
llvm/trunk/lib/IR/BasicBlock.cpp
llvm/trunk/lib/IR/Value.cpp
llvm/trunk/lib/Transforms/IPO/PartialInlining.cpp
llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
llvm/trunk/lib/Transforms/Utils/Local.cpp
llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
llvm/trunk/lib/Transforms/Vectorize/VPlan.cpp
Modified: llvm/trunk/include/llvm/ADT/STLExtras.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/STLExtras.h?rev=347256&r1=347255&r2=347256&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/STLExtras.h (original)
+++ llvm/trunk/include/llvm/ADT/STLExtras.h Mon Nov 19 11:54:27 2018
@@ -1405,6 +1405,40 @@ auto apply_tuple(F &&f, Tuple &&t) -> de
Indices{});
}
+/// Return true if the sequence [Begin, End) has exactly N items. Runs in O(N)
+/// time. Not meant for use with random-access iterators.
+template <typename IterTy>
+bool hasNItems(
+ IterTy &&Begin, IterTy &&End, unsigned N,
+ typename std::enable_if<
+ !std::is_same<
+ typename std::iterator_traits<typename std::remove_reference<
+ decltype(Begin)>::type>::iterator_category,
+ std::random_access_iterator_tag>::value,
+ void>::type * = nullptr) {
+ for (; N; --N, ++Begin)
+ if (Begin == End)
+ return false; // Too few.
+ return Begin == End;
+}
+
+/// Return true if the sequence [Begin, End) has N or more items. Runs in O(N)
+/// time. Not meant for use with random-access iterators.
+template <typename IterTy>
+bool hasNItemsOrMore(
+ IterTy &&Begin, IterTy &&End, unsigned N,
+ typename std::enable_if<
+ !std::is_same<
+ typename std::iterator_traits<typename std::remove_reference<
+ decltype(Begin)>::type>::iterator_category,
+ std::random_access_iterator_tag>::value,
+ void>::type * = nullptr) {
+ for (; N; --N, ++Begin)
+ if (Begin == End)
+ return false; // Too few.
+ return true;
+}
+
} // end namespace llvm
#endif // LLVM_ADT_STLEXTRAS_H
Modified: llvm/trunk/include/llvm/IR/BasicBlock.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/BasicBlock.h?rev=347256&r1=347255&r2=347256&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/BasicBlock.h (original)
+++ llvm/trunk/include/llvm/IR/BasicBlock.h Mon Nov 19 11:54:27 2018
@@ -237,6 +237,12 @@ public:
static_cast<const BasicBlock *>(this)->getUniquePredecessor());
}
+ /// Return true if this block has exactly N predecessors.
+ bool hasNPredecessors(unsigned N) const;
+
+ /// Return true if this block has N predecessors or more.
+ bool hasNPredecessorsOrMore(unsigned N) const;
+
/// Return the successor of this block if it has a single successor.
/// Otherwise return a null pointer.
///
Modified: llvm/trunk/include/llvm/IR/CFG.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/CFG.h?rev=347256&r1=347255&r2=347256&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/CFG.h (original)
+++ llvm/trunk/include/llvm/IR/CFG.h Mon Nov 19 11:54:27 2018
@@ -117,6 +117,8 @@ inline const_pred_iterator pred_end(cons
inline bool pred_empty(const BasicBlock *BB) {
return pred_begin(BB) == pred_end(BB);
}
+/// Get the number of predecessors of \p BB. This is a linear time operation.
+/// Use \ref BasicBlock::hasNPredecessors() or hasNPredecessorsOrMore if able.
inline unsigned pred_size(const BasicBlock *BB) {
return std::distance(pred_begin(BB), pred_end(BB));
}
Modified: llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp?rev=347256&r1=347255&r2=347256&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp (original)
+++ llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp Mon Nov 19 11:54:27 2018
@@ -1022,7 +1022,7 @@ void MemorySSAUpdater::wireOldPredecesso
MemoryPhi *Phi = MSSA->getMemoryAccess(Old);
if (!Phi)
return;
- if (pred_size(Old) == 1) {
+ if (Old->hasNPredecessors(1)) {
assert(pred_size(New) == Preds.size() &&
"Should have moved all predecessors.");
MSSA->moveTo(Phi, New, MemorySSA::Beginning);
Modified: llvm/trunk/lib/IR/BasicBlock.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/BasicBlock.cpp?rev=347256&r1=347255&r2=347256&view=diff
==============================================================================
--- llvm/trunk/lib/IR/BasicBlock.cpp (original)
+++ llvm/trunk/lib/IR/BasicBlock.cpp Mon Nov 19 11:54:27 2018
@@ -260,6 +260,14 @@ const BasicBlock *BasicBlock::getUniqueP
return PredBB;
}
+bool BasicBlock::hasNPredecessors(unsigned N) const {
+ return hasNItems(pred_begin(this), pred_end(this), N);
+}
+
+bool BasicBlock::hasNPredecessorsOrMore(unsigned N) const {
+ return hasNItemsOrMore(pred_begin(this), pred_end(this), N);
+}
+
const BasicBlock *BasicBlock::getSingleSuccessor() const {
succ_const_iterator SI = succ_begin(this), E = succ_end(this);
if (SI == E) return nullptr; // no successors
Modified: llvm/trunk/lib/IR/Value.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Value.cpp?rev=347256&r1=347255&r2=347256&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Value.cpp (original)
+++ llvm/trunk/lib/IR/Value.cpp Mon Nov 19 11:54:27 2018
@@ -130,20 +130,11 @@ void Value::destroyValueName() {
}
bool Value::hasNUses(unsigned N) const {
- const_use_iterator UI = use_begin(), E = use_end();
-
- for (; N; --N, ++UI)
- if (UI == E) return false; // Too few.
- return UI == E;
+ return hasNItems(use_begin(), use_end(), N);
}
bool Value::hasNUsesOrMore(unsigned N) const {
- const_use_iterator UI = use_begin(), E = use_end();
-
- for (; N; --N, ++UI)
- if (UI == E) return false; // Too few.
-
- return true;
+ return hasNItemsOrMore(use_begin(), use_end(), N);
}
bool Value::isUsedInBasicBlock(const BasicBlock *BB) const {
Modified: llvm/trunk/lib/Transforms/IPO/PartialInlining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/PartialInlining.cpp?rev=347256&r1=347255&r2=347256&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/PartialInlining.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/PartialInlining.cpp Mon Nov 19 11:54:27 2018
@@ -403,7 +403,7 @@ PartialInlinerImpl::computeOutliningCold
auto IsSingleEntry = [](SmallVectorImpl<BasicBlock *> &BlockList) {
BasicBlock *Dom = BlockList.front();
- return BlockList.size() > 1 && pred_size(Dom) == 1;
+ return BlockList.size() > 1 && Dom->hasNPredecessors(1);
};
auto IsSingleExit =
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp?rev=347256&r1=347255&r2=347256&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp Mon Nov 19 11:54:27 2018
@@ -1526,7 +1526,7 @@ bool InstCombiner::mergeStoreIntoSuccess
// Check if the successor block has exactly 2 incoming edges.
BasicBlock *StoreBB = SI.getParent();
BasicBlock *DestBB = StoreBB->getTerminator()->getSuccessor(0);
- if (pred_size(DestBB) != 2)
+ if (!DestBB->hasNPredecessors(2))
return false;
// Capture the other block (the block that doesn't contain our store).
Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=347256&r1=347255&r2=347256&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/Local.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/Local.cpp Mon Nov 19 11:54:27 2018
@@ -682,10 +682,9 @@ void llvm::MergeBasicBlockIntoOnlyPred(B
// DTU updates: Collect all the edges that enter
// PredBB. These dominator edges will be redirected to DestBB.
- std::vector <DominatorTree::UpdateType> Updates;
+ SmallVector<DominatorTree::UpdateType, 32> Updates;
if (DTU) {
- Updates.reserve(1 + (2 * pred_size(PredBB)));
Updates.push_back({DominatorTree::Delete, PredBB, DestBB});
for (auto I = pred_begin(PredBB), E = pred_end(PredBB); I != E; ++I) {
Updates.push_back({DominatorTree::Delete, *I, PredBB});
@@ -989,9 +988,8 @@ bool llvm::TryToSimplifyUncondBranchFrom
LLVM_DEBUG(dbgs() << "Killing Trivial BB: \n" << *BB);
- std::vector<DominatorTree::UpdateType> Updates;
+ SmallVector<DominatorTree::UpdateType, 32> Updates;
if (DTU) {
- Updates.reserve(1 + (2 * pred_size(BB)));
Updates.push_back({DominatorTree::Delete, BB, Succ});
// All predecessors of BB will be moved to Succ.
for (auto I = pred_begin(BB), E = pred_end(BB); I != E; ++I) {
Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=347256&r1=347255&r2=347256&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Mon Nov 19 11:54:27 2018
@@ -693,7 +693,7 @@ Value *SimplifyCFGOpt::isValueEqualityCo
if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
// Do not permit merging of large switch instructions into their
// predecessors unless there is only one predecessor.
- if (SI->getNumSuccessors() * pred_size(SI->getParent()) <= 128)
+ if (!SI->getParent()->hasNPredecessorsOrMore(128 / SI->getNumSuccessors()))
CV = SI->getCondition();
} else if (BranchInst *BI = dyn_cast<BranchInst>(TI))
if (BI->isConditional() && BI->getCondition()->hasOneUse())
@@ -2890,7 +2890,7 @@ static Value *ensureValueAvailableInSucc
if (!AlternativeV)
break;
- assert(pred_size(Succ) == 2);
+ assert(Succ->hasNPredecessors(2));
auto PredI = pred_begin(Succ);
BasicBlock *OtherPredBB = *PredI == BB ? *++PredI : *PredI;
if (PHI->getIncomingValueForBlock(OtherPredBB) == AlternativeV)
@@ -5774,7 +5774,7 @@ bool SimplifyCFGOpt::SimplifyUncondBranc
// backedge, so we can eliminate BB.
bool NeedCanonicalLoop =
Options.NeedCanonicalLoop &&
- (LoopHeaders && pred_size(BB) > 1 &&
+ (LoopHeaders && BB->hasNPredecessorsOrMore(2) &&
(LoopHeaders->count(BB) || LoopHeaders->count(Succ)));
BasicBlock::iterator I = BB->getFirstNonPHIOrDbg()->getIterator();
if (I->isTerminator() && BB != &BB->getParent()->getEntryBlock() &&
Modified: llvm/trunk/lib/Transforms/Vectorize/VPlan.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Vectorize/VPlan.cpp?rev=347256&r1=347255&r2=347256&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Vectorize/VPlan.cpp (original)
+++ llvm/trunk/lib/Transforms/Vectorize/VPlan.cpp Mon Nov 19 11:54:27 2018
@@ -468,7 +468,7 @@ void VPlan::updateDominatorTree(Dominato
"One successor of a basic block does not lead to the other.");
assert(InterimSucc->getSinglePredecessor() &&
"Interim successor has more than one predecessor.");
- assert(pred_size(PostDomSucc) == 2 &&
+ assert(PostDomSucc->hasNPredecessors(2) &&
"PostDom successor has more than two predecessors.");
DT->addNewBlock(InterimSucc, BB);
DT->addNewBlock(PostDomSucc, BB);
More information about the llvm-commits
mailing list