[PATCH] D83092: DomTree: Add findSiblingOfUncle helper

Nicolai Hähnle via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 24 09:13:50 PDT 2020


nhaehnle updated this revision to Diff 280483.
nhaehnle added a comment.

  v6:
  - rename to climbLhsUntilSiblings and add some explanatory ASCII art
    and comments for why this operation could be interesting


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83092/new/

https://reviews.llvm.org/D83092

Files:
  llvm/include/llvm/Support/GenericDomTree.h
  llvm/lib/Support/GenericDomTree.cpp


Index: llvm/lib/Support/GenericDomTree.cpp
===================================================================
--- llvm/lib/Support/GenericDomTree.cpp
+++ llvm/lib/Support/GenericDomTree.cpp
@@ -214,6 +214,60 @@
   return Dom ? Dom->getBlock() : CfgBlockRef();
 }
 
+/// climbLhsUntilSiblings - Under the assumption that \p B is the sibling
+/// of some ancestor of \p A in the tree, find that ancestor. Also handles
+/// the degenerate case where \p A itself is a sibling of \p B, or
+/// \p A is a descendant of \p B.
+///
+/// Given an edge A -> B in the control flow graph where B is _not_ dominated
+/// by A, this returns either B (if B dominates A) or a sibling of B that
+/// dominates A.
+///
+/// Example 1:
+///
+///        *
+///       / \
+///      R   B
+///      |
+///      *
+///      |
+///      A
+///
+///    --> return R
+///
+/// Example 2:
+///
+///         *
+///        / \
+///       A   B
+///
+///    --> return A
+///
+/// Example 3:
+///
+///         *
+///         |
+///         B
+///         |
+///         *
+///         |
+///         A
+///
+///    --> return B
+const GenericDomTreeNodeBase *GenericDominatorTreeBase::climbLhsUntilSiblings(
+    const GenericDomTreeNodeBase *A, const GenericDomTreeNodeBase *B) const {
+  assert(A && B && "Pointers are not valid");
+
+  // Use level information to go up the tree until the levels match.
+  assert(A->getLevel() >= B->getLevel());
+  while (A->getLevel() > B->getLevel())
+    A = A->IDom;
+
+  assert(A->IDom == B->IDom);
+
+  return A;
+}
+
 /// updateDFSNumbers - Assign In and Out numbers to the nodes while walking
 /// dominator tree in dfs order.
 void GenericDominatorTreeBase::updateDFSNumbers() const {
Index: llvm/include/llvm/Support/GenericDomTree.h
===================================================================
--- llvm/include/llvm/Support/GenericDomTree.h
+++ llvm/include/llvm/Support/GenericDomTree.h
@@ -305,6 +305,10 @@
   CfgBlockRef findNearestCommonDominatorBlock(CfgBlockRef A,
                                               CfgBlockRef B) const;
 
+  const GenericDomTreeNodeBase *
+  climbLhsUntilSiblings(const GenericDomTreeNodeBase *A,
+                        const GenericDomTreeNodeBase *B) const;
+
   void updateDFSNumbers() const;
 
 private:
@@ -495,6 +499,12 @@
     return dom->getBlock();
   }
 
+  const TreeNode *climbLhsUntilSiblings(const TreeNode *A,
+                                        const TreeNode *B) const {
+    return static_cast<const TreeNode *>(
+        GenericDominatorTreeBase::climbLhsUntilSiblings(A, B));
+  }
+
   //===--------------------------------------------------------------------===//
   // API to update (Post)DominatorTree information based on modifications to
   // the CFG...


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D83092.280483.patch
Type: text/x-patch
Size: 2750 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200724/bc0767da/attachment.bin>


More information about the llvm-commits mailing list