CFGDiff: Simplify and generalize over all graph types
authorDavid Blaikie <dblaikie@gmail.com>
Wed, 11 Mar 2020 22:56:24 +0000 (15:56 -0700)
committerDavid Blaikie <dblaikie@gmail.com>
Thu, 12 Mar 2020 17:45:45 +0000 (10:45 -0700)
Use GraphTraits in the implementation of the GraphDiff's own GraphTraits
so GraphDiff can be used across all graph types that provide
GraphTraits.

Also use partial template specializations to make the traits a bit more
compact.

Reviewers: asbirlea

Differential Revision: https://reviews.llvm.org/D76034

llvm/include/llvm/IR/CFGDiff.h

index 57b62dd..0b128ff 100644 (file)
@@ -39,7 +39,7 @@
 // templated / parametrized on using succ_iterator/pred_iterator and false/true
 // for the InverseEdge.
 
-// CFGViewSuccessors and CFGViewPredecessors, both can be parametrized to
+// CFGViewChildren and CFGViewPredecessors, both can be parametrized to
 // consider the graph inverted or not (i.e. InverseGraph). Successors
 // implicitly has InverseEdge = false and Predecessors implicitly has
 // InverseEdge = true (see calls to GraphDiff methods in there). The GraphTraits
 // - GraphDiff<BasicBlock *> is equivalent to InverseGraph = false
 // - GraphDiff<Inverse<BasicBlock *>> is equivalent to InverseGraph = true
 // - second pair item is BasicBlock *, then InverseEdge = false (so it inherits
-// from CFGViewSuccessors).
+// from CFGViewChildren).
 // - second pair item is Inverse<BasicBlock *>, then InverseEdge = true (so it
 // inherits from CFGViewPredecessors).
 
 // The 4 GraphTraits are as follows:
 // 1. std::pair<const GraphDiff<BasicBlock *> *, BasicBlock *>> :
-//        CFGViewSuccessors<false>
+//        CFGViewChildren<false>
 // Regular CFG, children means successors, InverseGraph = false,
 // InverseEdge = false.
 // 2. std::pair<const GraphDiff<Inverse<BasicBlock *>> *, BasicBlock *>> :
-//        CFGViewSuccessors<true>
+//        CFGViewChildren<true>
 // Reverse the graph, get successors but reverse-apply updates,
 // InverseGraph = true, InverseEdge = false.
 // 3. std::pair<const GraphDiff<BasicBlock *> *, Inverse<BasicBlock *>>> :
@@ -155,23 +155,27 @@ public:
 #endif
 };
 
-template <bool InverseGraph = false> struct CFGViewSuccessors {
-  using DataRef = const GraphDiff<BasicBlock *, InverseGraph> *;
+template <typename GraphT, bool InverseGraph = false, bool InverseEdge = false,
+          typename GT = GraphTraits<GraphT>>
+struct CFGViewChildren {
+  using DataRef = const GraphDiff<typename GT::NodeRef, InverseGraph> *;
+  using RawNodeRef = typename GT::NodeRef;
   using NodeRef = std::pair<DataRef, BasicBlock *>;
 
   using ExistingChildIterator =
-      WrappedPairNodeDataIterator<succ_iterator, NodeRef, DataRef>;
+      WrappedPairNodeDataIterator<typename GT::ChildIteratorType, NodeRef,
+                                  DataRef>;
   struct DeletedEdgesFilter {
-    BasicBlock *BB;
-    DeletedEdgesFilter(BasicBlock *BB) : BB(BB){};
+    RawNodeRef BB;
+    DeletedEdgesFilter(RawNodeRef BB) : BB(BB){};
     bool operator()(NodeRef N) const {
-      return !N.first->ignoreChild(BB, N.second, false);
+      return !N.first->ignoreChild(BB, N.second, InverseEdge);
     }
   };
   using FilterExistingChildrenIterator =
       filter_iterator<ExistingChildIterator, DeletedEdgesFilter>;
 
-  using vec_iterator = SmallVectorImpl<BasicBlock *>::const_iterator;
+  using vec_iterator = typename SmallVectorImpl<RawNodeRef>::const_iterator;
   using AddNewChildrenIterator =
       WrappedPairNodeDataIterator<vec_iterator, NodeRef, DataRef>;
   using ChildIteratorType =
@@ -179,11 +183,11 @@ template <bool InverseGraph = false> struct CFGViewSuccessors {
                       AddNewChildrenIterator>;
 
   static ChildIteratorType child_begin(NodeRef N) {
-    auto InsertVec = N.first->getAddedChildren(N.second, false);
+    auto InsertVec = N.first->getAddedChildren(N.second, InverseEdge);
     // filter iterator init:
     auto firstit = make_filter_range(
-        make_range<ExistingChildIterator>({succ_begin(N.second), N.first},
-                                          {succ_end(N.second), N.first}),
+        make_range<ExistingChildIterator>({GT::child_begin(N.second), N.first},
+                                          {GT::child_end(N.second), N.first}),
         DeletedEdgesFilter(N.second));
     // new inserts iterator init:
     auto secondit = make_range<AddNewChildrenIterator>(
@@ -194,11 +198,11 @@ template <bool InverseGraph = false> struct CFGViewSuccessors {
   }
 
   static ChildIteratorType child_end(NodeRef N) {
-    auto InsertVec = N.first->getAddedChildren(N.second, false);
+    auto InsertVec = N.first->getAddedChildren(N.second, InverseEdge);
     // filter iterator init:
     auto firstit = make_filter_range(
-        make_range<ExistingChildIterator>({succ_end(N.second), N.first},
-                                          {succ_end(N.second), N.first}),
+        make_range<ExistingChildIterator>({GT::child_end(N.second), N.first},
+                                          {GT::child_end(N.second), N.first}),
         DeletedEdgesFilter(N.second));
     // new inserts iterator init:
     auto secondit = make_range<AddNewChildrenIterator>(
@@ -209,76 +213,12 @@ template <bool InverseGraph = false> struct CFGViewSuccessors {
   }
 };
 
-template <bool InverseGraph = false> struct CFGViewPredecessors {
-  using DataRef = const GraphDiff<BasicBlock *, InverseGraph> *;
-  using NodeRef = std::pair<DataRef, BasicBlock *>;
-
-  using ExistingChildIterator =
-      WrappedPairNodeDataIterator<pred_iterator, NodeRef, DataRef>;
-  struct DeletedEdgesFilter {
-    BasicBlock *BB;
-    DeletedEdgesFilter(BasicBlock *BB) : BB(BB){};
-    bool operator()(NodeRef N) const {
-      return !N.first->ignoreChild(BB, N.second, true);
-    }
-  };
-  using FilterExistingChildrenIterator =
-      filter_iterator<ExistingChildIterator, DeletedEdgesFilter>;
-
-  using vec_iterator = SmallVectorImpl<BasicBlock *>::const_iterator;
-  using AddNewChildrenIterator =
-      WrappedPairNodeDataIterator<vec_iterator, NodeRef, DataRef>;
-  using ChildIteratorType =
-      concat_iterator<NodeRef, FilterExistingChildrenIterator,
-                      AddNewChildrenIterator>;
-
-  static ChildIteratorType child_begin(NodeRef N) {
-    auto InsertVec = N.first->getAddedChildren(N.second, true);
-    // filter iterator init:
-    auto firstit = make_filter_range(
-        make_range<ExistingChildIterator>({pred_begin(N.second), N.first},
-                                          {pred_end(N.second), N.first}),
-        DeletedEdgesFilter(N.second));
-    // new inserts iterator init:
-    auto secondit = make_range<AddNewChildrenIterator>(
-        {InsertVec.begin(), N.first}, {InsertVec.end(), N.first});
-
-    return concat_iterator<NodeRef, FilterExistingChildrenIterator,
-                           AddNewChildrenIterator>(firstit, secondit);
-  }
-
-  static ChildIteratorType child_end(NodeRef N) {
-    auto InsertVec = N.first->getAddedChildren(N.second, true);
-    // filter iterator init:
-    auto firstit = make_filter_range(
-        make_range<ExistingChildIterator>({pred_end(N.second), N.first},
-                                          {pred_end(N.second), N.first}),
-        DeletedEdgesFilter(N.second));
-    // new inserts iterator init:
-    auto secondit = make_range<AddNewChildrenIterator>(
-        {InsertVec.end(), N.first}, {InsertVec.end(), N.first});
-
-    return concat_iterator<NodeRef, FilterExistingChildrenIterator,
-                           AddNewChildrenIterator>(firstit, secondit);
-  }
-};
-
-template <>
-struct GraphTraits<
-    std::pair<const GraphDiff<BasicBlock *, false> *, BasicBlock *>>
-    : CFGViewSuccessors<false> {};
-template <>
-struct GraphTraits<
-    std::pair<const GraphDiff<BasicBlock *, true> *, BasicBlock *>>
-    : CFGViewSuccessors<true> {};
-template <>
-struct GraphTraits<
-    std::pair<const GraphDiff<BasicBlock *, false> *, Inverse<BasicBlock *>>>
-    : CFGViewPredecessors<false> {};
-template <>
-struct GraphTraits<
-    std::pair<const GraphDiff<BasicBlock *, true> *, Inverse<BasicBlock *>>>
-    : CFGViewPredecessors<true> {};
+template <typename T, bool B>
+struct GraphTraits<std::pair<const GraphDiff<T, B> *, T>>
+    : CFGViewChildren<T, B> {};
+template <typename T, bool B>
+struct GraphTraits<std::pair<const GraphDiff<T, B> *, Inverse<T>>>
+    : CFGViewChildren<Inverse<T>, B, true> {};
 } // end namespace llvm
 
 #endif // LLVM_IR_CFGDIFF_H