14 #ifndef LLVM_CODEGEN_PBQP_GRAPH_H 15 #define LLVM_CODEGEN_PBQP_GRAPH_H 46 template <
typename SolverT>
49 using CostAllocator =
typename SolverT::CostAllocator;
54 using Vector =
typename SolverT::Vector;
56 using VectorPtr =
typename CostAllocator::VectorPtr;
57 using MatrixPtr =
typename CostAllocator::MatrixPtr;
65 using AdjEdgeList = std::vector<EdgeId>;
66 using AdjEdgeIdx = AdjEdgeList::size_type;
67 using AdjEdgeItr = AdjEdgeList::const_iterator;
69 NodeEntry(
VectorPtr Costs) : Costs(std::move(Costs)) {}
71 static AdjEdgeIdx getInvalidAdjEdgeIdx() {
75 AdjEdgeIdx addAdjEdgeId(
EdgeId EId) {
76 AdjEdgeIdx Idx = AdjEdgeIds.size();
77 AdjEdgeIds.push_back(EId);
81 void removeAdjEdgeId(
Graph &
G,
NodeId ThisNId, AdjEdgeIdx Idx) {
88 G.getEdge(AdjEdgeIds.back()).setAdjEdgeIdx(ThisNId, Idx);
89 AdjEdgeIds[Idx] = AdjEdgeIds.back();
90 AdjEdgeIds.pop_back();
93 const AdjEdgeList& getAdjEdgeIds()
const {
return AdjEdgeIds; }
99 AdjEdgeList AdjEdgeIds;
105 : Costs(std::move(Costs)) {
108 ThisEdgeAdjIdxs[0] = NodeEntry::getInvalidAdjEdgeIdx();
109 ThisEdgeAdjIdxs[1] = NodeEntry::getInvalidAdjEdgeIdx();
112 void connectToN(
Graph &
G,
EdgeId ThisEdgeId,
unsigned NIdx) {
113 assert(ThisEdgeAdjIdxs[NIdx] == NodeEntry::getInvalidAdjEdgeIdx() &&
114 "Edge already connected to NIds[NIdx].");
115 NodeEntry &
N = G.getNode(NIds[NIdx]);
116 ThisEdgeAdjIdxs[NIdx] = N.addAdjEdgeId(ThisEdgeId);
120 connectToN(G, ThisEdgeId, 0);
121 connectToN(G, ThisEdgeId, 1);
124 void setAdjEdgeIdx(
NodeId NId,
typename NodeEntry::AdjEdgeIdx NewIdx) {
126 ThisEdgeAdjIdxs[0] = NewIdx;
128 assert(NId == NIds[1] &&
"Edge not connected to NId");
129 ThisEdgeAdjIdxs[1] = NewIdx;
133 void disconnectFromN(
Graph &G,
unsigned NIdx) {
134 assert(ThisEdgeAdjIdxs[NIdx] != NodeEntry::getInvalidAdjEdgeIdx() &&
135 "Edge not connected to NIds[NIdx].");
136 NodeEntry &
N = G.getNode(NIds[NIdx]);
137 N.removeAdjEdgeId(G, NIds[NIdx], ThisEdgeAdjIdxs[NIdx]);
138 ThisEdgeAdjIdxs[NIdx] = NodeEntry::getInvalidAdjEdgeIdx();
143 disconnectFromN(G, 0);
145 assert(NId == NIds[1] &&
"Edge does not connect NId");
146 disconnectFromN(G, 1);
150 NodeId getN1Id()
const {
return NIds[0]; }
151 NodeId getN2Id()
const {
return NIds[1]; }
158 typename NodeEntry::AdjEdgeIdx ThisEdgeAdjIdxs[2];
164 CostAllocator CostAlloc;
165 SolverT *Solver =
nullptr;
167 using NodeVector = std::vector<NodeEntry>;
168 using FreeNodeVector = std::vector<NodeId>;
170 FreeNodeVector FreeNodeIds;
172 using EdgeVector = std::vector<EdgeEntry>;
173 using FreeEdgeVector = std::vector<EdgeId>;
175 FreeEdgeVector FreeEdgeIds;
181 NodeEntry &getNode(
NodeId NId) {
182 assert(NId < Nodes.size() &&
"Out of bound NodeId");
185 const NodeEntry &getNode(
NodeId NId)
const {
186 assert(NId < Nodes.size() &&
"Out of bound NodeId");
190 EdgeEntry& getEdge(
EdgeId EId) {
return Edges[EId]; }
191 const EdgeEntry& getEdge(
EdgeId EId)
const {
return Edges[EId]; }
193 NodeId addConstructedNode(NodeEntry
N) {
195 if (!FreeNodeIds.empty()) {
196 NId = FreeNodeIds.back();
197 FreeNodeIds.pop_back();
198 Nodes[NId] = std::move(N);
201 Nodes.push_back(std::move(N));
206 EdgeId addConstructedEdge(EdgeEntry
E) {
208 "Attempt to add duplicate edge.");
210 if (!FreeEdgeIds.empty()) {
211 EId = FreeEdgeIds.back();
212 FreeEdgeIds.pop_back();
213 Edges[EId] = std::move(E);
216 Edges.push_back(std::move(E));
219 EdgeEntry &
NE = getEdge(EId);
222 NE.connect(*
this, EId);
226 void operator=(
const Graph &Other) {}
240 : CurNId(CurNId), EndNId(G.Nodes.
size()), FreeNodeIds(G.FreeNodeIds) {
241 this->CurNId = findNextInUse(CurNId);
251 while (NId < EndNId &&
is_contained(FreeNodeIds, NId)) {
258 const FreeNodeVector &FreeNodeIds;
264 : CurEId(CurEId), EndEId(G.Edges.
size()), FreeEdgeIds(G.FreeEdgeIds) {
265 this->CurEId = findNextInUse(CurEId);
275 while (EId < EndEId &&
is_contained(FreeEdgeIds, EId)) {
282 const FreeEdgeVector &FreeEdgeIds;
292 bool empty()
const {
return G.Nodes.empty(); }
294 typename NodeVector::size_type
size()
const {
295 return G.Nodes.size() -
G.FreeNodeIds.size();
309 bool empty()
const {
return G.Edges.empty(); }
311 typename NodeVector::size_type
size()
const {
312 return G.Edges.size() -
G.FreeEdgeIds.size();
323 typename NodeEntry::AdjEdgeItr
begin()
const {
324 return NE.getAdjEdgeIds().begin();
327 typename NodeEntry::AdjEdgeItr
end()
const {
328 return NE.getAdjEdgeIds().end();
331 bool empty()
const {
return NE.getAdjEdgeIds().empty(); }
333 typename NodeEntry::AdjEdgeList::size_type
size()
const {
334 return NE.getAdjEdgeIds().size();
358 assert(!Solver &&
"Solver already set. Call unsetSolver().");
360 for (
auto NId : nodeIds())
361 Solver->handleAddNode(NId);
362 for (
auto EId : edgeIds())
363 Solver->handleAddEdge(EId);
368 assert(Solver &&
"Solver not set.");
375 template <
typename OtherVectorT>
378 VectorPtr AllocatedCosts = CostAlloc.getVector(std::move(Costs));
379 NodeId NId = addConstructedNode(NodeEntry(AllocatedCosts));
381 Solver->handleAddNode(NId);
396 template <
typename OtherVectorPtrT>
398 NodeId NId = addConstructedNode(NodeEntry(Costs));
400 Solver->handleAddNode(NId);
409 template <
typename OtherVectorT>
411 assert(getNodeCosts(N1Id).getLength() == Costs.getRows() &&
412 getNodeCosts(N2Id).getLength() == Costs.getCols() &&
413 "Matrix dimensions mismatch.");
415 MatrixPtr AllocatedCosts = CostAlloc.getMatrix(std::move(Costs));
416 EdgeId EId = addConstructedEdge(EdgeEntry(N1Id, N2Id, AllocatedCosts));
418 Solver->handleAddEdge(EId);
434 template <
typename OtherMatrixPtrT>
436 OtherMatrixPtrT Costs) {
437 assert(getNodeCosts(N1Id).getLength() == Costs->getRows() &&
438 getNodeCosts(N2Id).getLength() == Costs->getCols() &&
439 "Matrix dimensions mismatch.");
441 EdgeId EId = addConstructedEdge(EdgeEntry(N1Id, N2Id, Costs));
443 Solver->handleAddEdge(EId);
448 bool empty()
const {
return NodeIdSet(*this).empty(); }
450 NodeIdSet
nodeIds()
const {
return NodeIdSet(*
this); }
451 EdgeIdSet
edgeIds()
const {
return EdgeIdSet(*
this); }
466 template <
typename OtherVectorT>
468 VectorPtr AllocatedCosts = CostAlloc.getVector(std::move(Costs));
470 Solver->handleSetNodeCosts(NId, *AllocatedCosts);
471 getNode(NId).Costs = AllocatedCosts;
483 return getNode(NId).Costs;
490 return *getNodeCostsPtr(NId);
494 return getNode(NId).Metadata;
498 return getNode(NId).Metadata;
502 return getNode(NId).getAdjEdgeIds().size();
508 template <
typename OtherMatrixT>
510 MatrixPtr AllocatedCosts = CostAlloc.getMatrix(std::move(Costs));
512 Solver->handleUpdateCosts(EId, *AllocatedCosts);
513 getEdge(EId).Costs = AllocatedCosts;
525 return getEdge(EId).Costs;
532 return *getEdge(EId).Costs;
536 return getEdge(EId).Metadata;
540 return getEdge(EId).Metadata;
547 return getEdge(EId).getN1Id();
554 return getEdge(EId).getN2Id();
562 EdgeEntry &E = getEdge(EId);
563 if (E.getN1Id() == NId) {
575 for (
auto AEId : adjEdgeIds(N1Id)) {
576 if ((getEdgeNode1Id(AEId) == N2Id) ||
577 (getEdgeNode2Id(AEId) == N2Id)) {
588 Solver->handleRemoveNode(NId);
589 NodeEntry &N = getNode(NId);
592 AEEnd = N.adjEdgesEnd();
598 FreeNodeIds.push_back(NId);
628 Solver->handleDisconnectEdge(EId, NId);
630 EdgeEntry &E = getEdge(EId);
631 E.disconnectFrom(*
this, NId);
637 for (
auto AEId : adjEdgeIds(NId))
638 disconnectEdge(AEId, getEdgeOtherNodeId(AEId, NId));
646 EdgeEntry &E = getEdge(EId);
647 E.connectTo(*
this, EId, NId);
649 Solver->handleReconnectEdge(EId, NId);
656 Solver->handleRemoveEdge(EId);
657 EdgeEntry &E = getEdge(EId);
659 FreeEdgeIds.push_back(EId);
660 Edges[EId].invalidate();
675 #endif // LLVM_CODEGEN_PBQP_GRAPH_HPP
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
EdgeIdSet(const Graph &G)
NodeVector::size_type size() const
This class represents lattice values for constants.
NodeEntry::AdjEdgeItr begin() const
EdgeId addEdge(NodeId N1Id, NodeId N2Id, OtherVectorT Costs)
Add an edge between the given nodes with the given costs.
bool empty() const
Returns true if the graph is empty.
typename RegAllocSolverImpl ::EdgeMetadata EdgeMetadata
EdgeId findEdge(NodeId N1Id, NodeId N2Id)
Get the edge connecting two nodes.
NodeVector::size_type size() const
static NodeId invalidNodeId()
Returns a value representing an invalid (non-existent) node.
bool operator==(const NodeItr &O) const
typename CostAllocator::VectorPtr VectorPtr
NodeItr(NodeId CurNId, const Graph &G)
bool operator!=(const NodeItr &O) 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.
NodeId addEdgeBypassingCostAllocator(NodeId N1Id, NodeId N2Id, OtherMatrixPtrT Costs)
Add an edge bypassing the cost allocator.
NodeId getEdgeNode1Id(EdgeId EId) const
Get the first node connected to this edge.
EdgeIdSet edgeIds() const
NodeMetadata & getNodeMetadata(NodeId NId)
void disconnectEdge(EdgeId EId, NodeId NId)
Disconnect an edge from the given node.
typename RegAllocSolverImpl ::GraphMetadata GraphMetadata
const EdgeMetadata & getEdgeMetadata(EdgeId EId) const
NodeIdSet nodeIds() const
NodeEntry::AdjEdgeList::size_type size() const
NodeEntry::AdjEdgeItr end() const
unsigned getNumNodes() const
Get the number of nodes in the graph.
NodeId getEdgeOtherNodeId(EdgeId EId, NodeId NId)
Get the "other" node connected to this edge.
typename RegAllocSolverImpl ::Matrix Matrix
NodeId addNodeBypassingCostAllocator(OtherVectorPtrT Costs)
Add a node bypassing the cost allocator.
const Matrix & getEdgeCosts(EdgeId EId) const
Get an edge's cost matrix.
void removeNode(NodeId NId)
Remove a node from the graph.
AdjEdgeIdSet adjEdgeIds(NodeId NId)
const MatrixPtr & getEdgeCostsPtr(EdgeId EId) const
Get a MatrixPtr to a node's cost matrix.
NodeId getEdgeNode2Id(EdgeId EId) const
Get the second node connected to this edge.
unsigned getNumEdges() const
Get the number of edges in the graph.
typename NodeEntry::AdjEdgeItr AdjEdgeItr
const Vector & getNodeCosts(NodeId NId) const
Get a node's cost vector.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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.
bool operator==(const EdgeItr &O) 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.
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
const NodeMetadata & getNodeMetadata(NodeId NId) const
const VectorPtr & getNodeCostsPtr(NodeId NId) const
Get a VectorPtr to a node's cost vector.
Graph(GraphMetadata Metadata)
Construct an empty PBQP graph with the given graph metadata.
const GraphMetadata & getMetadata() const
Get a const-reference to the graph metadata.
NodeEntry::AdjEdgeList::size_type getNodeDegree(NodeId NId) const
bool operator!=(const EdgeItr &O) const
typename RegAllocSolverImpl ::RawVector RawVector
static EdgeId invalidEdgeId()
Returns a value representing an invalid (non-existent) edge.
void disconnectAllNeighborsFromNode(NodeId NId)
Convenience method to disconnect all neighbours from the given node.
typename RegAllocSolverImpl ::Vector Vector
EdgeMetadata & getEdgeMetadata(EdgeId EId)
typename CostAllocator::MatrixPtr MatrixPtr
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
typename RegAllocSolverImpl ::NodeMetadata NodeMetadata
NodeIdSet(const Graph &G)
std::forward_iterator_tag iterator_category
typename RegAllocSolverImpl ::RawMatrix RawMatrix
NodeId addNode(OtherVectorT Costs)
Add a node with the given costs.
void setNodeCosts(NodeId NId, OtherVectorT Costs)
Set a node's cost vector.
std::vector< uint32_t > Metadata
PAL metadata represented as a vector.
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.