Lang Hames | 98e6e6d | 2010-01-06 08:53:34 +0000 | [diff] [blame] | 1 | //===-- Briggs.h --- Briggs Heuristic for PBQP ------------------*- C++ -*-===// |
Lang Hames | 25e9651 | 2009-08-07 00:25:12 +0000 | [diff] [blame] | 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // This class implements the Briggs test for "allocability" of nodes in a |
| 11 | // PBQP graph representing a register allocation problem. Nodes which can be |
| 12 | // proven allocable (by a safe and relatively accurate test) are removed from |
| 13 | // the PBQP graph first. If no provably allocable node is present in the graph |
| 14 | // then the node with the minimal spill-cost to degree ratio is removed. |
| 15 | // |
| 16 | //===----------------------------------------------------------------------===// |
| 17 | |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 18 | #ifndef LLVM_CODEGEN_PBQP_HEURISTICS_BRIGGS_H |
| 19 | #define LLVM_CODEGEN_PBQP_HEURISTICS_BRIGGS_H |
| 20 | |
Chandler Carruth | 9f4185e | 2010-01-27 10:27:10 +0000 | [diff] [blame] | 21 | #include "llvm/Support/Compiler.h" |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 22 | #include "../HeuristicSolver.h" |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 23 | #include "../HeuristicBase.h" |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 24 | |
| 25 | #include <set> |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 26 | #include <limits> |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 27 | |
| 28 | namespace PBQP { |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 29 | namespace Heuristics { |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 30 | |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 31 | /// \brief PBQP Heuristic which applies an allocability test based on |
| 32 | /// Briggs. |
| 33 | /// |
| 34 | /// This heuristic assumes that the elements of cost vectors in the PBQP |
| 35 | /// problem represent storage options, with the first being the spill |
| 36 | /// option and subsequent elements representing legal registers for the |
| 37 | /// corresponding node. Edge cost matrices are likewise assumed to represent |
| 38 | /// register constraints. |
| 39 | /// If one or more nodes can be proven allocable by this heuristic (by |
| 40 | /// inspection of their constraint matrices) then the allocable node of |
| 41 | /// highest degree is selected for the next reduction and pushed to the |
| 42 | /// solver stack. If no nodes can be proven allocable then the node with |
| 43 | /// the lowest estimated spill cost is selected and push to the solver stack |
| 44 | /// instead. |
| 45 | /// |
| 46 | /// This implementation is built on top of HeuristicBase. |
| 47 | class Briggs : public HeuristicBase<Briggs> { |
| 48 | private: |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 49 | |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 50 | class LinkDegreeComparator { |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 51 | public: |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 52 | LinkDegreeComparator(HeuristicSolverImpl<Briggs> &s) : s(&s) {} |
| 53 | bool operator()(Graph::NodeItr n1Itr, Graph::NodeItr n2Itr) const { |
| 54 | if (s->getSolverDegree(n1Itr) > s->getSolverDegree(n2Itr)) |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 55 | return true; |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 56 | if (s->getSolverDegree(n1Itr) < s->getSolverDegree(n2Itr)) |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 57 | return false; |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 58 | return (&*n1Itr < &*n2Itr); |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 59 | } |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 60 | private: |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 61 | HeuristicSolverImpl<Briggs> *s; |
| 62 | }; |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 63 | |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 64 | class SpillCostComparator { |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 65 | public: |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 66 | SpillCostComparator(HeuristicSolverImpl<Briggs> &s) |
| 67 | : s(&s), g(&s.getGraph()) {} |
| 68 | bool operator()(Graph::NodeItr n1Itr, Graph::NodeItr n2Itr) const { |
| 69 | PBQPNum cost1 = g->getNodeCosts(n1Itr)[0] / s->getSolverDegree(n1Itr), |
| 70 | cost2 = g->getNodeCosts(n2Itr)[0] / s->getSolverDegree(n2Itr); |
| 71 | if (cost1 < cost2) |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 72 | return true; |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 73 | if (cost1 > cost2) |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 74 | return false; |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 75 | return (&*n1Itr < &*n2Itr); |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 76 | } |
| 77 | |
| 78 | private: |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 79 | HeuristicSolverImpl<Briggs> *s; |
| 80 | Graph *g; |
| 81 | }; |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 82 | |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 83 | typedef std::list<Graph::NodeItr> RNAllocableList; |
| 84 | typedef RNAllocableList::iterator RNAllocableListItr; |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 85 | |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 86 | typedef std::list<Graph::NodeItr> RNUnallocableList; |
| 87 | typedef RNUnallocableList::iterator RNUnallocableListItr; |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 88 | |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 89 | public: |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 90 | |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 91 | struct NodeData { |
| 92 | typedef std::vector<unsigned> UnsafeDegreesArray; |
| 93 | bool isHeuristic, isAllocable, isInitialized; |
| 94 | unsigned numDenied, numSafe; |
| 95 | UnsafeDegreesArray unsafeDegrees; |
| 96 | RNAllocableListItr rnaItr; |
| 97 | RNUnallocableListItr rnuItr; |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 98 | |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 99 | NodeData() |
| 100 | : isHeuristic(false), isAllocable(false), isInitialized(false), |
| 101 | numDenied(0), numSafe(0) { } |
| 102 | }; |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 103 | |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 104 | struct EdgeData { |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 105 | typedef std::vector<unsigned> UnsafeArray; |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 106 | unsigned worst, reverseWorst; |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 107 | UnsafeArray unsafe, reverseUnsafe; |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 108 | bool isUpToDate; |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 109 | |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 110 | EdgeData() : worst(0), reverseWorst(0), isUpToDate(false) {} |
| 111 | }; |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 112 | |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 113 | /// \brief Construct an instance of the Briggs heuristic. |
| 114 | /// @param solver A reference to the solver which is using this heuristic. |
| 115 | Briggs(HeuristicSolverImpl<Briggs> &solver) : |
| 116 | HeuristicBase<Briggs>(solver) {} |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 117 | |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 118 | /// \brief Determine whether a node should be reduced using optimal |
| 119 | /// reduction. |
| 120 | /// @param nItr Node iterator to be considered. |
| 121 | /// @return True if the given node should be optimally reduced, false |
| 122 | /// otherwise. |
| 123 | /// |
| 124 | /// Selects nodes of degree 0, 1 or 2 for optimal reduction, with one |
| 125 | /// exception. Nodes whose spill cost (element 0 of their cost vector) is |
| 126 | /// infinite are checked for allocability first. Allocable nodes may be |
| 127 | /// optimally reduced, but nodes whose allocability cannot be proven are |
| 128 | /// selected for heuristic reduction instead. |
| 129 | bool shouldOptimallyReduce(Graph::NodeItr nItr) { |
| 130 | if (getSolver().getSolverDegree(nItr) < 3) { |
Lang Hames | 4a08b90 | 2010-02-12 09:43:37 +0000 | [diff] [blame] | 131 | return true; |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 132 | } |
| 133 | // else |
| 134 | return false; |
| 135 | } |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 136 | |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 137 | /// \brief Add a node to the heuristic reduce list. |
| 138 | /// @param nItr Node iterator to add to the heuristic reduce list. |
| 139 | void addToHeuristicReduceList(Graph::NodeItr nItr) { |
| 140 | NodeData &nd = getHeuristicNodeData(nItr); |
| 141 | initializeNode(nItr); |
| 142 | nd.isHeuristic = true; |
| 143 | if (nd.isAllocable) { |
| 144 | nd.rnaItr = rnAllocableList.insert(rnAllocableList.end(), nItr); |
| 145 | } else { |
| 146 | nd.rnuItr = rnUnallocableList.insert(rnUnallocableList.end(), nItr); |
| 147 | } |
| 148 | } |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 149 | |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 150 | /// \brief Heuristically reduce one of the nodes in the heuristic |
| 151 | /// reduce list. |
| 152 | /// @return True if a reduction takes place, false if the heuristic reduce |
| 153 | /// list is empty. |
| 154 | /// |
| 155 | /// If the list of allocable nodes is non-empty a node is selected |
| 156 | /// from it and pushed to the stack. Otherwise if the non-allocable list |
| 157 | /// is non-empty a node is selected from it and pushed to the stack. |
| 158 | /// If both lists are empty the method simply returns false with no action |
| 159 | /// taken. |
| 160 | bool heuristicReduce() { |
| 161 | if (!rnAllocableList.empty()) { |
| 162 | RNAllocableListItr rnaItr = |
| 163 | min_element(rnAllocableList.begin(), rnAllocableList.end(), |
| 164 | LinkDegreeComparator(getSolver())); |
| 165 | Graph::NodeItr nItr = *rnaItr; |
| 166 | rnAllocableList.erase(rnaItr); |
| 167 | handleRemoveNode(nItr); |
| 168 | getSolver().pushToStack(nItr); |
| 169 | return true; |
| 170 | } else if (!rnUnallocableList.empty()) { |
| 171 | RNUnallocableListItr rnuItr = |
| 172 | min_element(rnUnallocableList.begin(), rnUnallocableList.end(), |
| 173 | SpillCostComparator(getSolver())); |
| 174 | Graph::NodeItr nItr = *rnuItr; |
| 175 | rnUnallocableList.erase(rnuItr); |
| 176 | handleRemoveNode(nItr); |
| 177 | getSolver().pushToStack(nItr); |
| 178 | return true; |
| 179 | } |
| 180 | // else |
| 181 | return false; |
| 182 | } |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 183 | |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 184 | /// \brief Prepare a change in the costs on the given edge. |
| 185 | /// @param eItr Edge iterator. |
| 186 | void preUpdateEdgeCosts(Graph::EdgeItr eItr) { |
| 187 | Graph &g = getGraph(); |
| 188 | Graph::NodeItr n1Itr = g.getEdgeNode1(eItr), |
| 189 | n2Itr = g.getEdgeNode2(eItr); |
| 190 | NodeData &n1 = getHeuristicNodeData(n1Itr), |
| 191 | &n2 = getHeuristicNodeData(n2Itr); |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 192 | |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 193 | if (n1.isHeuristic) |
| 194 | subtractEdgeContributions(eItr, getGraph().getEdgeNode1(eItr)); |
| 195 | if (n2.isHeuristic) |
| 196 | subtractEdgeContributions(eItr, getGraph().getEdgeNode2(eItr)); |
| 197 | |
| 198 | EdgeData &ed = getHeuristicEdgeData(eItr); |
| 199 | ed.isUpToDate = false; |
| 200 | } |
| 201 | |
| 202 | /// \brief Handle the change in the costs on the given edge. |
| 203 | /// @param eItr Edge iterator. |
| 204 | void postUpdateEdgeCosts(Graph::EdgeItr eItr) { |
| 205 | // This is effectively the same as adding a new edge now, since |
| 206 | // we've factored out the costs of the old one. |
| 207 | handleAddEdge(eItr); |
| 208 | } |
| 209 | |
| 210 | /// \brief Handle the addition of a new edge into the PBQP graph. |
| 211 | /// @param eItr Edge iterator for the added edge. |
| 212 | /// |
| 213 | /// Updates allocability of any nodes connected by this edge which are |
| 214 | /// being managed by the heuristic. If allocability changes they are |
| 215 | /// moved to the appropriate list. |
| 216 | void handleAddEdge(Graph::EdgeItr eItr) { |
| 217 | Graph &g = getGraph(); |
| 218 | Graph::NodeItr n1Itr = g.getEdgeNode1(eItr), |
| 219 | n2Itr = g.getEdgeNode2(eItr); |
| 220 | NodeData &n1 = getHeuristicNodeData(n1Itr), |
| 221 | &n2 = getHeuristicNodeData(n2Itr); |
| 222 | |
| 223 | // If neither node is managed by the heuristic there's nothing to be |
| 224 | // done. |
| 225 | if (!n1.isHeuristic && !n2.isHeuristic) |
| 226 | return; |
| 227 | |
| 228 | // Ok - we need to update at least one node. |
| 229 | computeEdgeContributions(eItr); |
| 230 | |
| 231 | // Update node 1 if it's managed by the heuristic. |
| 232 | if (n1.isHeuristic) { |
| 233 | bool n1WasAllocable = n1.isAllocable; |
| 234 | addEdgeContributions(eItr, n1Itr); |
| 235 | updateAllocability(n1Itr); |
| 236 | if (n1WasAllocable && !n1.isAllocable) { |
| 237 | rnAllocableList.erase(n1.rnaItr); |
| 238 | n1.rnuItr = |
| 239 | rnUnallocableList.insert(rnUnallocableList.end(), n1Itr); |
| 240 | } |
| 241 | } |
| 242 | |
| 243 | // Likewise for node 2. |
| 244 | if (n2.isHeuristic) { |
| 245 | bool n2WasAllocable = n2.isAllocable; |
| 246 | addEdgeContributions(eItr, n2Itr); |
| 247 | updateAllocability(n2Itr); |
| 248 | if (n2WasAllocable && !n2.isAllocable) { |
| 249 | rnAllocableList.erase(n2.rnaItr); |
| 250 | n2.rnuItr = |
| 251 | rnUnallocableList.insert(rnUnallocableList.end(), n2Itr); |
| 252 | } |
| 253 | } |
| 254 | } |
| 255 | |
| 256 | /// \brief Handle disconnection of an edge from a node. |
| 257 | /// @param eItr Edge iterator for edge being disconnected. |
| 258 | /// @param nItr Node iterator for the node being disconnected from. |
| 259 | /// |
| 260 | /// Updates allocability of the given node and, if appropriate, moves the |
| 261 | /// node to a new list. |
| 262 | void handleRemoveEdge(Graph::EdgeItr eItr, Graph::NodeItr nItr) { |
| 263 | NodeData &nd = getHeuristicNodeData(nItr); |
| 264 | |
| 265 | // If the node is not managed by the heuristic there's nothing to be |
| 266 | // done. |
| 267 | if (!nd.isHeuristic) |
| 268 | return; |
| 269 | |
Chandler Carruth | 9f4185e | 2010-01-27 10:27:10 +0000 | [diff] [blame] | 270 | EdgeData &ed ATTRIBUTE_UNUSED = getHeuristicEdgeData(eItr); |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 271 | |
| 272 | assert(ed.isUpToDate && "Edge data is not up to date."); |
| 273 | |
| 274 | // Update node. |
| 275 | bool ndWasAllocable = nd.isAllocable; |
| 276 | subtractEdgeContributions(eItr, nItr); |
| 277 | updateAllocability(nItr); |
| 278 | |
| 279 | // If the node has gone optimal... |
| 280 | if (shouldOptimallyReduce(nItr)) { |
| 281 | nd.isHeuristic = false; |
| 282 | addToOptimalReduceList(nItr); |
| 283 | if (ndWasAllocable) { |
| 284 | rnAllocableList.erase(nd.rnaItr); |
| 285 | } else { |
| 286 | rnUnallocableList.erase(nd.rnuItr); |
| 287 | } |
| 288 | } else { |
| 289 | // Node didn't go optimal, but we might have to move it |
| 290 | // from "unallocable" to "allocable". |
| 291 | if (!ndWasAllocable && nd.isAllocable) { |
| 292 | rnUnallocableList.erase(nd.rnuItr); |
| 293 | nd.rnaItr = rnAllocableList.insert(rnAllocableList.end(), nItr); |
| 294 | } |
| 295 | } |
| 296 | } |
| 297 | |
| 298 | private: |
| 299 | |
| 300 | NodeData& getHeuristicNodeData(Graph::NodeItr nItr) { |
| 301 | return getSolver().getHeuristicNodeData(nItr); |
| 302 | } |
| 303 | |
| 304 | EdgeData& getHeuristicEdgeData(Graph::EdgeItr eItr) { |
| 305 | return getSolver().getHeuristicEdgeData(eItr); |
| 306 | } |
| 307 | |
| 308 | // Work out what this edge will contribute to the allocability of the |
| 309 | // nodes connected to it. |
| 310 | void computeEdgeContributions(Graph::EdgeItr eItr) { |
| 311 | EdgeData &ed = getHeuristicEdgeData(eItr); |
| 312 | |
| 313 | if (ed.isUpToDate) |
| 314 | return; // Edge data is already up to date. |
| 315 | |
| 316 | Matrix &eCosts = getGraph().getEdgeCosts(eItr); |
| 317 | |
| 318 | unsigned numRegs = eCosts.getRows() - 1, |
| 319 | numReverseRegs = eCosts.getCols() - 1; |
| 320 | |
| 321 | std::vector<unsigned> rowInfCounts(numRegs, 0), |
| 322 | colInfCounts(numReverseRegs, 0); |
| 323 | |
| 324 | ed.worst = 0; |
| 325 | ed.reverseWorst = 0; |
| 326 | ed.unsafe.clear(); |
| 327 | ed.unsafe.resize(numRegs, 0); |
| 328 | ed.reverseUnsafe.clear(); |
| 329 | ed.reverseUnsafe.resize(numReverseRegs, 0); |
| 330 | |
| 331 | for (unsigned i = 0; i < numRegs; ++i) { |
| 332 | for (unsigned j = 0; j < numReverseRegs; ++j) { |
| 333 | if (eCosts[i + 1][j + 1] == |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 334 | std::numeric_limits<PBQPNum>::infinity()) { |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 335 | ed.unsafe[i] = 1; |
| 336 | ed.reverseUnsafe[j] = 1; |
| 337 | ++rowInfCounts[i]; |
| 338 | ++colInfCounts[j]; |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 339 | |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 340 | if (colInfCounts[j] > ed.worst) { |
| 341 | ed.worst = colInfCounts[j]; |
| 342 | } |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 343 | |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 344 | if (rowInfCounts[i] > ed.reverseWorst) { |
| 345 | ed.reverseWorst = rowInfCounts[i]; |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 346 | } |
| 347 | } |
| 348 | } |
| 349 | } |
| 350 | |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 351 | ed.isUpToDate = true; |
| 352 | } |
| 353 | |
| 354 | // Add the contributions of the given edge to the given node's |
| 355 | // numDenied and safe members. No action is taken other than to update |
| 356 | // these member values. Once updated these numbers can be used by clients |
| 357 | // to update the node's allocability. |
| 358 | void addEdgeContributions(Graph::EdgeItr eItr, Graph::NodeItr nItr) { |
| 359 | EdgeData &ed = getHeuristicEdgeData(eItr); |
| 360 | |
| 361 | assert(ed.isUpToDate && "Using out-of-date edge numbers."); |
| 362 | |
| 363 | NodeData &nd = getHeuristicNodeData(nItr); |
| 364 | unsigned numRegs = getGraph().getNodeCosts(nItr).getLength() - 1; |
| 365 | |
| 366 | bool nIsNode1 = nItr == getGraph().getEdgeNode1(eItr); |
| 367 | EdgeData::UnsafeArray &unsafe = |
| 368 | nIsNode1 ? ed.unsafe : ed.reverseUnsafe; |
| 369 | nd.numDenied += nIsNode1 ? ed.worst : ed.reverseWorst; |
| 370 | |
| 371 | for (unsigned r = 0; r < numRegs; ++r) { |
| 372 | if (unsafe[r]) { |
| 373 | if (nd.unsafeDegrees[r]==0) { |
| 374 | --nd.numSafe; |
| 375 | } |
| 376 | ++nd.unsafeDegrees[r]; |
| 377 | } |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 378 | } |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 379 | } |
| 380 | |
| 381 | // Subtract the contributions of the given edge to the given node's |
| 382 | // numDenied and safe members. No action is taken other than to update |
| 383 | // these member values. Once updated these numbers can be used by clients |
| 384 | // to update the node's allocability. |
| 385 | void subtractEdgeContributions(Graph::EdgeItr eItr, Graph::NodeItr nItr) { |
| 386 | EdgeData &ed = getHeuristicEdgeData(eItr); |
| 387 | |
| 388 | assert(ed.isUpToDate && "Using out-of-date edge numbers."); |
| 389 | |
| 390 | NodeData &nd = getHeuristicNodeData(nItr); |
| 391 | unsigned numRegs = getGraph().getNodeCosts(nItr).getLength() - 1; |
| 392 | |
| 393 | bool nIsNode1 = nItr == getGraph().getEdgeNode1(eItr); |
| 394 | EdgeData::UnsafeArray &unsafe = |
| 395 | nIsNode1 ? ed.unsafe : ed.reverseUnsafe; |
| 396 | nd.numDenied -= nIsNode1 ? ed.worst : ed.reverseWorst; |
| 397 | |
| 398 | for (unsigned r = 0; r < numRegs; ++r) { |
| 399 | if (unsafe[r]) { |
| 400 | if (nd.unsafeDegrees[r] == 1) { |
| 401 | ++nd.numSafe; |
| 402 | } |
| 403 | --nd.unsafeDegrees[r]; |
| 404 | } |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 405 | } |
Lang Hames | 408dcd3 | 2010-01-26 04:49:58 +0000 | [diff] [blame] | 406 | } |
| 407 | |
| 408 | void updateAllocability(Graph::NodeItr nItr) { |
| 409 | NodeData &nd = getHeuristicNodeData(nItr); |
| 410 | unsigned numRegs = getGraph().getNodeCosts(nItr).getLength() - 1; |
| 411 | nd.isAllocable = nd.numDenied < numRegs || nd.numSafe > 0; |
| 412 | } |
| 413 | |
| 414 | void initializeNode(Graph::NodeItr nItr) { |
| 415 | NodeData &nd = getHeuristicNodeData(nItr); |
| 416 | |
| 417 | if (nd.isInitialized) |
| 418 | return; // Node data is already up to date. |
| 419 | |
| 420 | unsigned numRegs = getGraph().getNodeCosts(nItr).getLength() - 1; |
| 421 | |
| 422 | nd.numDenied = 0; |
| 423 | nd.numSafe = numRegs; |
| 424 | nd.unsafeDegrees.resize(numRegs, 0); |
| 425 | |
| 426 | typedef HeuristicSolverImpl<Briggs>::SolverEdgeItr SolverEdgeItr; |
| 427 | |
| 428 | for (SolverEdgeItr aeItr = getSolver().solverEdgesBegin(nItr), |
| 429 | aeEnd = getSolver().solverEdgesEnd(nItr); |
| 430 | aeItr != aeEnd; ++aeItr) { |
| 431 | |
| 432 | Graph::EdgeItr eItr = *aeItr; |
| 433 | computeEdgeContributions(eItr); |
| 434 | addEdgeContributions(eItr, nItr); |
| 435 | } |
| 436 | |
| 437 | updateAllocability(nItr); |
| 438 | nd.isInitialized = true; |
| 439 | } |
| 440 | |
| 441 | void handleRemoveNode(Graph::NodeItr xnItr) { |
| 442 | typedef HeuristicSolverImpl<Briggs>::SolverEdgeItr SolverEdgeItr; |
| 443 | std::vector<Graph::EdgeItr> edgesToRemove; |
| 444 | for (SolverEdgeItr aeItr = getSolver().solverEdgesBegin(xnItr), |
| 445 | aeEnd = getSolver().solverEdgesEnd(xnItr); |
| 446 | aeItr != aeEnd; ++aeItr) { |
| 447 | Graph::NodeItr ynItr = getGraph().getEdgeOtherNode(*aeItr, xnItr); |
| 448 | handleRemoveEdge(*aeItr, ynItr); |
| 449 | edgesToRemove.push_back(*aeItr); |
| 450 | } |
| 451 | while (!edgesToRemove.empty()) { |
| 452 | getSolver().removeSolverEdge(edgesToRemove.back()); |
| 453 | edgesToRemove.pop_back(); |
| 454 | } |
| 455 | } |
| 456 | |
| 457 | RNAllocableList rnAllocableList; |
| 458 | RNUnallocableList rnUnallocableList; |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 459 | }; |
| 460 | |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 461 | } |
Lang Hames | 3ca9a5b | 2009-08-06 23:32:48 +0000 | [diff] [blame] | 462 | } |
| 463 | |
| 464 | |
| 465 | #endif // LLVM_CODEGEN_PBQP_HEURISTICS_BRIGGS_H |