LLVM 24.0.0git
GraphTraits.h
Go to the documentation of this file.
1//===- llvm/ADT/GraphTraits.h - Graph traits template -----------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file defines the little GraphTraits<X> template class that should be
11/// specialized by classes that want to be iteratable by generic graph
12/// iterators.
13///
14/// This file also defines the marker class Inverse that is used to iterate over
15/// graphs in a graph defined, inverse ordering...
16///
17//===----------------------------------------------------------------------===//
18
19#ifndef LLVM_ADT_GRAPHTRAITS_H
20#define LLVM_ADT_GRAPHTRAITS_H
21
22#include "llvm/ADT/STLExtras.h"
24
25namespace llvm {
26
27// GraphTraits - This class should be specialized by different graph types...
28// which is why the default version is empty.
29//
30// This template evolved from supporting `BasicBlock` to also later supporting
31// more complex types (e.g. CFG and DomTree).
32//
33// GraphTraits can be used to create a view over a graph interpreting it
34// differently without requiring a copy of the original graph. This could
35// be achieved by carrying more data in NodeRef.
36template<class GraphType>
38 // Elements to provide:
39
40 // typedef NodeRef - Type of Node token in the graph, which should
41 // be cheap to copy.
42 // typedef ChildIteratorType - Type used to iterate over children in graph,
43 // dereference to a NodeRef.
44
45 // static NodeRef getEntryNode(const GraphType &)
46 // Return the entry node of the graph
47
48 // static ChildIteratorType child_begin(NodeRef)
49 // static ChildIteratorType child_end (NodeRef)
50 // Return iterators that point to the beginning and ending of the child
51 // node list for the specified node.
52
53 // typedef ...iterator nodes_iterator; - dereference to a NodeRef
54 // static nodes_iterator nodes_begin(GraphType *G)
55 // static nodes_iterator nodes_end (GraphType *G)
56 // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
57
58 // typedef EdgeRef - Type of Edge token in the graph, which should
59 // be cheap to copy.
60 // typedef ChildEdgeIteratorType - Type used to iterate over children edges in
61 // graph, dereference to a EdgeRef.
62
63 // static ChildEdgeIteratorType child_edge_begin(NodeRef)
64 // static ChildEdgeIteratorType child_edge_end(NodeRef)
65 // Return iterators that point to the beginning and ending of the
66 // edge list for the given callgraph node.
67 //
68 // static NodeRef edge_dest(EdgeRef)
69 // Return the destination node of an edge.
70
71 // static unsigned size (GraphType *G)
72 // Return total number of nodes in the graph
73
74 // Optionally implement the following:
75 // static unsigned getNumber(NodeRef)
76 // Return a unique number of a node. Numbers are ideally dense, these are
77 // used to store nodes in a vector.
78 // static unsigned getMaxNumber(GraphType *G)
79 // Return the maximum number that getNumber() will return, or 0 if this is
80 // unknown. Intended for reserving large enough buffers.
81 // static unsigned getNumberEpoch(GraphType *G)
82 // Return the "epoch" of the node numbers. Should return a different
83 // number after renumbering, so users can assert that the epoch didn't
84 // change => numbers are still valid. If renumberings are not tracked, it
85 // is always valid to return a constant value. This is solely for to ease
86 // debugging by having a way to detect use of outdated numbers.
87
88 // If anyone tries to use this class without having an appropriate
89 // specialization, make an error. If you get this error, it's because you
90 // need to include the appropriate specialization of GraphTraits<> for your
91 // graph, or you need to define it for a new graph type. Either that or
92 // your argument to XXX_begin(...) is unknown or needs to have the proper .h
93 // file #include'd.
94 using NodeRef = typename GraphType::UnknownGraphTypeError;
95};
96
97namespace detail {
98template <typename T>
100 std::declval<typename GraphTraits<T>::NodeRef>()));
101} // namespace detail
102
103/// Indicate whether a GraphTraits<NodeT>::getNumber() is supported.
104template <typename NodeT>
105constexpr bool GraphHasNodeNumbers =
107
108// Inverse - This class is used as a little marker class to tell the graph
109// iterator to iterate over the graph in a graph defined "Inverse" ordering.
110// Not all graphs define an inverse ordering, and if they do, it depends on
111// the graph exactly what that is. Here's an example of usage with the
112// df_iterator:
113//
114// idf_iterator<Method*> I = idf_begin(M), E = idf_end(M);
115// for (; I != E; ++I) { ... }
116//
117// Which is equivalent to:
118// df_iterator<Inverse<Method*>> I = idf_begin(M), E = idf_end(M);
119// for (; I != E; ++I) { ... }
120//
121template <class GraphType>
122struct Inverse {
123 const GraphType &Graph;
124
125 inline Inverse(const GraphType &G) : Graph(G) {}
126};
127
128// Provide a partial specialization of GraphTraits so that the inverse of an
129// inverse falls back to the original graph.
130template <class T> struct GraphTraits<Inverse<Inverse<T>>> : GraphTraits<T> {};
131
132// Provide iterator ranges for the graph traits nodes and children
133template <class GraphType>
139template <class GraphType>
141inverse_nodes(const GraphType &G) {
142 return make_range(GraphTraits<Inverse<GraphType>>::nodes_begin(G),
143 GraphTraits<Inverse<GraphType>>::nodes_end(G));
144}
145
146template <class GraphType>
147iterator_range<typename GraphTraits<GraphType>::ChildIteratorType>
152
153template <class GraphType>
159
160template <class GraphType>
161iterator_range<typename GraphTraits<GraphType>::ChildEdgeIteratorType>
166
167} // end namespace llvm
168
169#endif // LLVM_ADT_GRAPHTRAITS_H
Unify divergent function exit nodes
#define G(x, y, z)
Definition MD5.cpp:55
#define T
This file contains some templates that are useful if you are working with the STL at all.
A range adaptor for a pair of iterators.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
decltype(GraphTraits< T >::getNumber( std::declval< typename GraphTraits< T >::NodeRef >())) has_number_t
Definition GraphTraits.h:99
This is an optimization pass for GlobalISel generic memory operations.
iterator_range< typename GraphTraits< Inverse< GraphType > >::nodes_iterator > inverse_nodes(const GraphType &G)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
constexpr bool GraphHasNodeNumbers
Indicate whether a GraphTraits<NodeT>::getNumber() is supported.
iterator_range(Container &&) -> iterator_range< llvm::detail::IterOfRange< Container > >
iterator_range< typename GraphTraits< GraphType >::ChildEdgeIteratorType > children_edges(const typename GraphTraits< GraphType >::NodeRef &G)
iterator_range< typename GraphTraits< Inverse< GraphType > >::ChildIteratorType > inverse_children(const typename GraphTraits< GraphType >::NodeRef &G)
typename detail::detector< void, Op, Args... >::value_t is_detected
Detects if a given trait holds for some set of arguments 'Args'.
iterator_range< typename GraphTraits< GraphType >::ChildIteratorType > children(const typename GraphTraits< GraphType >::NodeRef &G)
typename GraphType::UnknownGraphTypeError NodeRef
Definition GraphTraits.h:94
const GraphType & Graph
Inverse(const GraphType &G)