LLVM 22.0.0git
DirectedGraph.h
Go to the documentation of this file.
1//===- llvm/ADT/DirectedGraph.h - Directed Graph ----------------*- 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 interface and a base class implementation for a
11/// directed graph.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_ADT_DIRECTEDGRAPH_H
16#define LLVM_ADT_DIRECTEDGRAPH_H
17
19#include "llvm/ADT/SetVector.h"
21#include "llvm/Support/Debug.h"
23
24namespace llvm {
25
26/// Represent an edge in the directed graph.
27/// The edge contains the target node it connects to.
28template <class NodeType, class EdgeType> class DGEdge {
29public:
30 DGEdge() = delete;
31 /// Create an edge pointing to the given node \p N.
32 explicit DGEdge(NodeType &N) : TargetNode(N) {}
36 TargetNode = E.TargetNode;
37 return *this;
38 }
39
40 /// Static polymorphism: delegate implementation (via isEqualTo) to the
41 /// derived class.
42 bool operator==(const DGEdge &E) const {
43 return getDerived().isEqualTo(E.getDerived());
44 }
45 bool operator!=(const DGEdge &E) const { return !operator==(E); }
46
47 /// Retrieve the target node this edge connects to.
48 const NodeType &getTargetNode() const { return TargetNode; }
49 NodeType &getTargetNode() {
50 return const_cast<NodeType &>(
51 static_cast<const DGEdge<NodeType, EdgeType> &>(*this).getTargetNode());
52 }
53
54 /// Set the target node this edge connects to.
55 void setTargetNode(const NodeType &N) { TargetNode = N; }
56
57protected:
58 // As the default implementation use address comparison for equality.
59 bool isEqualTo(const EdgeType &E) const { return this == &E; }
60
61 // Cast the 'this' pointer to the derived type and return a reference.
62 EdgeType &getDerived() { return *static_cast<EdgeType *>(this); }
63 const EdgeType &getDerived() const {
64 return *static_cast<const EdgeType *>(this);
65 }
66
67 // The target node this edge connects to.
68 NodeType &TargetNode;
69};
70
71/// Represent a node in the directed graph.
72/// The node has a (possibly empty) list of outgoing edges.
73template <class NodeType, class EdgeType> class DGNode {
74public:
78
79 /// Create a node with a single outgoing edge \p E.
80 explicit DGNode(EdgeType &E) : Edges() { Edges.insert(&E); }
81 DGNode() = default;
82
83 /// Static polymorphism: delegate implementation (via isEqualTo) to the
84 /// derived class.
85 friend bool operator==(const NodeType &M, const NodeType &N) {
86 return M.isEqualTo(N);
87 }
88 friend bool operator!=(const NodeType &M, const NodeType &N) {
89 return !(M == N);
90 }
91
92 const_iterator begin() const { return Edges.begin(); }
93 const_iterator end() const { return Edges.end(); }
94 iterator begin() { return Edges.begin(); }
95 iterator end() { return Edges.end(); }
96 const EdgeType &front() const { return *Edges.front(); }
97 EdgeType &front() { return *Edges.front(); }
98 const EdgeType &back() const { return *Edges.back(); }
99 EdgeType &back() { return *Edges.back(); }
100
101 /// Collect in \p EL, all the edges from this node to \p N.
102 /// Return true if at least one edge was found, and false otherwise.
103 /// Note that this implementation allows more than one edge to connect
104 /// a given pair of nodes.
105 bool findEdgesTo(const NodeType &N, SmallVectorImpl<EdgeType *> &EL) const {
106 assert(EL.empty() && "Expected the list of edges to be empty.");
107 for (auto *E : Edges)
108 if (E->getTargetNode() == N)
109 EL.push_back(E);
110 return !EL.empty();
111 }
112
113 /// Add the given edge \p E to this node, if it doesn't exist already. Returns
114 /// true if the edge is added and false otherwise.
115 bool addEdge(EdgeType &E) { return Edges.insert(&E); }
116
117 /// Remove the given edge \p E from this node, if it exists.
118 void removeEdge(EdgeType &E) { Edges.remove(&E); }
119
120 /// Test whether there is an edge that goes from this node to \p N.
121 bool hasEdgeTo(const NodeType &N) const {
122 return (findEdgeTo(N) != Edges.end());
123 }
124
125 /// Retrieve the outgoing edges for the node.
126 const EdgeListTy &getEdges() const { return Edges; }
128 return const_cast<EdgeListTy &>(
129 static_cast<const DGNode<NodeType, EdgeType> &>(*this).Edges);
130 }
131
132 /// Clear the outgoing edges.
133 void clear() { Edges.clear(); }
134
135protected:
136 // As the default implementation use address comparison for equality.
137 bool isEqualTo(const NodeType &N) const { return this == &N; }
138
139 // Cast the 'this' pointer to the derived type and return a reference.
140 NodeType &getDerived() { return *static_cast<NodeType *>(this); }
141 const NodeType &getDerived() const {
142 return *static_cast<const NodeType *>(this);
143 }
144
145 /// Find an edge to \p N. If more than one edge exists, this will return
146 /// the first one in the list of edges.
147 const_iterator findEdgeTo(const NodeType &N) const {
148 return llvm::find_if(
149 Edges, [&N](const EdgeType *E) { return E->getTargetNode() == N; });
150 }
151
152 // The list of outgoing edges.
154};
155
156/// Directed graph
157///
158/// The graph is represented by a table of nodes.
159/// Each node contains a (possibly empty) list of outgoing edges.
160/// Each edge contains the target node it connects to.
161template <class NodeType, class EdgeType> class DirectedGraph {
162protected:
165public:
169
170 DirectedGraph() = default;
171 explicit DirectedGraph(NodeType &N) : Nodes() { addNode(N); }
172
173 const_iterator begin() const { return Nodes.begin(); }
174 const_iterator end() const { return Nodes.end(); }
175 iterator begin() { return Nodes.begin(); }
176 iterator end() { return Nodes.end(); }
177 const NodeType &front() const { return *Nodes.front(); }
178 NodeType &front() { return *Nodes.front(); }
179 const NodeType &back() const { return *Nodes.back(); }
180 NodeType &back() { return *Nodes.back(); }
181
182 size_t size() const { return Nodes.size(); }
183
184 /// Find the given node \p N in the table.
185 const_iterator findNode(const NodeType &N) const {
186 return llvm::find_if(Nodes,
187 [&N](const NodeType *Node) { return *Node == N; });
188 }
189 iterator findNode(const NodeType &N) {
190 return const_cast<iterator>(
191 static_cast<const DGraphType &>(*this).findNode(N));
192 }
193
194 /// Add the given node \p N to the graph if it is not already present.
195 bool addNode(NodeType &N) {
196 if (findNode(N) != Nodes.end())
197 return false;
198 Nodes.push_back(&N);
199 return true;
200 }
201
202 /// Collect in \p EL all edges that are coming into node \p N. Return true
203 /// if at least one edge was found, and false otherwise.
204 bool findIncomingEdgesToNode(const NodeType &N, SmallVectorImpl<EdgeType*> &EL) const {
205 assert(EL.empty() && "Expected the list of edges to be empty.");
206 EdgeListTy TempList;
207 for (auto *Node : Nodes) {
208 if (*Node == N)
209 continue;
210 Node->findEdgesTo(N, TempList);
211 llvm::append_range(EL, TempList);
212 TempList.clear();
213 }
214 return !EL.empty();
215 }
216
217 /// Remove the given node \p N from the graph. If the node has incoming or
218 /// outgoing edges, they are also removed. Return true if the node was found
219 /// and then removed, and false if the node was not found in the graph to
220 /// begin with.
221 bool removeNode(NodeType &N) {
223 if (IT == Nodes.end())
224 return false;
225 // Remove incoming edges.
226 EdgeListTy EL;
227 for (auto *Node : Nodes) {
228 if (*Node == N)
229 continue;
230 Node->findEdgesTo(N, EL);
231 for (auto *E : EL)
232 Node->removeEdge(*E);
233 EL.clear();
234 }
235 N.clear();
236 Nodes.erase(IT);
237 return true;
238 }
239
240 /// Assuming nodes \p Src and \p Dst are already in the graph, connect node \p
241 /// Src to node \p Dst using the provided edge \p E. Return true if \p Src is
242 /// not already connected to \p Dst via \p E, and false otherwise.
243 bool connect(NodeType &Src, NodeType &Dst, EdgeType &E) {
244 assert(findNode(Src) != Nodes.end() && "Src node should be present.");
245 assert(findNode(Dst) != Nodes.end() && "Dst node should be present.");
246 assert((E.getTargetNode() == Dst) &&
247 "Target of the given edge does not match Dst.");
248 return Src.addEdge(E);
249 }
250
251protected:
252 // The list of nodes in the graph.
254};
255
256} // namespace llvm
257
258#endif // LLVM_ADT_DIRECTEDGRAPH_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::values(clEnumValN(DefaultIT, "arm-default-it", "Generate any type of IT block"), clEnumValN(RestrictedIT, "arm-restrict-it", "Disallow complex IT blocks")))
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the little GraphTraits<X> template class that should be specialized by classes that...
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallVector class.
DGEdge(NodeType &N)
Create an edge pointing to the given node N.
DGEdge()=delete
bool operator==(const DGEdge &E) const
Static polymorphism: delegate implementation (via isEqualTo) to the derived class.
bool operator!=(const DGEdge &E) const
EdgeType & getDerived()
const EdgeType & getDerived() const
const NodeType & getTargetNode() const
Retrieve the target node this edge connects to.
NodeType & getTargetNode()
void setTargetNode(const NodeType &N)
Set the target node this edge connects to.
bool isEqualTo(const EdgeType &E) const
DGEdge(const DGEdge< NodeType, EdgeType > &E)
DGEdge< NodeType, EdgeType > & operator=(const DGEdge< NodeType, EdgeType > &E)
const_iterator begin() const
iterator end()
iterator begin()
friend bool operator==(const NodeType &M, const NodeType &N)
Static polymorphism: delegate implementation (via isEqualTo) to the derived class.
bool addEdge(EdgeType &E)
Add the given edge E to this node, if it doesn't exist already.
const_iterator end() const
void removeEdge(EdgeType &E)
Remove the given edge E from this node, if it exists.
DGNode()=default
const EdgeType & front() const
EdgeType & front()
SetVector< EdgeType * > EdgeListTy
typename EdgeListTy::const_iterator const_iterator
bool findEdgesTo(const NodeType &N, SmallVectorImpl< EdgeType * > &EL) const
Collect in EL, all the edges from this node to N.
const EdgeListTy & getEdges() const
Retrieve the outgoing edges for the node.
const EdgeType & back() const
bool isEqualTo(const NodeType &N) const
EdgeType & back()
bool hasEdgeTo(const NodeType &N) const
Test whether there is an edge that goes from this node to N.
DGNode(EdgeType &E)
Create a node with a single outgoing edge E.
void clear()
Clear the outgoing edges.
const NodeType & getDerived() const
EdgeListTy & getEdges()
NodeType & getDerived()
friend bool operator!=(const NodeType &M, const NodeType &N)
const_iterator findEdgeTo(const NodeType &N) const
Find an edge to N.
typename EdgeListTy::iterator iterator
DirectedGraph()=default
const NodeType & front() const
size_t size() const
const NodeType & back() const
bool connect(NodeType &Src, NodeType &Dst, EdgeType &E)
Assuming nodes Src and Dst are already in the graph, connect node Src to node Dst using the provided ...
SmallVector< NodeType *, 10 > NodeListTy
bool findIncomingEdgesToNode(const NodeType &N, SmallVectorImpl< EdgeType * > &EL) const
Collect in EL all edges that are coming into node N.
const_iterator begin() const
const_iterator end() const
typename NodeListTy::iterator iterator
typename NodeListTy::const_iterator const_iterator
DirectedGraph< NodeType, EdgeType > DGraphType
bool addNode(NodeType &N)
Add the given node N to the graph if it is not already present.
DirectedGraph(NodeType &N)
bool removeNode(NodeType &N)
Remove the given node N from the graph.
SmallVector< EdgeType *, 10 > EdgeListTy
iterator findNode(const NodeType &N)
const_iterator findNode(const NodeType &N) const
Find the given node N in the table.
A vector that has set insertion semantics.
Definition SetVector.h:59
typename vector_type::const_iterator iterator
Definition SetVector.h:71
typename vector_type::const_iterator const_iterator
Definition SetVector.h:72
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This is an optimization pass for GlobalISel generic memory operations.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2136
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1758
#define N