Update prebuilt Clang to r416183b from Android.
https://android.googlesource.com/platform/prebuilts/clang/host/
linux-x86/+/06a71ddac05c22edb2d10b590e1769b3f8619bef
clang 12.0.5 (based on r416183b) from build 7284624.
Change-Id: I277a316abcf47307562d8b748b84870f31a72866
Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
diff --git a/linux-x64/clang/include/llvm/Analysis/LoopInfoImpl.h b/linux-x64/clang/include/llvm/Analysis/LoopInfoImpl.h
index 6ff4837..0730225 100644
--- a/linux-x64/clang/include/llvm/Analysis/LoopInfoImpl.h
+++ b/linux-x64/clang/include/llvm/Analysis/LoopInfoImpl.h
@@ -17,7 +17,6 @@
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SetVector.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/IR/Dominators.h"
@@ -35,7 +34,7 @@
SmallVectorImpl<BlockT *> &ExitingBlocks) const {
assert(!isInvalid() && "Loop not in a valid state!");
for (const auto BB : blocks())
- for (const auto &Succ : children<BlockT *>(BB))
+ for (auto *Succ : children<BlockT *>(BB))
if (!contains(Succ)) {
// Not in current loop? It must be an exit block.
ExitingBlocks.push_back(BB);
@@ -63,12 +62,19 @@
SmallVectorImpl<BlockT *> &ExitBlocks) const {
assert(!isInvalid() && "Loop not in a valid state!");
for (const auto BB : blocks())
- for (const auto &Succ : children<BlockT *>(BB))
+ for (auto *Succ : children<BlockT *>(BB))
if (!contains(Succ))
// Not in current loop? It must be an exit block.
ExitBlocks.push_back(Succ);
}
+template <class BlockT, class LoopT>
+bool LoopBase<BlockT, LoopT>::hasNoExitBlocks() const {
+ SmallVector<BlockT *, 8> ExitBlocks;
+ getExitBlocks(ExitBlocks);
+ return ExitBlocks.empty();
+}
+
/// getExitBlock - If getExitBlocks would return exactly one block,
/// return that block. Otherwise return null.
template <class BlockT, class LoopT>
@@ -85,9 +91,9 @@
bool LoopBase<BlockT, LoopT>::hasDedicatedExits() const {
// Each predecessor of each exit block of a normal loop is contained
// within the loop.
- SmallVector<BlockT *, 4> ExitBlocks;
- getExitBlocks(ExitBlocks);
- for (BlockT *EB : ExitBlocks)
+ SmallVector<BlockT *, 4> UniqueExitBlocks;
+ getUniqueExitBlocks(UniqueExitBlocks);
+ for (BlockT *EB : UniqueExitBlocks)
for (BlockT *Predecessor : children<Inverse<BlockT *>>(EB))
if (!contains(Predecessor))
return false;
@@ -95,49 +101,36 @@
return true;
}
+// Helper function to get unique loop exits. Pred is a predicate pointing to
+// BasicBlocks in a loop which should be considered to find loop exits.
+template <class BlockT, class LoopT, typename PredicateT>
+void getUniqueExitBlocksHelper(const LoopT *L,
+ SmallVectorImpl<BlockT *> &ExitBlocks,
+ PredicateT Pred) {
+ assert(!L->isInvalid() && "Loop not in a valid state!");
+ SmallPtrSet<BlockT *, 32> Visited;
+ auto Filtered = make_filter_range(L->blocks(), Pred);
+ for (BlockT *BB : Filtered)
+ for (BlockT *Successor : children<BlockT *>(BB))
+ if (!L->contains(Successor))
+ if (Visited.insert(Successor).second)
+ ExitBlocks.push_back(Successor);
+}
+
template <class BlockT, class LoopT>
void LoopBase<BlockT, LoopT>::getUniqueExitBlocks(
SmallVectorImpl<BlockT *> &ExitBlocks) const {
- typedef GraphTraits<BlockT *> BlockTraits;
- typedef GraphTraits<Inverse<BlockT *>> InvBlockTraits;
+ getUniqueExitBlocksHelper(this, ExitBlocks,
+ [](const BlockT *BB) { return true; });
+}
- assert(hasDedicatedExits() &&
- "getUniqueExitBlocks assumes the loop has canonical form exits!");
-
- SmallVector<BlockT *, 32> SwitchExitBlocks;
- for (BlockT *Block : this->blocks()) {
- SwitchExitBlocks.clear();
- for (BlockT *Successor : children<BlockT *>(Block)) {
- // If block is inside the loop then it is not an exit block.
- if (contains(Successor))
- continue;
-
- BlockT *FirstPred = *InvBlockTraits::child_begin(Successor);
-
- // If current basic block is this exit block's first predecessor then only
- // insert exit block in to the output ExitBlocks vector. This ensures that
- // same exit block is not inserted twice into ExitBlocks vector.
- if (Block != FirstPred)
- continue;
-
- // If a terminator has more then two successors, for example SwitchInst,
- // then it is possible that there are multiple edges from current block to
- // one exit block.
- if (std::distance(BlockTraits::child_begin(Block),
- BlockTraits::child_end(Block)) <= 2) {
- ExitBlocks.push_back(Successor);
- continue;
- }
-
- // In case of multiple edges from current block to exit block, collect
- // only one edge in ExitBlocks. Use switchExitBlocks to keep track of
- // duplicate edges.
- if (!is_contained(SwitchExitBlocks, Successor)) {
- SwitchExitBlocks.push_back(Successor);
- ExitBlocks.push_back(Successor);
- }
- }
- }
+template <class BlockT, class LoopT>
+void LoopBase<BlockT, LoopT>::getUniqueNonLatchExitBlocks(
+ SmallVectorImpl<BlockT *> &ExitBlocks) const {
+ const BlockT *Latch = getLoopLatch();
+ assert(Latch && "Latch block must exists");
+ getUniqueExitBlocksHelper(this, ExitBlocks,
+ [Latch](const BlockT *BB) { return BB != Latch; });
}
template <class BlockT, class LoopT>
@@ -155,7 +148,7 @@
SmallVectorImpl<Edge> &ExitEdges) const {
assert(!isInvalid() && "Loop not in a valid state!");
for (const auto BB : blocks())
- for (const auto &Succ : children<BlockT *>(BB))
+ for (auto *Succ : children<BlockT *>(BB))
if (!contains(Succ))
// Not in current loop? It must be an exit block.
ExitEdges.emplace_back(BB, Succ);
@@ -213,8 +206,6 @@
}
}
- // Make sure there is only one exit out of the preheader.
- assert(Out && "Header of loop has no predecessors from outside loop?");
return Out;
}
@@ -518,7 +509,7 @@
if (Subloop && Block == Subloop->getHeader()) {
// We reach this point once per subloop after processing all the blocks in
// the subloop.
- if (Subloop->getParentLoop())
+ if (!Subloop->isOutermost())
Subloop->getParentLoop()->getSubLoopsVector().push_back(Subloop);
else
LI->addTopLevelLoop(Subloop);
@@ -684,10 +675,10 @@
const SmallPtrSetImpl<const BlockT *> &BlocksSet = L->getBlocksSet();
const SmallPtrSetImpl<const BlockT *> &OtherBlocksSet = L->getBlocksSet();
assert(BlocksSet.size() == OtherBlocksSet.size() &&
- std::all_of(BlocksSet.begin(), BlocksSet.end(),
- [&OtherBlocksSet](const BlockT *BB) {
- return OtherBlocksSet.count(BB);
- }) &&
+ llvm::all_of(BlocksSet,
+ [&OtherBlocksSet](const BlockT *BB) {
+ return OtherBlocksSet.count(BB);
+ }) &&
"Mismatched basic blocks in BlocksSets!");
}
#endif
@@ -697,7 +688,7 @@
const DomTreeBase<BlockT> &DomTree) const {
DenseSet<const LoopT *> Loops;
for (iterator I = begin(), E = end(); I != E; ++I) {
- assert(!(*I)->getParentLoop() && "Top-level loop has a parent!");
+ assert((*I)->isOutermost() && "Top-level loop has a parent!");
(*I)->verifyLoopNest(&Loops);
}