15 #ifndef LLVM_CODEGEN_PBQP_GRAPH_H
16 #define LLVM_CODEGEN_PBQP_GRAPH_H
36 return std::numeric_limits<NodeId>::max();
41 return std::numeric_limits<EdgeId>::max();
48 template <
typename SolverT>
51 typedef typename SolverT::CostAllocator CostAllocator;
55 typedef typename SolverT::Vector
Vector;
57 typedef typename CostAllocator::VectorPtr
VectorPtr;
58 typedef typename CostAllocator::MatrixPtr
MatrixPtr;
67 typedef std::vector<EdgeId> AdjEdgeList;
68 typedef AdjEdgeList::size_type AdjEdgeIdx;
69 typedef AdjEdgeList::const_iterator
AdjEdgeItr;
71 static AdjEdgeIdx getInvalidAdjEdgeIdx() {
72 return std::numeric_limits<AdjEdgeIdx>::max();
75 NodeEntry(
VectorPtr Costs) : Costs(std::move(Costs)) {}
77 AdjEdgeIdx addAdjEdgeId(
EdgeId EId) {
78 AdjEdgeIdx Idx = AdjEdgeIds.size();
79 AdjEdgeIds.push_back(EId);
83 void removeAdjEdgeId(
Graph &
G,
NodeId ThisNId, AdjEdgeIdx Idx) {
90 G.getEdge(AdjEdgeIds.back()).setAdjEdgeIdx(ThisNId, Idx);
91 AdjEdgeIds[Idx] = AdjEdgeIds.back();
92 AdjEdgeIds.pop_back();
95 const AdjEdgeList& getAdjEdgeIds()
const {
return AdjEdgeIds; }
100 AdjEdgeList AdjEdgeIds;
106 : Costs(std::move(Costs)) {
109 ThisEdgeAdjIdxs[0] = NodeEntry::getInvalidAdjEdgeIdx();
110 ThisEdgeAdjIdxs[1] = NodeEntry::getInvalidAdjEdgeIdx();
113 void connectToN(
Graph &
G,
EdgeId ThisEdgeId,
unsigned NIdx) {
114 assert(ThisEdgeAdjIdxs[NIdx] == NodeEntry::getInvalidAdjEdgeIdx() &&
115 "Edge already connected to NIds[NIdx].");
116 NodeEntry &
N = G.getNode(NIds[NIdx]);
117 ThisEdgeAdjIdxs[NIdx] = N.addAdjEdgeId(ThisEdgeId);
121 connectToN(G, ThisEdgeId, 0);
122 connectToN(G, ThisEdgeId, 1);
125 void setAdjEdgeIdx(
NodeId NId,
typename NodeEntry::AdjEdgeIdx NewIdx) {
127 ThisEdgeAdjIdxs[0] = NewIdx;
129 assert(NId == NIds[1] &&
"Edge not connected to NId");
130 ThisEdgeAdjIdxs[1] = NewIdx;
134 void disconnectFromN(
Graph &G,
unsigned NIdx) {
135 assert(ThisEdgeAdjIdxs[NIdx] != NodeEntry::getInvalidAdjEdgeIdx() &&
136 "Edge not connected to NIds[NIdx].");
137 NodeEntry &N = G.getNode(NIds[NIdx]);
138 N.removeAdjEdgeId(G, NIds[NIdx], ThisEdgeAdjIdxs[NIdx]);
139 ThisEdgeAdjIdxs[NIdx] = NodeEntry::getInvalidAdjEdgeIdx();
144 disconnectFromN(G, 0);
146 assert(NId == NIds[1] &&
"Edge does not connect NId");
147 disconnectFromN(G, 1);
151 NodeId getN1Id()
const {
return NIds[0]; }
152 NodeId getN2Id()
const {
return NIds[1]; }
157 typename NodeEntry::AdjEdgeIdx ThisEdgeAdjIdxs[2];
163 CostAllocator CostAlloc;
166 typedef std::vector<NodeEntry> NodeVector;
167 typedef std::vector<NodeId> FreeNodeVector;
169 FreeNodeVector FreeNodeIds;
171 typedef std::vector<EdgeEntry> EdgeVector;
172 typedef std::vector<EdgeId> FreeEdgeVector;
174 FreeEdgeVector FreeEdgeIds;
178 NodeEntry &getNode(
NodeId NId) {
179 assert(NId < Nodes.size() &&
"Out of bound NodeId");
182 const NodeEntry &getNode(
NodeId NId)
const {
183 assert(NId < Nodes.size() &&
"Out of bound NodeId");
187 EdgeEntry& getEdge(
EdgeId EId) {
return Edges[EId]; }
188 const EdgeEntry& getEdge(
EdgeId EId)
const {
return Edges[EId]; }
190 NodeId addConstructedNode(NodeEntry N) {
192 if (!FreeNodeIds.empty()) {
193 NId = FreeNodeIds.back();
194 FreeNodeIds.pop_back();
195 Nodes[NId] = std::move(N);
198 Nodes.push_back(std::move(N));
203 EdgeId addConstructedEdge(EdgeEntry
E) {
205 "Attempt to add duplicate edge.");
207 if (!FreeEdgeIds.empty()) {
208 EId = FreeEdgeIds.back();
209 FreeEdgeIds.pop_back();
210 Edges[EId] = std::move(E);
213 Edges.push_back(std::move(E));
216 EdgeEntry &
NE = getEdge(EId);
219 NE.connect(*
this, EId);
224 void operator=(
const Graph &Other) {}
239 : CurNId(CurNId), EndNId(G.Nodes.size()), FreeNodeIds(G.FreeNodeIds) {
240 this->CurNId = findNextInUse(CurNId);
250 while (NId < EndNId &&
is_contained(FreeNodeIds, NId)) {
257 const FreeNodeVector &FreeNodeIds;
263 : CurEId(CurEId), EndEId(G.Edges.size()), FreeEdgeIds(G.FreeEdgeIds) {
264 this->CurEId = findNextInUse(CurEId);
274 while (EId < EndEId &&
is_contained(FreeEdgeIds, EId)) {
281 const FreeEdgeVector &FreeEdgeIds;
289 bool empty()
const {
return G.Nodes.empty(); }
290 typename NodeVector::size_type
size()
const {
291 return G.Nodes.size() - G.FreeNodeIds.size();
302 bool empty()
const {
return G.Edges.empty(); }
303 typename NodeVector::size_type
size()
const {
304 return G.Edges.size() - G.FreeEdgeIds.size();
313 typename NodeEntry::AdjEdgeItr
begin()
const {
314 return NE.getAdjEdgeIds().begin();
316 typename NodeEntry::AdjEdgeItr
end()
const {
317 return NE.getAdjEdgeIds().end();
319 bool empty()
const {
return NE.getAdjEdgeIds().empty(); }
320 typename NodeEntry::AdjEdgeList::size_type
size()
const {
321 return NE.getAdjEdgeIds().size();
332 : Metadata(std::move(Metadata)), Solver(nullptr) {}
345 assert(!Solver &&
"Solver already set. Call unsetSolver().");
348 Solver->handleAddNode(NId);
350 Solver->handleAddEdge(EId);
355 assert(Solver &&
"Solver not set.");
362 template <
typename OtherVectorT>
365 VectorPtr AllocatedCosts = CostAlloc.getVector(std::move(Costs));
366 NodeId NId = addConstructedNode(NodeEntry(AllocatedCosts));
368 Solver->handleAddNode(NId);
383 template <
typename OtherVectorPtrT>
385 NodeId NId = addConstructedNode(NodeEntry(Costs));
387 Solver->handleAddNode(NId);
396 template <
typename OtherVectorT>
400 "Matrix dimensions mismatch.");
402 MatrixPtr AllocatedCosts = CostAlloc.getMatrix(std::move(Costs));
403 EdgeId EId = addConstructedEdge(EdgeEntry(N1Id, N2Id, AllocatedCosts));
405 Solver->handleAddEdge(EId);
421 template <
typename OtherMatrixPtrT>
423 OtherMatrixPtrT Costs) {
426 "Matrix dimensions mismatch.");
428 EdgeId EId = addConstructedEdge(EdgeEntry(N1Id, N2Id, Costs));
430 Solver->handleAddEdge(EId);
435 bool empty()
const {
return NodeIdSet(*this).empty(); }
437 NodeIdSet
nodeIds()
const {
return NodeIdSet(*
this); }
438 EdgeIdSet
edgeIds()
const {
return EdgeIdSet(*
this); }
453 template <
typename OtherVectorT>
455 VectorPtr AllocatedCosts = CostAlloc.getVector(std::move(Costs));
457 Solver->handleSetNodeCosts(NId, *AllocatedCosts);
458 getNode(NId).Costs = AllocatedCosts;
470 return getNode(NId).Costs;
481 return getNode(NId).Metadata;
485 return getNode(NId).Metadata;
489 return getNode(NId).getAdjEdgeIds().size();
495 template <
typename OtherMatrixT>
497 MatrixPtr AllocatedCosts = CostAlloc.getMatrix(std::move(Costs));
499 Solver->handleUpdateCosts(EId, *AllocatedCosts);
500 getEdge(EId).Costs = AllocatedCosts;
512 return getEdge(EId).Costs;
519 return *getEdge(EId).Costs;
523 return getEdge(EId).Metadata;
527 return getEdge(EId).Metadata;
534 return getEdge(EId).getN1Id();
541 return getEdge(EId).getN2Id();
549 EdgeEntry &E = getEdge(EId);
550 if (E.getN1Id() == NId) {
575 Solver->handleRemoveNode(NId);
576 NodeEntry &N = getNode(NId);
579 AEEnd = N.adjEdgesEnd();
585 FreeNodeIds.push_back(NId);
615 Solver->handleDisconnectEdge(EId, NId);
617 EdgeEntry &E = getEdge(EId);
618 E.disconnectFrom(*
this, NId);
633 EdgeEntry &E = getEdge(EId);
634 E.connectTo(*
this, EId, NId);
636 Solver->handleReconnectEdge(EId, NId);
643 Solver->handleRemoveEdge(EId);
644 EdgeEntry &E = getEdge(EId);
646 FreeEdgeIds.push_back(EId);
647 Edges[EId].invalidate();
662 #endif // LLVM_CODEGEN_PBQP_GRAPH_HPP
const NodeMetadata & getNodeMetadata(NodeId NId) const
EdgeIdSet(const Graph &G)
NodeId getEdgeNode1Id(EdgeId EId) const
Get the first node connected to this edge.
const VectorPtr & getNodeCostsPtr(NodeId NId) const
Get a VectorPtr to a node's cost vector.
NodeVector::size_type size() const
EdgeId addEdge(NodeId N1Id, NodeId N2Id, OtherVectorT Costs)
Add an edge between the given nodes with the given costs.
EdgeId findEdge(NodeId N1Id, NodeId N2Id)
Get the edge connecting two nodes.
static NodeId invalidNodeId()
Returns a value representing an invalid (non-existent) node.
unsigned getNumEdges() const
Get the number of edges in the graph.
NodeId getEdgeNode2Id(EdgeId EId) const
Get the second node connected to this edge.
NodeItr(NodeId CurNId, const Graph &G)
NodeEntry::AdjEdgeItr begin() const
void reconnectEdge(EdgeId EId, NodeId NId)
Re-attach an edge to its nodes.
void updateEdgeCosts(EdgeId EId, OtherMatrixT Costs)
Update an edge's cost matrix.
const GraphMetadata & getMetadata() const
Get a const-reference to the graph metadata.
NodeId addEdgeBypassingCostAllocator(NodeId N1Id, NodeId N2Id, OtherMatrixPtrT Costs)
Add an edge bypassing the cost allocator.
NodeEntry::AdjEdgeItr AdjEdgeItr
SolverT::GraphMetadata GraphMetadata
SolverT::NodeMetadata NodeMetadata
const Vector & getNodeCosts(NodeId NId) const
Get a node's cost vector.
NodeVector::size_type size() const
bool operator!=(const NodeItr &O) const
SolverT::RawMatrix RawMatrix
NodeMetadata & getNodeMetadata(NodeId NId)
NodeEntry::AdjEdgeList::size_type size() const
void disconnectEdge(EdgeId EId, NodeId NId)
Disconnect an edge from the given node.
CostAllocator::VectorPtr VectorPtr
Graph()
Construct an empty PBQP graph.
NodeId getEdgeOtherNodeId(EdgeId EId, NodeId NId)
Get the "other" node connected to this edge.
NodeEntry::AdjEdgeList::size_type getNodeDegree(NodeId NId) const
unsigned getNumNodes() const
Get the number of nodes in the graph.
EdgeIdSet edgeIds() const
bool operator!=(const EdgeItr &O) const
NodeId addNodeBypassingCostAllocator(OtherVectorPtrT Costs)
Add a node bypassing the cost allocator.
NodeIdSet nodeIds() const
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
void removeNode(NodeId NId)
Remove a node from the graph.
AdjEdgeIdSet adjEdgeIds(NodeId NId)
void setSolver(SolverT &S)
Lock this graph to the given solver instance in preparation for running the solver.
void clear()
Remove all nodes and edges from the graph.
NodeEntry::AdjEdgeItr end() const
EdgeItr(EdgeId CurEId, const Graph &G)
GraphMetadata & getMetadata()
Get a reference to the graph metadata.
void removeEdge(EdgeId EId)
Remove an edge from the graph.
AdjEdgeIdSet(const NodeEntry &NE)
void unsetSolver()
Release from solver instance.
Graph(GraphMetadata Metadata)
Construct an empty PBQP graph with the given graph metadata.
const Matrix & getEdgeCosts(EdgeId EId) const
Get an edge's cost matrix.
bool empty() const
Returns true if the graph is empty.
static EdgeId invalidEdgeId()
Returns a value representing an invalid (non-existent) edge.
SolverT::EdgeMetadata EdgeMetadata
void disconnectAllNeighborsFromNode(NodeId NId)
Convenience method to disconnect all neighbours from the given node.
bool operator==(const NodeItr &O) const
std::forward_iterator_tag iterator_category
EdgeMetadata & getEdgeMetadata(EdgeId EId)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
NodeIdSet(const Graph &G)
const EdgeMetadata & getEdgeMetadata(EdgeId EId) const
const MatrixPtr & getEdgeCostsPtr(EdgeId EId) const
Get a MatrixPtr to a node's cost matrix.
NodeId addNode(OtherVectorT Costs)
Add a node with the given costs.
bool operator==(const EdgeItr &O) const
SolverT::RawVector RawVector
CostAllocator::MatrixPtr MatrixPtr
void setNodeCosts(NodeId NId, OtherVectorT Costs)
Set a node's cost vector.
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.