llvm.org GIT mirror llvm / ec97f95
Change the PBQP graph adjacency list structure from std::set to std::vector. The edge data structure (EdgeEntry) now holds the indices of its entries in the adjacency lists of the nodes it connects. This trades a little ugliness for faster insertion/removal, which is now O(1) with a cheap constant factor. All of this is implementation detail within the PBQP graph, the external API remains unchanged. Individual register allocations are likely to change, since the adjacency lists will now be ordered differently (or rather, will now be unordered). This shouldn't affect the average quality of allocations however. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204841 91177308-0d34-0410-b5e6-96231b3b80d8 Lang Hames 6 years ago
1 changed file(s) with 106 addition(s) and 22 deletion(s). Raw diff Collapse all Expand all
5050
5151 class NodeEntry {
5252 public:
53 typedef std::seteId> AdjEdgeList;
53 typedef std::vectoreId> AdjEdgeList;
54 typedef AdjEdgeList::size_type AdjEdgeIdx;
5455 typedef AdjEdgeList::const_iterator AdjEdgeItr;
56
57 static AdjEdgeIdx getInvalidAdjEdgeIdx() {
58 return std::numeric_limits::max();
59 }
60
5561 NodeEntry(VectorPtr Costs) : Costs(Costs) {}
62
63 AdjEdgeIdx addAdjEdgeId(EdgeId EId) {
64 AdjEdgeIdx Idx = AdjEdgeIds.size();
65 AdjEdgeIds.push_back(EId);
66 return Idx;
67 }
68
69 // If a swap is performed, returns the new EdgeId that must be
70 // updated, otherwise returns invalidEdgeId().
71 EdgeId removeAdjEdgeId(AdjEdgeIdx Idx) {
72 EdgeId EIdToUpdate = Graph::invalidEdgeId();
73 if (Idx < AdjEdgeIds.size() - 1) {
74 std::swap(AdjEdgeIds[Idx], AdjEdgeIds.back());
75 EIdToUpdate = AdjEdgeIds[Idx];
76 }
77 AdjEdgeIds.pop_back();
78 return EIdToUpdate;
79 }
80
81 const AdjEdgeList& getAdjEdgeIds() const { return AdjEdgeIds; }
5682
5783 VectorPtr Costs;
5884 NodeMetadata Metadata;
85 private:
5986 AdjEdgeList AdjEdgeIds;
6087 };
6188
6289 class EdgeEntry {
6390 public:
6491 EdgeEntry(NodeId N1Id, NodeId N2Id, MatrixPtr Costs)
65 : Costs(Costs), N1Id(N1Id), N2Id(N2Id) {}
92 : Costs(Costs) {
93 NIds[0] = N1Id;
94 NIds[1] = N2Id;
95 ThisEdgeAdjIdxs[0] = NodeEntry::getInvalidAdjEdgeIdx();
96 ThisEdgeAdjIdxs[1] = NodeEntry::getInvalidAdjEdgeIdx();
97 }
98
6699 void invalidate() {
67 N1Id = N2Id = Graph::invalidNodeId();
100 NIds[0] = NIds[1] = Graph::invalidNodeId();
101 ThisEdgeAdjIdxs[0] = ThisEdgeAdjIdxs[1] =
102 NodeEntry::getInvalidAdjEdgeIdx();
68103 Costs = nullptr;
69104 }
70 NodeId getN1Id() const { return N1Id; }
71 NodeId getN2Id() const { return N2Id; }
105
106 void connectToN(Graph &G, EdgeId ThisEdgeId, unsigned NIdx) {
107 assert(ThisEdgeAdjIdxs[NIdx] == NodeEntry::getInvalidAdjEdgeIdx() &&
108 "Edge already connected to NIds[NIdx].");
109 NodeEntry &N = G.getNode(NIds[NIdx]);
110 ThisEdgeAdjIdxs[NIdx] = N.addAdjEdgeId(ThisEdgeId);
111 }
112
113 void connectTo(Graph &G, EdgeId ThisEdgeId, NodeId NId) {
114 if (NId == NIds[0])
115 connectToN(G, ThisEdgeId, 0);
116 else {
117 assert(NId == NIds[1] && "Edge does not connect NId.");
118 connectToN(G, ThisEdgeId, 1);
119 }
120 }
121
122 void connect(Graph &G, EdgeId ThisEdgeId) {
123 connectToN(G, ThisEdgeId, 0);
124 connectToN(G, ThisEdgeId, 1);
125 }
126
127 void updateAdjEdgeIdx(NodeId NId, typename NodeEntry::AdjEdgeIdx NewIdx) {
128 if (NId == NIds[0])
129 ThisEdgeAdjIdxs[0] = NewIdx;
130 else {
131 assert(NId == NIds[1] && "Edge not connected to NId");
132 ThisEdgeAdjIdxs[1] = NewIdx;
133 }
134 }
135
136 void disconnectFromN(Graph &G, unsigned NIdx) {
137 assert(ThisEdgeAdjIdxs[NIdx] != NodeEntry::getInvalidAdjEdgeIdx() &&
138 "Edge not connected to NIds[NIdx].");
139 NodeEntry &N = G.getNode(NIds[NIdx]);
140 EdgeId EIdToUpdate = N.removeAdjEdgeId(ThisEdgeAdjIdxs[NIdx]);
141 if (EIdToUpdate != Graph::invalidEdgeId())
142 G.getEdge(EIdToUpdate).updateAdjEdgeIdx(NIds[NIdx], ThisEdgeAdjIdxs[NIdx]);
143 ThisEdgeAdjIdxs[NIdx] = NodeEntry::getInvalidAdjEdgeIdx();
144 }
145
146 void disconnectFrom(Graph &G, NodeId NId) {
147 if (NId == NIds[0])
148 disconnectFromN(G, 0);
149 else {
150 assert(NId == NIds[1] && "Edge does not connect NId");
151 disconnectFromN(G, 1);
152 }
153 }
154
155 NodeId getN1Id() const { return NIds[0]; }
156 NodeId getN2Id() const { return NIds[1]; }
72157 MatrixPtr Costs;
73158 EdgeMetadata Metadata;
74159 private:
75 NodeId N1Id, N2Id;
160 NodeId NIds[2];
161 typename NodeEntry::AdjEdgeIdx ThisEdgeAdjIdxs[2];
76162 };
77163
78164 // ----- MEMBERS -----
133219 (N2.Costs->getLength() == NE.Costs->getCols()) &&
134220 "Edge cost dimensions do not match node costs dimensions.");
135221
136 N1.AdjEdgeIds.insert(EId);
137 N2.AdjEdgeIds.insert(EId);
222 // Add the edge to the adjacency sets of its nodes.
223 NE.connect(*this, EId);
138224 return EId;
139225 }
140226
227313 public:
228314 AdjEdgeIdSet(const NodeEntry &NE) : NE(NE) { }
229315 typename NodeEntry::AdjEdgeItr begin() const {
230 return NE.AdjEdgeIds.begin();
316 return NE.getAdjEdgeIds().begin();
231317 }
232318 typename NodeEntry::AdjEdgeItr end() const {
233 return NE.AdjEdgeIds.end();
234 }
235 bool empty() const { return NE.AdjEdges.empty(); }
319 return NE.getAdjEdgeIds().end();
320 }
321 bool empty() const { return NE.getAdjEdgeIds().empty(); }
236322 typename NodeEntry::AdjEdgeList::size_type size() const {
237 return NE.AdjEdgeIds.size();
323 return NE.getAdjEdgeIds().size();
238324 }
239325 private:
240326 const NodeEntry &NE;
335421 }
336422
337423 typename NodeEntry::AdjEdgeList::size_type getNodeDegree(NodeId NId) const {
338 return getNode(NId).AdjEdgeIds.size();
424 return getNode(NId).getAdjEdgeIds().size();
339425 }
340426
341427 /// \brief Set an edge's cost matrix.
458544 void disconnectEdge(EdgeId EId, NodeId NId) {
459545 if (Solver)
460546 Solver->handleDisconnectEdge(EId, NId);
461 NodeEntry &N = getNode(NId);
462 N.AdjEdgeIds.erase(EId);
547
548 EdgeEntry &E = getEdge(EId);
549 E.disconnectFrom(*this, NId);
463550 }
464551
465552 /// \brief Convenience method to disconnect all neighbours from the given
474561 /// Adds an edge that had been previously disconnected back into the
475562 /// adjacency set of the nodes that the edge connects.
476563 void reconnectEdge(EdgeId EId, NodeId NId) {
477 NodeEntry &N = getNode(NId);
478 N.addAdjEdge(EId);
564 EdgeEntry &E = getEdge(EId);
565 E.connectTo(*this, EId, NId);
479566 if (Solver)
480567 Solver->handleReconnectEdge(EId, NId);
481568 }
486573 if (Solver)
487574 Solver->handleRemoveEdge(EId);
488575 EdgeEntry &E = getEdge(EId);
489 NodeEntry &N1 = getNode(E.getNode1());
490 NodeEntry &N2 = getNode(E.getNode2());
491 N1.removeEdge(EId);
492 N2.removeEdge(EId);
576 E.disconnect();
493577 FreeEdgeIds.push_back(EId);
494578 Edges[EId].invalidate();
495579 }