Update clang to r339409.
Change-Id: I800772d2d838223be1f6b40d490c4591b937fca2
diff --git a/linux-x64/clang/include/llvm/Analysis/LoopInfoImpl.h b/linux-x64/clang/include/llvm/Analysis/LoopInfoImpl.h
index b3a16b5..9413898 100644
--- a/linux-x64/clang/include/llvm/Analysis/LoopInfoImpl.h
+++ b/linux-x64/clang/include/llvm/Analysis/LoopInfoImpl.h
@@ -82,6 +82,74 @@
return nullptr;
}
+template <class BlockT, class LoopT>
+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)
+ for (BlockT *Predecessor : children<Inverse<BlockT *>>(EB))
+ if (!contains(Predecessor))
+ return false;
+ // All the requirements are met.
+ return true;
+}
+
+template <class BlockT, class LoopT>
+void LoopBase<BlockT, LoopT>::getUniqueExitBlocks(
+ SmallVectorImpl<BlockT *> &ExitBlocks) const {
+ typedef GraphTraits<BlockT *> BlockTraits;
+ typedef GraphTraits<Inverse<BlockT *>> InvBlockTraits;
+
+ 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>
+BlockT *LoopBase<BlockT, LoopT>::getUniqueExitBlock() const {
+ SmallVector<BlockT *, 8> UniqueExitBlocks;
+ getUniqueExitBlocks(UniqueExitBlocks);
+ if (UniqueExitBlocks.size() == 1)
+ return UniqueExitBlocks[0];
+ return nullptr;
+}
+
/// getExitEdges - Return all pairs of (_inside_block_,_outside_block_).
template <class BlockT, class LoopT>
void LoopBase<BlockT, LoopT>::getExitEdges(
@@ -572,8 +640,8 @@
template <typename T>
bool compareVectors(std::vector<T> &BB1, std::vector<T> &BB2) {
- std::sort(BB1.begin(), BB1.end());
- std::sort(BB2.begin(), BB2.end());
+ llvm::sort(BB1.begin(), BB1.end());
+ llvm::sort(BB2.begin(), BB2.end());
return BB1 == BB2;
}
@@ -617,6 +685,15 @@
std::vector<BlockT *> OtherBBs = OtherL->getBlocks();
assert(compareVectors(BBs, OtherBBs) &&
"Mismatched basic blocks in the loops!");
+
+ 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);
+ }) &&
+ "Mismatched basic blocks in BlocksSets!");
}
#endif
@@ -636,6 +713,9 @@
LoopT *L = Entry.second;
assert(Loops.count(L) && "orphaned loop");
assert(L->contains(BB) && "orphaned block");
+ for (LoopT *ChildLoop : *L)
+ assert(!ChildLoop->contains(BB) &&
+ "BBMap should point to the innermost loop containing BB");
}
// Recompute LoopInfo to verify loops structure.