llvm.org GIT mirror llvm / 94a229e
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@347256 91177308-0d34-0410-b5e6-96231b3b80d8 Vedant Kumar 1 year, 9 months ago
11 changed file(s) with 61 addition(s) and 22 deletion(s). Raw diff Collapse all Expand all
14041404 Indices{});
14051405 }
14061406
1407 /// Return true if the sequence [Begin, End) has exactly N items. Runs in O(N)
1408 /// time. Not meant for use with random-access iterators.
1409 template
1410 bool hasNItems(
1411 IterTy &&Begin, IterTy &&End, unsigned N,
1412 typename std::enable_if<
1413 !std::is_same<
1414 typename std::iterator_traits
1415 decltype(Begin)>::type>::iterator_category,
1416 std::random_access_iterator_tag>::value,
1417 void>::type * = nullptr) {
1418 for (; N; --N, ++Begin)
1419 if (Begin == End)
1420 return false; // Too few.
1421 return Begin == End;
1422 }
1423
1424 /// Return true if the sequence [Begin, End) has N or more items. Runs in O(N)
1425 /// time. Not meant for use with random-access iterators.
1426 template
1427 bool hasNItemsOrMore(
1428 IterTy &&Begin, IterTy &&End, unsigned N,
1429 typename std::enable_if<
1430 !std::is_same<
1431 typename std::iterator_traits
1432 decltype(Begin)>::type>::iterator_category,
1433 std::random_access_iterator_tag>::value,
1434 void>::type * = nullptr) {
1435 for (; N; --N, ++Begin)
1436 if (Begin == End)
1437 return false; // Too few.
1438 return true;
1439 }
1440
14071441 } // end namespace llvm
14081442
14091443 #endif // LLVM_ADT_STLEXTRAS_H
236236 static_cast(this)->getUniquePredecessor());
237237 }
238238
239 /// Return true if this block has exactly N predecessors.
240 bool hasNPredecessors(unsigned N) const;
241
242 /// Return true if this block has N predecessors or more.
243 bool hasNPredecessorsOrMore(unsigned N) const;
244
239245 /// Return the successor of this block if it has a single successor.
240246 /// Otherwise return a null pointer.
241247 ///
116116 inline bool pred_empty(const BasicBlock *BB) {
117117 return pred_begin(BB) == pred_end(BB);
118118 }
119 /// Get the number of predecessors of \p BB. This is a linear time operation.
120 /// Use \ref BasicBlock::hasNPredecessors() or hasNPredecessorsOrMore if able.
119121 inline unsigned pred_size(const BasicBlock *BB) {
120122 return std::distance(pred_begin(BB), pred_end(BB));
121123 }
10211021 MemoryPhi *Phi = MSSA->getMemoryAccess(Old);
10221022 if (!Phi)
10231023 return;
1024 if (pred_size(Old) == 1) {
1024 if (Old->hasNPredecessors(1)) {
10251025 assert(pred_size(New) == Preds.size() &&
10261026 "Should have moved all predecessors.");
10271027 MSSA->moveTo(Phi, New, MemorySSA::Beginning);
259259 return PredBB;
260260 }
261261
262 bool BasicBlock::hasNPredecessors(unsigned N) const {
263 return hasNItems(pred_begin(this), pred_end(this), N);
264 }
265
266 bool BasicBlock::hasNPredecessorsOrMore(unsigned N) const {
267 return hasNItemsOrMore(pred_begin(this), pred_end(this), N);
268 }
269
262270 const BasicBlock *BasicBlock::getSingleSuccessor() const {
263271 succ_const_iterator SI = succ_begin(this), E = succ_end(this);
264272 if (SI == E) return nullptr; // no successors
129129 }
130130
131131 bool Value::hasNUses(unsigned N) const {
132 const_use_iterator UI = use_begin(), E = use_end();
133
134 for (; N; --N, ++UI)
135 if (UI == E) return false; // Too few.
136 return UI == E;
132 return hasNItems(use_begin(), use_end(), N);
137133 }
138134
139135 bool Value::hasNUsesOrMore(unsigned N) const {
140 const_use_iterator UI = use_begin(), E = use_end();
141
142 for (; N; --N, ++UI)
143 if (UI == E) return false; // Too few.
144
145 return true;
136 return hasNItemsOrMore(use_begin(), use_end(), N);
146137 }
147138
148139 bool Value::isUsedInBasicBlock(const BasicBlock *BB) const {
402402
403403 auto IsSingleEntry = [](SmallVectorImpl &BlockList) {
404404 BasicBlock *Dom = BlockList.front();
405 return BlockList.size() > 1 && pred_size(Dom) == 1;
405 return BlockList.size() > 1 && Dom->hasNPredecessors(1);
406406 };
407407
408408 auto IsSingleExit =
15251525 // Check if the successor block has exactly 2 incoming edges.
15261526 BasicBlock *StoreBB = SI.getParent();
15271527 BasicBlock *DestBB = StoreBB->getTerminator()->getSuccessor(0);
1528 if (pred_size(DestBB) != 2)
1528 if (!DestBB->hasNPredecessors(2))
15291529 return false;
15301530
15311531 // Capture the other block (the block that doesn't contain our store).
681681
682682 // DTU updates: Collect all the edges that enter
683683 // PredBB. These dominator edges will be redirected to DestBB.
684 std::vector > Updates;
684 SmallVector> Updates;
685685
686686 if (DTU) {
687 Updates.reserve(1 + (2 * pred_size(PredBB)));
688687 Updates.push_back({DominatorTree::Delete, PredBB, DestBB});
689688 for (auto I = pred_begin(PredBB), E = pred_end(PredBB); I != E; ++I) {
690689 Updates.push_back({DominatorTree::Delete, *I, PredBB});
988987
989988 LLVM_DEBUG(dbgs() << "Killing Trivial BB: \n" << *BB);
990989
991 std::vector> Updates;
990 SmallVector> Updates;
992991 if (DTU) {
993 Updates.reserve(1 + (2 * pred_size(BB)));
994992 Updates.push_back({DominatorTree::Delete, BB, Succ});
995993 // All predecessors of BB will be moved to Succ.
996994 for (auto I = pred_begin(BB), E = pred_end(BB); I != E; ++I) {
692692 if (SwitchInst *SI = dyn_cast(TI)) {
693693 // Do not permit merging of large switch instructions into their
694694 // predecessors unless there is only one predecessor.
695 if (SI->getNumSuccessors() * pred_size(SI->getParent()) <= 128)
695 if (!SI->getParent()->hasNPredecessorsOrMore(128 / SI->getNumSuccessors()))
696696 CV = SI->getCondition();
697697 } else if (BranchInst *BI = dyn_cast(TI))
698698 if (BI->isConditional() && BI->getCondition()->hasOneUse())
28892889 if (!AlternativeV)
28902890 break;
28912891
2892 assert(pred_size(Succ) == 2);
2892 assert(Succ->hasNPredecessors(2));
28932893 auto PredI = pred_begin(Succ);
28942894 BasicBlock *OtherPredBB = *PredI == BB ? *++PredI : *PredI;
28952895 if (PHI->getIncomingValueForBlock(OtherPredBB) == AlternativeV)
57735773 // backedge, so we can eliminate BB.
57745774 bool NeedCanonicalLoop =
57755775 Options.NeedCanonicalLoop &&
5776 (LoopHeaders && pred_size(BB) > 1 &&
5776 (LoopHeaders && BB->hasNPredecessorsOrMore(2) &&
57775777 (LoopHeaders->count(BB) || LoopHeaders->count(Succ)));
57785778 BasicBlock::iterator I = BB->getFirstNonPHIOrDbg()->getIterator();
57795779 if (I->isTerminator() && BB != &BB->getParent()->getEntryBlock() &&
467467 "One successor of a basic block does not lead to the other.");
468468 assert(InterimSucc->getSinglePredecessor() &&
469469 "Interim successor has more than one predecessor.");
470 assert(pred_size(PostDomSucc) == 2 &&
470 assert(PostDomSucc->hasNPredecessors(2) &&
471471 "PostDom successor has more than two predecessors.");
472472 DT->addNewBlock(InterimSucc, BB);
473473 DT->addNewBlock(PostDomSucc, BB);