blob: fd37f5cbb32014a0dbd98cb29674bf4af21476ad [file] [log] [blame]
Lang Hames3ca9a5b2009-08-06 23:32:48 +00001#ifndef LLVM_CODEGEN_PBQP_HEURISTICS_BRIGGS_H
2#define LLVM_CODEGEN_PBQP_HEURISTICS_BRIGGS_H
3
4#include "../HeuristicSolver.h"
5
6#include <set>
7
8namespace PBQP {
9namespace Heuristics {
10
11class Briggs {
12 public:
13
14 class NodeData;
15 class EdgeData;
16
17 private:
18
19 typedef HeuristicSolverImpl<Briggs> Solver;
20 typedef HSITypes<NodeData, EdgeData> HSIT;
21 typedef HSIT::SolverGraph SolverGraph;
22 typedef HSIT::GraphNodeIterator GraphNodeIterator;
23 typedef HSIT::GraphEdgeIterator GraphEdgeIterator;
24
25 class LinkDegreeComparator {
26 public:
27 LinkDegreeComparator() : g(0) {}
28 LinkDegreeComparator(SolverGraph *g) : g(g) {}
29
30 bool operator()(const GraphNodeIterator &node1Itr,
31 const GraphNodeIterator &node2Itr) const {
32 assert((g != 0) && "Graph object not set, cannot access node data.");
33 unsigned n1Degree = g->getNodeData(node1Itr).getLinkDegree(),
34 n2Degree = g->getNodeData(node2Itr).getLinkDegree();
35 if (n1Degree > n2Degree) {
36 return true;
37 }
38 else if (n1Degree < n2Degree) {
39 return false;
40 }
41 // else they're "equal" by degree, differentiate based on ID.
42 return g->getNodeID(node1Itr) < g->getNodeID(node2Itr);
43 }
44
45 private:
46 SolverGraph *g;
47 };
48
49 class SpillPriorityComparator {
50 public:
51 SpillPriorityComparator() : g(0) {}
52 SpillPriorityComparator(SolverGraph *g) : g(g) {}
53
54 bool operator()(const GraphNodeIterator &node1Itr,
55 const GraphNodeIterator &node2Itr) const {
56 assert((g != 0) && "Graph object not set, cannot access node data.");
57 PBQPNum cost1 =
58 g->getNodeCosts(node1Itr)[0] /
59 g->getNodeData(node1Itr).getLinkDegree(),
60 cost2 =
61 g->getNodeCosts(node2Itr)[0] /
62 g->getNodeData(node2Itr).getLinkDegree();
63
64 if (cost1 < cost2) {
65 return true;
66 }
67 else if (cost1 > cost2) {
68 return false;
69 }
70 // else they'er "equal" again, differentiate based on address again.
71 return g->getNodeID(node1Itr) < g->getNodeID(node2Itr);
72 }
73
74 private:
75 SolverGraph *g;
76 };
77
78 typedef std::set<GraphNodeIterator, LinkDegreeComparator>
79 RNAllocableNodeList;
80 typedef RNAllocableNodeList::iterator RNAllocableNodeListIterator;
81
82 typedef std::set<GraphNodeIterator, SpillPriorityComparator>
83 RNUnallocableNodeList;
84 typedef RNUnallocableNodeList::iterator RNUnallocableNodeListIterator;
85
86 public:
87
88 class NodeData {
89 private:
90 RNAllocableNodeListIterator rNAllocableNodeListItr;
91 RNUnallocableNodeListIterator rNUnallocableNodeListItr;
92 unsigned numRegOptions, numDenied, numSafe;
93 std::vector<unsigned> unsafeDegrees;
94 bool allocable;
95
96 void addRemoveLink(SolverGraph &g, const GraphNodeIterator &nodeItr,
97 const GraphEdgeIterator &edgeItr, bool add) {
98
99 //assume we're adding...
100 unsigned udTarget = 0, dir = 1;
101
102 if (!add) {
103 udTarget = 1;
104 dir = -1;
105 }
106
107 EdgeData &linkEdgeData = g.getEdgeData(edgeItr).getHeuristicData();
108
109 EdgeData::ConstUnsafeIterator edgeUnsafeBegin, edgeUnsafeEnd;
110
111 if (nodeItr == g.getEdgeNode1Itr(edgeItr)) {
112 numDenied += (dir * linkEdgeData.getWorstDegree());
113 edgeUnsafeBegin = linkEdgeData.unsafeBegin();
114 edgeUnsafeEnd = linkEdgeData.unsafeEnd();
115 }
116 else {
117 numDenied += (dir * linkEdgeData.getReverseWorstDegree());
118 edgeUnsafeBegin = linkEdgeData.reverseUnsafeBegin();
119 edgeUnsafeEnd = linkEdgeData.reverseUnsafeEnd();
120 }
121
122 assert((unsafeDegrees.size() ==
123 static_cast<unsigned>(
124 std::distance(edgeUnsafeBegin, edgeUnsafeEnd)))
125 && "Unsafe array size mismatch.");
126
127 std::vector<unsigned>::iterator unsafeDegreesItr =
128 unsafeDegrees.begin();
129
130 for (EdgeData::ConstUnsafeIterator edgeUnsafeItr = edgeUnsafeBegin;
131 edgeUnsafeItr != edgeUnsafeEnd;
132 ++edgeUnsafeItr, ++unsafeDegreesItr) {
133
134 if ((*edgeUnsafeItr == 1) && (*unsafeDegreesItr == udTarget)) {
135 numSafe -= dir;
136 }
137 *unsafeDegreesItr += (dir * (*edgeUnsafeItr));
138 }
139
140 allocable = (numDenied < numRegOptions) || (numSafe > 0);
141 }
142
143 public:
144
145 void setup(SolverGraph &g, const GraphNodeIterator &nodeItr) {
146
147 numRegOptions = g.getNodeCosts(nodeItr).getLength() - 1;
148
149 numSafe = numRegOptions; // Optimistic, correct below.
150 numDenied = 0; // Also optimistic.
151 unsafeDegrees.resize(numRegOptions, 0);
152
153 HSIT::NodeData &nodeData = g.getNodeData(nodeItr);
154
155 for (HSIT::NodeData::AdjLinkIterator
156 adjLinkItr = nodeData.adjLinksBegin(),
157 adjLinkEnd = nodeData.adjLinksEnd();
158 adjLinkItr != adjLinkEnd; ++adjLinkItr) {
159
160 addRemoveLink(g, nodeItr, *adjLinkItr, true);
161 }
162 }
163
164 bool isAllocable() const { return allocable; }
165
166 void handleAddLink(SolverGraph &g, const GraphNodeIterator &nodeItr,
167 const GraphEdgeIterator &adjEdge) {
168 addRemoveLink(g, nodeItr, adjEdge, true);
169 }
170
171 void handleRemoveLink(SolverGraph &g, const GraphNodeIterator &nodeItr,
172 const GraphEdgeIterator &adjEdge) {
173 addRemoveLink(g, nodeItr, adjEdge, false);
174 }
175
176 void setRNAllocableNodeListItr(
177 const RNAllocableNodeListIterator &rNAllocableNodeListItr) {
178
179 this->rNAllocableNodeListItr = rNAllocableNodeListItr;
180 }
181
182 RNAllocableNodeListIterator getRNAllocableNodeListItr() const {
183 return rNAllocableNodeListItr;
184 }
185
186 void setRNUnallocableNodeListItr(
187 const RNUnallocableNodeListIterator &rNUnallocableNodeListItr) {
188
189 this->rNUnallocableNodeListItr = rNUnallocableNodeListItr;
190 }
191
192 RNUnallocableNodeListIterator getRNUnallocableNodeListItr() const {
193 return rNUnallocableNodeListItr;
194 }
195
196
197 };
198
199 class EdgeData {
200 private:
201
202 typedef std::vector<unsigned> UnsafeArray;
203
204 unsigned worstDegree,
205 reverseWorstDegree;
206 UnsafeArray unsafe, reverseUnsafe;
207
208 public:
209
210 EdgeData() : worstDegree(0), reverseWorstDegree(0) {}
211
212 typedef UnsafeArray::const_iterator ConstUnsafeIterator;
213
214 void setup(SolverGraph &g, const GraphEdgeIterator &edgeItr) {
215 const Matrix &edgeCosts = g.getEdgeCosts(edgeItr);
216 unsigned numRegs = edgeCosts.getRows() - 1,
217 numReverseRegs = edgeCosts.getCols() - 1;
218
219 unsafe.resize(numRegs, 0);
220 reverseUnsafe.resize(numReverseRegs, 0);
221
222 std::vector<unsigned> rowInfCounts(numRegs, 0),
223 colInfCounts(numReverseRegs, 0);
224
225 for (unsigned i = 0; i < numRegs; ++i) {
226 for (unsigned j = 0; j < numReverseRegs; ++j) {
227 if (edgeCosts[i + 1][j + 1] ==
228 std::numeric_limits<PBQPNum>::infinity()) {
229 unsafe[i] = 1;
230 reverseUnsafe[j] = 1;
231 ++rowInfCounts[i];
232 ++colInfCounts[j];
233
234 if (colInfCounts[j] > worstDegree) {
235 worstDegree = colInfCounts[j];
236 }
237
238 if (rowInfCounts[i] > reverseWorstDegree) {
239 reverseWorstDegree = rowInfCounts[i];
240 }
241 }
242 }
243 }
244 }
245
246 unsigned getWorstDegree() const { return worstDegree; }
247 unsigned getReverseWorstDegree() const { return reverseWorstDegree; }
248 ConstUnsafeIterator unsafeBegin() const { return unsafe.begin(); }
249 ConstUnsafeIterator unsafeEnd() const { return unsafe.end(); }
250 ConstUnsafeIterator reverseUnsafeBegin() const {
251 return reverseUnsafe.begin();
252 }
253 ConstUnsafeIterator reverseUnsafeEnd() const {
254 return reverseUnsafe.end();
255 }
256 };
257
258 void initialise(Solver &solver) {
259 this->s = &solver;
260 g = &s->getGraph();
261 rNAllocableBucket = RNAllocableNodeList(LinkDegreeComparator(g));
262 rNUnallocableBucket =
263 RNUnallocableNodeList(SpillPriorityComparator(g));
264
265 for (GraphEdgeIterator
266 edgeItr = g->edgesBegin(), edgeEnd = g->edgesEnd();
267 edgeItr != edgeEnd; ++edgeItr) {
268
269 g->getEdgeData(edgeItr).getHeuristicData().setup(*g, edgeItr);
270 }
271
272 for (GraphNodeIterator
273 nodeItr = g->nodesBegin(), nodeEnd = g->nodesEnd();
274 nodeItr != nodeEnd; ++nodeItr) {
275
276 g->getNodeData(nodeItr).getHeuristicData().setup(*g, nodeItr);
277 }
278 }
279
280 void addToRNBucket(const GraphNodeIterator &nodeItr) {
281 NodeData &nodeData = g->getNodeData(nodeItr).getHeuristicData();
282
283 if (nodeData.isAllocable()) {
284 nodeData.setRNAllocableNodeListItr(
285 rNAllocableBucket.insert(rNAllocableBucket.begin(), nodeItr));
286 }
287 else {
288 nodeData.setRNUnallocableNodeListItr(
289 rNUnallocableBucket.insert(rNUnallocableBucket.begin(), nodeItr));
290 }
291 }
292
293 void removeFromRNBucket(const GraphNodeIterator &nodeItr) {
294 NodeData &nodeData = g->getNodeData(nodeItr).getHeuristicData();
295
296 if (nodeData.isAllocable()) {
297 rNAllocableBucket.erase(nodeData.getRNAllocableNodeListItr());
298 }
299 else {
300 rNUnallocableBucket.erase(nodeData.getRNUnallocableNodeListItr());
301 }
302 }
303
304 void handleAddLink(const GraphEdgeIterator &edgeItr) {
305 // We assume that if we got here this edge is attached to at least
306 // one high degree node.
307 g->getEdgeData(edgeItr).getHeuristicData().setup(*g, edgeItr);
308
309 GraphNodeIterator n1Itr = g->getEdgeNode1Itr(edgeItr),
310 n2Itr = g->getEdgeNode2Itr(edgeItr);
311
312 HSIT::NodeData &n1Data = g->getNodeData(n1Itr),
313 &n2Data = g->getNodeData(n2Itr);
314
315 if (n1Data.getLinkDegree() > 2) {
316 n1Data.getHeuristicData().handleAddLink(*g, n1Itr, edgeItr);
317 }
318 if (n2Data.getLinkDegree() > 2) {
319 n2Data.getHeuristicData().handleAddLink(*g, n2Itr, edgeItr);
320 }
321 }
322
323 void handleRemoveLink(const GraphEdgeIterator &edgeItr,
324 const GraphNodeIterator &nodeItr) {
325 NodeData &nodeData = g->getNodeData(nodeItr).getHeuristicData();
326 nodeData.handleRemoveLink(*g, nodeItr, edgeItr);
327 }
328
329 void processRN() {
330
331 /*
332 std::cerr << "processRN():\n"
333 << " rNAllocable = [ ";
334 for (RNAllocableNodeListIterator nItr = rNAllocableBucket.begin(),
335 nEnd = rNAllocableBucket.end();
336 nItr != nEnd; ++nItr) {
337 std::cerr << g->getNodeID(*nItr) << " (" << g->getNodeData(*nItr).getLinkDegree() << ") ";
338 }
339 std::cerr << "]\n"
340 << " rNUnallocable = [ ";
341 for (RNUnallocableNodeListIterator nItr = rNUnallocableBucket.begin(),
342 nEnd = rNUnallocableBucket.end();
343 nItr != nEnd; ++nItr) {
344 float bCost = g->getNodeCosts(*nItr)[0] / g->getNodeData(*nItr).getLinkDegree();
345 std::cerr << g->getNodeID(*nItr) << " (" << bCost << ") ";
346 }
347 std::cerr << "]\n";
348 */
349
350 if (!rNAllocableBucket.empty()) {
351 GraphNodeIterator selectedNodeItr = *rNAllocableBucket.begin();
352 //std::cerr << "RN safely pushing " << g->getNodeID(selectedNodeItr) << "\n";
353 rNAllocableBucket.erase(rNAllocableBucket.begin());
354 s->pushStack(selectedNodeItr);
355 s->unlinkNode(selectedNodeItr);
356 }
357 else {
358 GraphNodeIterator selectedNodeItr = *rNUnallocableBucket.begin();
359 //std::cerr << "RN optimistically pushing " << g->getNodeID(selectedNodeItr) << "\n";
360 rNUnallocableBucket.erase(rNUnallocableBucket.begin());
361 s->pushStack(selectedNodeItr);
362 s->unlinkNode(selectedNodeItr);
363 }
364
365 }
366
367 bool rNBucketEmpty() const {
368 return (rNAllocableBucket.empty() && rNUnallocableBucket.empty());
369 }
370
371private:
372
373 Solver *s;
374 SolverGraph *g;
375 RNAllocableNodeList rNAllocableBucket;
376 RNUnallocableNodeList rNUnallocableBucket;
377};
378
379
380
381}
382}
383
384
385#endif // LLVM_CODEGEN_PBQP_HEURISTICS_BRIGGS_H