Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:05

0001 //===- llvm/ADT/GraphTraits.h - Graph traits template -----------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 ///
0009 /// \file
0010 /// This file defines the little GraphTraits<X> template class that should be
0011 /// specialized by classes that want to be iteratable by generic graph
0012 /// iterators.
0013 ///
0014 /// This file also defines the marker class Inverse that is used to iterate over
0015 /// graphs in a graph defined, inverse ordering...
0016 ///
0017 //===----------------------------------------------------------------------===//
0018 
0019 #ifndef LLVM_ADT_GRAPHTRAITS_H
0020 #define LLVM_ADT_GRAPHTRAITS_H
0021 
0022 #include "llvm/ADT/STLExtras.h"
0023 #include "llvm/ADT/iterator_range.h"
0024 
0025 namespace llvm {
0026 
0027 // GraphTraits - This class should be specialized by different graph types...
0028 // which is why the default version is empty.
0029 //
0030 // This template evolved from supporting `BasicBlock` to also later supporting
0031 // more complex types (e.g. CFG and DomTree).
0032 //
0033 // GraphTraits can be used to create a view over a graph interpreting it
0034 // differently without requiring a copy of the original graph. This could
0035 // be achieved by carrying more data in NodeRef. See LoopBodyTraits for one
0036 // example.
0037 template<class GraphType>
0038 struct GraphTraits {
0039   // Elements to provide:
0040 
0041   // typedef NodeRef           - Type of Node token in the graph, which should
0042   //                             be cheap to copy.
0043   // typedef ChildIteratorType - Type used to iterate over children in graph,
0044   //                             dereference to a NodeRef.
0045 
0046   // static NodeRef getEntryNode(const GraphType &)
0047   //    Return the entry node of the graph
0048 
0049   // static ChildIteratorType child_begin(NodeRef)
0050   // static ChildIteratorType child_end  (NodeRef)
0051   //    Return iterators that point to the beginning and ending of the child
0052   //    node list for the specified node.
0053 
0054   // typedef  ...iterator nodes_iterator; - dereference to a NodeRef
0055   // static nodes_iterator nodes_begin(GraphType *G)
0056   // static nodes_iterator nodes_end  (GraphType *G)
0057   //    nodes_iterator/begin/end - Allow iteration over all nodes in the graph
0058 
0059   // typedef EdgeRef           - Type of Edge token in the graph, which should
0060   //                             be cheap to copy.
0061   // typedef ChildEdgeIteratorType - Type used to iterate over children edges in
0062   //                             graph, dereference to a EdgeRef.
0063 
0064   // static ChildEdgeIteratorType child_edge_begin(NodeRef)
0065   // static ChildEdgeIteratorType child_edge_end(NodeRef)
0066   //     Return iterators that point to the beginning and ending of the
0067   //     edge list for the given callgraph node.
0068   //
0069   // static NodeRef edge_dest(EdgeRef)
0070   //     Return the destination node of an edge.
0071 
0072   // static unsigned       size       (GraphType *G)
0073   //    Return total number of nodes in the graph
0074 
0075   // Optionally implement the following:
0076   // static unsigned getNumber(NodeRef)
0077   //    Return a unique number of a node. Numbers are ideally dense, these are
0078   //    used to store nodes in a vector.
0079   // static unsigned getMaxNumber(GraphType *G)
0080   //    Return the maximum number that getNumber() will return, or 0 if this is
0081   //    unknown. Intended for reserving large enough buffers.
0082   // static unsigned getNumberEpoch(GraphType *G)
0083   //    Return the "epoch" of the node numbers. Should return a different
0084   //    number after renumbering, so users can assert that the epoch didn't
0085   //    change => numbers are still valid. If renumberings are not tracked, it
0086   //    is always valid to return a constant value. This is solely for to ease
0087   //    debugging by having a way to detect use of outdated numbers.
0088 
0089   // If anyone tries to use this class without having an appropriate
0090   // specialization, make an error.  If you get this error, it's because you
0091   // need to include the appropriate specialization of GraphTraits<> for your
0092   // graph, or you need to define it for a new graph type. Either that or
0093   // your argument to XXX_begin(...) is unknown or needs to have the proper .h
0094   // file #include'd.
0095   using NodeRef = typename GraphType::UnknownGraphTypeError;
0096 };
0097 
0098 namespace detail {
0099 template <typename T>
0100 using has_number_t = decltype(GraphTraits<T>::getNumber(
0101     std::declval<typename GraphTraits<T>::NodeRef>()));
0102 } // namespace detail
0103 
0104 /// Indicate whether a GraphTraits<NodeT>::getNumber() is supported.
0105 template <typename NodeT>
0106 constexpr bool GraphHasNodeNumbers =
0107     is_detected<detail::has_number_t, NodeT>::value;
0108 
0109 // Inverse - This class is used as a little marker class to tell the graph
0110 // iterator to iterate over the graph in a graph defined "Inverse" ordering.
0111 // Not all graphs define an inverse ordering, and if they do, it depends on
0112 // the graph exactly what that is.  Here's an example of usage with the
0113 // df_iterator:
0114 //
0115 // idf_iterator<Method*> I = idf_begin(M), E = idf_end(M);
0116 // for (; I != E; ++I) { ... }
0117 //
0118 // Which is equivalent to:
0119 // df_iterator<Inverse<Method*>> I = idf_begin(M), E = idf_end(M);
0120 // for (; I != E; ++I) { ... }
0121 //
0122 template <class GraphType>
0123 struct Inverse {
0124   const GraphType &Graph;
0125 
0126   inline Inverse(const GraphType &G) : Graph(G) {}
0127 };
0128 
0129 // Provide a partial specialization of GraphTraits so that the inverse of an
0130 // inverse falls back to the original graph.
0131 template <class T> struct GraphTraits<Inverse<Inverse<T>>> : GraphTraits<T> {};
0132 
0133 // Provide iterator ranges for the graph traits nodes and children
0134 template <class GraphType>
0135 iterator_range<typename GraphTraits<GraphType>::nodes_iterator>
0136 nodes(const GraphType &G) {
0137   return make_range(GraphTraits<GraphType>::nodes_begin(G),
0138                     GraphTraits<GraphType>::nodes_end(G));
0139 }
0140 template <class GraphType>
0141 iterator_range<typename GraphTraits<Inverse<GraphType>>::nodes_iterator>
0142 inverse_nodes(const GraphType &G) {
0143   return make_range(GraphTraits<Inverse<GraphType>>::nodes_begin(G),
0144                     GraphTraits<Inverse<GraphType>>::nodes_end(G));
0145 }
0146 
0147 template <class GraphType>
0148 iterator_range<typename GraphTraits<GraphType>::ChildIteratorType>
0149 children(const typename GraphTraits<GraphType>::NodeRef &G) {
0150   return make_range(GraphTraits<GraphType>::child_begin(G),
0151                     GraphTraits<GraphType>::child_end(G));
0152 }
0153 
0154 template <class GraphType>
0155 iterator_range<typename GraphTraits<Inverse<GraphType>>::ChildIteratorType>
0156 inverse_children(const typename GraphTraits<GraphType>::NodeRef &G) {
0157   return make_range(GraphTraits<Inverse<GraphType>>::child_begin(G),
0158                     GraphTraits<Inverse<GraphType>>::child_end(G));
0159 }
0160 
0161 template <class GraphType>
0162 iterator_range<typename GraphTraits<GraphType>::ChildEdgeIteratorType>
0163 children_edges(const typename GraphTraits<GraphType>::NodeRef &G) {
0164   return make_range(GraphTraits<GraphType>::child_edge_begin(G),
0165                     GraphTraits<GraphType>::child_edge_end(G));
0166 }
0167 
0168 } // end namespace llvm
0169 
0170 #endif // LLVM_ADT_GRAPHTRAITS_H