[PATCH] D75024: [SCCIterator] Check if a SCC is a natural loop.
Stefanos Baziotis via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sun Feb 23 11:31:19 PST 2020
baziotis created this revision.
baziotis added reviewers: Meinersbur, fhahn, lebedev.ri, efriedma.
Herald added subscribers: llvm-commits, dexonsmith.
Herald added a project: LLVM.
- Get LoopInfo for the function.
- Given an SCC, take one random block of it. Then, call `getLoopFor()` with
that block.
If we don't get a loop back, then this SCC is definitely not a loop.
- Otherwise, we compare the size of the SCC with that of the loop and there
are 3 cases:
- They're equal: this SCC is a loop.
- The SCC is smaller: This SCC is not a loop because `getLoopFor()` gives
the innermost loop. So, if this is smaller, it is an SCC inside a loop.
- The SCC is bigger: In that case, we can't decide since let's say the
SCC has blocks A, B, C. And the loop has blocks A, B. But blocks A, B, C
might also make a loop. However, since `getLoopFor()` gives us the
innermost loop, it will give us A, B. So, in that case, use
`getParentLoop()` repeatedly and repeat the procedure for the parent loops.
https://reviews.llvm.org/D75024
Files:
llvm/include/llvm/ADT/SCCIterator.h
Index: llvm/include/llvm/ADT/SCCIterator.h
===================================================================
--- llvm/include/llvm/ADT/SCCIterator.h
+++ llvm/include/llvm/ADT/SCCIterator.h
@@ -130,6 +130,9 @@
/// still contain a loop if the node has an edge back to itself.
bool hasLoop() const;
+ /// Test if the current SCC is a natural loop.
+ bool isNaturalLoop() const;
+
/// This informs the \c scc_iterator that the specified \c Old node
/// has been deleted, and \c New is to be used in its place.
void ReplaceNode(NodeRef Old, NodeRef New) {
@@ -224,6 +227,37 @@
return false;
}
+template <class GraphT, class GT>
+bool scc_iterator<GraphT, GT>::isNaturalLoop() const {
+ assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!");
+
+ // TODO: Somehow get LoopInfo analysis for this graph into a variable LI.
+
+ if (!hasLoop())
+ return false;
+ Loop *L = LI->getLoopFor(CurrentSCC.front());
+ // If any random block in this SCC does not belong to a loop,
+ // then this SCC is definitely not a loop.
+ if (!L)
+ return false;
+ // L is the _innermost_ loop that has a common block with the SCC.
+ // Since a loop is always an SCC, if their number of blocks
+ // are equal, the SCC is a loop - specifically, L. Otherwise, there are 2 cases:
+ // - If the SCC has less blocks, then it is definitely not a loop.
+ // - If it has more, then we can't decide since the SCC can be a parent loop of L.
+ // So, we perform the same test for the parent of L.
+ do {
+ if (L->getNumBlocks() == CurrentSCC.size())
+ return true;
+ if (CurrentSCC.size() < L->getNumBlocks())
+ return false;
+ L = L->getParentLoop();
+ } while (L);
+ // L is nullptr, so we found no loop that matches exactly
+ // the number of blocks of the SCC and so the SCC is not a loop.
+ return false;
+}
+
/// Construct the begin iterator for a deduced graph type T.
template <class T> scc_iterator<T> scc_begin(const T &G) {
return scc_iterator<T>::begin(G);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D75024.246117.patch
Type: text/x-patch
Size: 2020 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200223/cc432e76/attachment.bin>
More information about the llvm-commits
mailing list