[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