1 cananian 1.1.2.1 /* 2 cananian 1.1.2.1 * RegAlloc/Color.java 3 cananian 1.1.2.1 * graph coloring algorithm for register allocation. 4 cananian 1.1.2.1 * 5 cananian 1.1.2.1 * ALGORITHM: Worklist-based algorithm described in 6 cananian 1.1.2.1 * 'Modern Compiler Implementation in Java' 7 cananian 1.1.2.1 * 8 cananian 1.1.2.1 * C. Scott Ananian, cananian@princeton.edu, COS320 9 cananian 1.1.2.1 */ 10 cananian 1.1.2.1 11 cananian 1.1.2.2 package harpoon.Backend.CSAHack.RegAlloc; 12 cananian 1.1.2.1 13 cananian 1.1.2.2 import harpoon.Backend.CSAHack.Graph.Node; 14 cananian 1.1.2.2 import harpoon.Backend.CSAHack.Graph.NodeList; 15 cananian 1.1.2.1 16 cananian 1.1.2.3 import harpoon.Backend.CSAHack.RegAlloc.RegWork.Moves; 17 cananian 1.1.2.3 import harpoon.Backend.CSAHack.RegAlloc.RegWork.NodeSet; 18 cananian 1.1.2.3 19 cananian 1.1.2.2 import harpoon.Temp.Temp; 20 cananian 1.1.2.2 import harpoon.Temp.TempList; 21 cananian 1.1.2.2 import harpoon.Temp.TempMap; 22 cananian 1.1.2.1 23 cananian 1.1.2.2 import harpoon.Backend.CSAHack.FlowGraph.FlowGraph; 24 cananian 1.1.2.5 import harpoon.Util.Util; 25 cananian 1.1.2.1 26 cananian 1.1.2.1 import java.util.Vector; 27 cananian 1.1.2.1 import java.util.Hashtable; 28 cananian 1.1.2.1 29 cananian 1.1.2.1 /** 30 cananian 1.1.2.1 * Graph coloring algorithm for register allocation. 31 cananian 1.1.2.1 * @version 1.00, 25 Nov 1996 32 cananian 1.1.2.1 * @author C. Scott Ananian 33 cananian 1.1.2.1 * @see RegAlloc.RegAlloc 34 cananian 1.1.2.1 */ 35 cananian 1.1.2.2 class Color implements TempMap { 36 cananian 1.1.2.1 FlowGraph flow; 37 cananian 1.1.2.1 InterferenceGraph ig; 38 cananian 1.1.2.1 TempList registers; 39 cananian 1.1.2.1 TempMap initial; 40 cananian 1.1.2.1 Vector reg = new Vector(); // vector of register temps 41 cananian 1.1.2.1 int K; // number of registers 42 cananian 1.1.2.1 43 cananian 1.1.2.1 boolean debug = false; // en-/dis- able debugging information. 44 cananian 1.1.2.1 45 cananian 1.1.2.1 /** 46 cananian 1.1.2.1 * @return TempList of spilled registers 47 cananian 1.1.2.1 */ 48 cananian 1.1.2.1 public TempList spills() { 49 cananian 1.1.2.1 TempList r = null; 50 cananian 1.1.2.1 for (NodeList nl = sets.spilled.nodes(); nl!=null; nl=nl.tail) 51 cananian 1.1.2.1 r = new TempList(ig.gtemp(nl.head), r); 52 cananian 1.1.2.1 return r; 53 cananian 1.1.2.1 } 54 cananian 1.1.2.1 55 cananian 1.1.2.1 /** 56 cananian 1.1.2.1 * Color an interference graph. 57 cananian 1.1.2.1 * @param flow flow graph defining moves able to be coalesced 58 cananian 1.1.2.1 * @param ig interference graph for the temporaries 59 cananian 1.1.2.1 * @param initial Initial coloring of machine registers 60 cananian 1.1.2.1 * @param registers List of pre-colored machine registers. 61 cananian 1.1.2.1 */ 62 cananian 1.1.2.1 public Color(FlowGraph flow, 63 cananian 1.1.2.1 InterferenceGraph ig, 64 cananian 1.1.2.1 TempMap initial, 65 cananian 1.1.2.1 TempList registers) { 66 cananian 1.1.2.1 this.flow = flow; 67 cananian 1.1.2.1 this.ig = ig; 68 cananian 1.1.2.1 this.registers = registers; 69 cananian 1.1.2.1 this.initial = initial; 70 cananian 1.1.2.1 // Set K to the number of registers 71 cananian 1.1.2.2 for (TempList tl = registers; tl!=null; tl=tl.tail) 72 cananian 1.1.2.1 reg.addElement(tl.head); 73 cananian 1.1.2.1 K = reg.size(); 74 cananian 1.1.2.1 75 cananian 1.1.2.1 main(); 76 cananian 1.1.2.1 } 77 cananian 1.1.2.1 78 cananian 1.1.2.1 private void main() { 79 cananian 1.1.2.1 Build(); 80 cananian 1.1.2.1 check(); 81 cananian 1.1.2.1 MakeWorklist(); 82 cananian 1.1.2.1 check(); 83 cananian 1.1.2.1 84 cananian 1.1.2.1 do { 85 cananian 1.1.2.1 if (!sets.worklist.simplify.empty()) {Simplify();check();} 86 cananian 1.1.2.1 else if (!moves.worklist.empty()) {Coalesce();check();} 87 cananian 1.1.2.1 else if (!sets.worklist.freeze.empty()) {Freeze(); check();} 88 cananian 1.1.2.1 else if (!sets.worklist.spill.empty()) {SelectSpill();check();} 89 cananian 1.1.2.1 } while (!(sets.worklist.simplify.empty() && 90 cananian 1.1.2.1 sets.worklist.freeze.empty() && 91 cananian 1.1.2.1 sets.worklist.spill.empty() && 92 cananian 1.1.2.1 moves.worklist.empty())); 93 cananian 1.1.2.1 94 cananian 1.1.2.1 check(); 95 cananian 1.1.2.1 AssignColors(); 96 cananian 1.1.2.1 97 cananian 1.1.2.1 } 98 cananian 1.1.2.1 99 cananian 1.1.2.1 private Moves moves; 100 cananian 1.1.2.1 private NodeSet sets; 101 cananian 1.1.2.1 102 cananian 1.1.2.1 private Hashtable moveList, degree; 103 cananian 1.1.2.1 private Hashtable alias, color; 104 cananian 1.1.2.1 105 cananian 1.1.2.1 void Build() { 106 cananian 1.1.2.1 alias = new Hashtable(); 107 cananian 1.1.2.1 sets = new NodeSet(registers, ig); 108 cananian 1.1.2.1 moves = new Moves(flow); 109 cananian 1.1.2.1 110 cananian 1.1.2.1 // Create mapping of interference graph node to the move instruction 111 cananian 1.1.2.1 // nodes it is associated with. 112 cananian 1.1.2.1 moveList = new Hashtable(); 113 cananian 1.1.2.1 for (NodeList nl = flow.nodes(); nl!=null; nl=nl.tail) { 114 cananian 1.1.2.1 if (flow.isMove(nl.head)) { 115 cananian 1.1.2.2 for (TempList tl = merge(flow.use(nl.head),flow.def(nl.head)); 116 cananian 1.1.2.1 tl!=null; tl=tl.tail) { 117 cananian 1.1.2.2 Node tempnode = ig.tnode(tl.head); 118 cananian 1.1.2.1 // quick error check hack 119 cananian 1.1.2.1 if (tempnode == null) // this should never happen! 120 cananian 1.1.2.1 throw new Error("Interference graph doesn't contain a node "+ 121 cananian 1.1.2.1 "for temporary "+tl.head.toString()+", which "+ 122 cananian 1.1.2.1 "is use/def in node "+nl.head.toString()); 123 cananian 1.1.2.1 moveList.put(tempnode, 124 cananian 1.1.2.1 new NodeList(nl.head, 125 cananian 1.1.2.1 (NodeList) moveList.get(tempnode))); 126 cananian 1.1.2.1 } 127 cananian 1.1.2.1 } 128 cananian 1.1.2.1 } 129 cananian 1.1.2.1 // Initialize degree with computed degree of each node. 130 cananian 1.1.2.1 degree = new Hashtable(); 131 cananian 1.1.2.1 for (NodeList nl = ig.nodes(); nl!=null; nl=nl.tail) 132 cananian 1.1.2.1 degree.put(nl.head, new Integer( 133 cananian 1.1.2.1 len(union(nl.head.succ(), nl.head.pred())))); 134 cananian 1.1.2.1 } 135 cananian 1.1.2.1 void MakeWorklist() { 136 cananian 1.1.2.1 while (!sets.initial.empty()) { 137 cananian 1.1.2.1 Node n = sets.initial.head(); 138 cananian 1.1.2.1 sets.initial.remove(n); 139 cananian 1.1.2.1 140 cananian 1.1.2.1 if(Degree(n) >= K) 141 cananian 1.1.2.1 sets.worklist.spill.add(n); 142 cananian 1.1.2.1 else if (MoveRelated(n)) 143 cananian 1.1.2.1 sets.worklist.freeze.add(n); 144 cananian 1.1.2.1 else 145 cananian 1.1.2.1 sets.worklist.simplify.add(n); 146 cananian 1.1.2.1 } 147 cananian 1.1.2.1 } 148 cananian 1.1.2.1 void Simplify() { 149 cananian 1.1.2.1 Node n = sets.worklist.simplify.head(); 150 cananian 1.1.2.1 sets.worklist.simplify.remove(n); 151 cananian 1.1.2.1 sets.selectStack.push(n); 152 cananian 1.1.2.1 for (NodeList nl=Adjacent(n); nl!=null; nl=nl.tail) 153 cananian 1.1.2.7 if (!sets.precolored.contains(nl.head)) 154 cananian 1.1.2.7 DecrementDegree(nl.head); 155 cananian 1.1.2.1 } 156 cananian 1.1.2.1 void Coalesce() { 157 cananian 1.1.2.1 Node m = moves.worklist.head(); 158 cananian 1.1.2.1 159 cananian 1.1.2.1 if (!flow.isMove(m)) throw new Error("Internal error"); 160 cananian 1.1.2.1 TempList use = flow.use(m); 161 cananian 1.1.2.1 TempList def = flow.def(m); 162 cananian 1.1.2.10 if (/*use.tail != null ||*/ def.tail != null)//derived use implies base use 163 cananian 1.1.2.4 throw new Error("Node supposed to be a MOVE: "+m); 164 cananian 1.1.2.1 165 cananian 1.1.2.1 Node x = GetAlias(ig.tnode(def.head)); 166 cananian 1.1.2.1 Node y = GetAlias(ig.tnode(use.head)); 167 cananian 1.1.2.1 Node u=x,v=y; 168 cananian 1.1.2.1 if (sets.precolored.contains(y)) { 169 cananian 1.1.2.1 u=y; v=x; 170 cananian 1.1.2.1 } 171 cananian 1.1.2.1 moves.worklist.remove(m); 172 cananian 1.1.2.1 if (u==v) { 173 cananian 1.1.2.1 // Coalesce u and v 174 cananian 1.1.2.1 moves.coalesced.add(m); 175 cananian 1.1.2.1 AddWorkList(u); 176 cananian 1.1.2.1 } else if (sets.precolored.contains(v) || u.adj(v)) { 177 cananian 1.1.2.1 // Constrain u 178 cananian 1.1.2.1 moves.constrained.add(m); 179 cananian 1.1.2.1 AddWorkList(u); 180 cananian 1.1.2.1 AddWorkList(v); 181 cananian 1.1.2.1 } else if ((sets.precolored.contains(u) && OK(Adjacent(v),u)) || 182 cananian 1.1.2.1 ((!sets.precolored.contains(u)) && 183 cananian 1.1.2.1 Conservative(merge(Adjacent(u), Adjacent(v))))) { 184 cananian 1.1.2.1 // Combine u and v 185 cananian 1.1.2.1 moves.coalesced.add(m); 186 cananian 1.1.2.1 Combine(u,v); 187 cananian 1.1.2.1 AddWorkList(u); 188 cananian 1.1.2.1 } else 189 cananian 1.1.2.1 moves.active.add(m); 190 cananian 1.1.2.1 } 191 cananian 1.1.2.1 void Freeze() { 192 cananian 1.1.2.1 Node u = sets.worklist.freeze.head(); 193 cananian 1.1.2.1 sets.worklist.freeze.remove(u); 194 cananian 1.1.2.1 sets.worklist.simplify.add(u); 195 cananian 1.1.2.1 FreezeMoves(u); 196 cananian 1.1.2.1 } 197 cananian 1.1.2.5 void FreezeMoves(Node u) { 198 cananian 1.1.2.5 for (NodeList m = NodeMoves(u); m!=null; m=m.tail) { 199 cananian 1.3.2.1 assert moves.active.contains(m.head); 200 cananian 1.1.2.5 moves.active.remove(m.head); 201 cananian 1.1.2.1 moves.frozen.add(m.head); 202 cananian 1.1.2.1 203 cananian 1.1.2.1 if (!flow.isMove(m.head)) throw new Error("Internal error"); 204 cananian 1.1.2.1 TempList use = flow.use(m.head); 205 cananian 1.1.2.1 TempList def = flow.def(m.head); 206 cananian 1.1.2.10 if (/*use.tail != null ||*/ def.tail != null)//derived use implies base use 207 cananian 1.1.2.1 throw new Error("Node supposed to be a MOVE"); 208 cananian 1.1.2.1 209 cananian 1.1.2.5 Temp x = def.head, y = use.head; 210 cananian 1.1.2.5 Node v; 211 cananian 1.1.2.5 if (GetAlias(ig.tnode(y))==GetAlias(u)) 212 cananian 1.1.2.5 v = GetAlias(ig.tnode(x)); 213 cananian 1.1.2.5 else 214 cananian 1.1.2.5 v = GetAlias(ig.tnode(y)); 215 cananian 1.1.2.5 216 cananian 1.1.2.7 /** Degree(v) should be >> K for precolored nodes, but we don't 217 cananian 1.1.2.7 * actually keep the adjacency info for precolored nodes around, 218 cananian 1.1.2.7 * so opt out of the test instead. [CSA] */ 219 cananian 1.1.2.9 if (!sets.precolored.contains(v) && 220 cananian 1.1.2.9 (NodeMoves(v)==null) && (Degree(v) < K) ) { 221 cananian 1.3.2.1 assert sets.worklist.freeze.contains(v); 222 cananian 1.1.2.1 sets.worklist.freeze.remove(v); 223 cananian 1.1.2.1 sets.worklist.simplify.add(v); 224 cananian 1.1.2.1 } 225 cananian 1.1.2.1 } 226 cananian 1.1.2.1 } 227 cananian 1.1.2.1 void SelectSpill() { 228 cananian 1.1.2.1 Node bestspill = sets.worklist.spill.head(); 229 cananian 1.1.2.1 int bestscore = ig.spillCost(bestspill); 230 cananian 1.1.2.1 for (NodeList nl = sets.worklist.spill.nodes(); nl!=null; nl=nl.tail) { 231 cananian 1.1.2.1 int nodescore = ig.spillCost(nl.head); 232 cananian 1.1.2.1 // bestscore is lowest spillCost 233 cananian 1.1.2.1 if (nodescore < bestscore) { 234 cananian 1.1.2.1 bestspill = nl.head; 235 cananian 1.1.2.1 bestscore = nodescore; 236 cananian 1.1.2.1 } 237 cananian 1.1.2.1 } 238 cananian 1.1.2.1 // OK, spill this guy. 239 cananian 1.1.2.1 //System.out.println("Spilling "+ig.gtemp(bestspill).toString()); 240 cananian 1.1.2.1 sets.worklist.spill.remove(bestspill); 241 cananian 1.1.2.1 sets.worklist.simplify.add(bestspill); 242 cananian 1.1.2.1 FreezeMoves(bestspill); 243 cananian 1.1.2.1 } 244 cananian 1.1.2.1 void AssignColors() { 245 cananian 1.1.2.1 color = new Hashtable(); 246 cananian 1.1.2.1 247 cananian 1.1.2.7 /* Color precolored nodes. */ 248 cananian 1.3.2.1 assert reg.size()==K; 249 cananian 1.1.2.7 for (int i=0; i<reg.size(); i++) 250 cananian 1.1.2.7 color.put(reg.elementAt(i), new Integer(i)); 251 cananian 1.1.2.1 252 cananian 1.1.2.1 while(!sets.selectStack.empty()) { 253 cananian 1.1.2.1 Node n = (Node) sets.selectStack.pop(); 254 cananian 1.1.2.8 int k; 255 cananian 1.1.2.7 // node should be previously uncolored. 256 cananian 1.3.2.1 assert !color.containsKey(ig.gtemp(n)); 257 cananian 1.1.2.1 boolean okColors[] = new boolean[K]; 258 cananian 1.1.2.1 for (k=0; k<K; k++) 259 cananian 1.1.2.1 okColors[k]=true; 260 cananian 1.1.2.1 for (NodeList nl = union(n.succ(),n.pred()); nl!=null; nl=nl.tail) { 261 cananian 1.1.2.1 Node w = GetAlias(nl.head); 262 cananian 1.1.2.1 if (sets.colored.contains(w) || sets.precolored.contains(w)) 263 cananian 1.1.2.1 okColors[getColor(ig.gtemp(w))]=false; 264 cananian 1.1.2.1 } 265 cananian 1.1.2.1 for (k=0; k<K; k++) 266 cananian 1.1.2.1 if (okColors[k]) { 267 cananian 1.1.2.1 sets.colored.add(n); 268 cananian 1.1.2.1 color.put(ig.gtemp(n), new Integer(k)); 269 cananian 1.1.2.1 break; 270 cananian 1.1.2.1 } 271 cananian 1.1.2.1 if (k==K) // no ok colors! 272 cananian 1.1.2.1 sets.spilled.add(n); 273 cananian 1.1.2.1 } 274 cananian 1.1.2.7 for (NodeList nl = sets.coalesced.nodes(); nl!=null; nl=nl.tail) { 275 cananian 1.1.2.7 // node should be previously uncolored. 276 cananian 1.3.2.1 assert !color.containsKey(ig.gtemp(nl.head)); 277 cananian 1.1.2.1 color.put(ig.gtemp(nl.head), 278 cananian 1.1.2.1 new Integer(getColor(ig.gtemp(GetAlias(nl.head))))); 279 cananian 1.1.2.7 } 280 cananian 1.1.2.1 // for (java.util.Enumeration e=color.keys(); e.hasMoreElements(); ) { 281 cananian 1.1.2.1 // Temp t = (Temp) e.nextElement(); 282 cananian 1.1.2.1 // System.out.println(t.toString()+" <= "+ 283 cananian 1.1.2.1 // ((Temp)reg.elementAt(getColor(t))).toString()); 284 cananian 1.1.2.1 // } 285 cananian 1.1.2.1 } 286 cananian 1.1.2.1 int getColor(Temp w) { 287 cananian 1.3.2.1 assert color.get(w)!=null : "No color for "+w; 288 cananian 1.1.2.1 return ((Integer)color.get(w)).intValue(); 289 cananian 1.1.2.1 } 290 cananian 1.1.2.1 291 cananian 1.1.2.2 public Temp tempMap(Temp t) { 292 cananian 1.3.2.1 assert !reg.contains(t) || // registers should map to themselves 293 cananian 1.3.2.1 (reg.elementAt(getColor(t))==t); 294 cananian 1.1.2.1 return initial.tempMap((Temp)reg.elementAt(getColor(t))); 295 cananian 1.1.2.1 } 296 cananian 1.1.2.1 297 cananian 1.1.2.1 // Utility functions: 298 cananian 1.1.2.1 void AddEdge(Node u, Node v) { 299 cananian 1.1.2.1 if (!u.adj(v) && (u!=v)) { 300 cananian 1.1.2.1 ig.addEdge(u,v); 301 cananian 1.1.2.7 if (!sets.precolored.contains(u)) 302 cananian 1.1.2.1 degree.put(u, new Integer(Degree(u)+1)); 303 cananian 1.1.2.7 if (!sets.precolored.contains(v)) 304 cananian 1.1.2.1 degree.put(v, new Integer(Degree(v)+1)); 305 cananian 1.1.2.1 } 306 cananian 1.1.2.1 } 307 cananian 1.1.2.1 308 cananian 1.1.2.1 NodeList Adjacent(Node n) { 309 cananian 1.1.2.7 /* We don't maintain adjacency lists for precolored nodes */ 310 cananian 1.3.2.1 assert !sets.precolored.contains(n); 311 cananian 1.1.2.1 NodeList r=null; 312 cananian 1.1.2.1 for (NodeList nl=union(n.succ(),n.pred()); nl!=null; nl=nl.tail) 313 cananian 1.1.2.1 if (!sets.coalesced.contains(nl.head) && 314 cananian 1.1.2.1 !sets.selectStack.contains(nl.head)) 315 cananian 1.1.2.1 r = new NodeList(nl.head, r); 316 cananian 1.1.2.1 return r; 317 cananian 1.1.2.1 } 318 cananian 1.1.2.1 void AddWorkList(Node u) { 319 cananian 1.1.2.1 if ((!sets.precolored.contains(u)) && 320 cananian 1.1.2.1 (!MoveRelated(u)) && 321 cananian 1.1.2.1 (Degree(u) < K)) { 322 cananian 1.1.2.1 sets.worklist.freeze.remove(u); 323 cananian 1.1.2.1 sets.worklist.simplify.add(u); 324 cananian 1.1.2.1 } 325 cananian 1.1.2.1 } 326 cananian 1.1.2.1 boolean OK(Node t, Node r) { 327 cananian 1.1.2.7 /* precolored nodes will always have degree >> K, but we don't 328 cananian 1.1.2.7 * actually maintain this info in the array. */ 329 cananian 1.1.2.7 return (sets.precolored.contains(t) || 330 cananian 1.1.2.7 (Degree(t) < K) || 331 cananian 1.1.2.1 t.adj(r)); 332 cananian 1.1.2.1 } 333 cananian 1.1.2.1 boolean OK(NodeList nl, Node r) { 334 cananian 1.1.2.1 for ( ; nl!=null; nl=nl.tail) 335 cananian 1.1.2.1 if (!OK(nl.head, r)) return false; 336 cananian 1.1.2.1 return true; 337 cananian 1.1.2.1 } 338 cananian 1.1.2.1 boolean Conservative(NodeList nl) { 339 cananian 1.1.2.1 int k = 0; 340 cananian 1.1.2.1 for ( ; nl!=null; nl=nl.tail) 341 cananian 1.1.2.7 /* precolored nodes will always have degree >> K, but we don't 342 cananian 1.1.2.7 * actually maintain this info in the array. */ 343 cananian 1.1.2.7 if (sets.precolored.contains(nl.head) || Degree(nl.head) >= K) 344 cananian 1.1.2.1 k++; 345 cananian 1.1.2.1 return ( k < K ); 346 cananian 1.1.2.1 } 347 cananian 1.1.2.1 Node GetAlias(Node n) { 348 cananian 1.1.2.1 if (sets.coalesced.contains(n)) 349 cananian 1.1.2.1 return GetAlias((Node)alias.get(n)); 350 cananian 1.1.2.1 else 351 cananian 1.1.2.1 return n; 352 cananian 1.1.2.1 } 353 cananian 1.1.2.1 354 cananian 1.1.2.1 void Combine(Node u, Node v) { 355 cananian 1.1.2.1 if (sets.worklist.freeze.contains(v)) 356 cananian 1.1.2.1 sets.worklist.freeze.remove(v); 357 cananian 1.1.2.1 else 358 cananian 1.1.2.1 sets.worklist.spill.remove(v); 359 cananian 1.1.2.1 360 cananian 1.1.2.1 sets.coalesced.add(v); 361 cananian 1.1.2.1 alias.put(v, u); 362 cananian 1.1.2.1 363 cananian 1.1.2.1 moveList.put(u, merge((NodeList)moveList.get(u), 364 cananian 1.1.2.1 (NodeList)moveList.get(v))); 365 cananian 1.1.2.11 // quoting appel, pg 252: When v is coalesced into u, moves associated 366 cananian 1.1.2.11 // with v are added to the move work-list. this will catch other moves 367 cananian 1.1.2.11 // from u to v. [CSA BUGFIX, 31-Mar-2000] 368 cananian 1.1.2.11 EnableMoves(new NodeList(v, null));//BUGFIX. 369 cananian 1.1.2.1 for (NodeList nl = Adjacent(v); nl!=null; nl=nl.tail) { 370 cananian 1.1.2.1 AddEdge(nl.head,u); 371 cananian 1.1.2.7 /* We don't keep degree information for precolored nodes. */ 372 cananian 1.1.2.7 if (!sets.precolored.contains(nl.head)) 373 cananian 1.1.2.7 DecrementDegree(nl.head); 374 cananian 1.1.2.1 } 375 cananian 1.1.2.7 if (sets.worklist.freeze.contains(u) && Degree(u) >= K) { 376 cananian 1.1.2.1 sets.worklist.freeze.remove(u); 377 cananian 1.1.2.1 sets.worklist.spill.add(u); 378 cananian 1.1.2.1 } 379 cananian 1.1.2.1 } 380 cananian 1.1.2.1 381 cananian 1.1.2.1 int Degree(Node m) { 382 cananian 1.1.2.7 /* We don't keep accurate degree information for precolored nodes. */ 383 cananian 1.3.2.1 assert !sets.precolored.contains(m); 384 cananian 1.1.2.1 return ((Integer)degree.get(m)).intValue(); 385 cananian 1.1.2.1 } 386 cananian 1.1.2.1 void DecrementDegree(Node m) { 387 cananian 1.1.2.1 int d = Degree(m); 388 cananian 1.1.2.1 degree.put(m, new Integer(d-1)); 389 cananian 1.1.2.1 //System.out.println("DecDegree("+ig.gtemp(m).toString()+"), "+d); 390 cananian 1.1.2.1 if (d == K) { 391 cananian 1.1.2.1 if (sets.worklist.spill.contains(m)) { 392 cananian 1.1.2.1 EnableMoves(new NodeList(m, Adjacent(m))); 393 cananian 1.1.2.1 sets.worklist.spill.remove(m); 394 cananian 1.1.2.1 if (MoveRelated(m)) 395 cananian 1.1.2.1 sets.worklist.freeze.add(m); 396 cananian 1.1.2.1 else 397 cananian 1.1.2.1 sets.worklist.simplify.add(m); 398 cananian 1.1.2.1 } 399 cananian 1.1.2.1 } 400 cananian 1.1.2.1 } 401 cananian 1.1.2.1 void EnableMoves(NodeList nl) { 402 cananian 1.1.2.1 for ( ; nl!=null; nl=nl.tail) 403 cananian 1.1.2.1 for (NodeList ml=NodeMoves(nl.head); ml!=null; ml=ml.tail) 404 cananian 1.1.2.1 if (moves.active.contains(ml.head)) { 405 cananian 1.1.2.1 moves.active.remove(ml.head); 406 cananian 1.1.2.1 moves.worklist.add(ml.head); 407 cananian 1.1.2.1 } 408 cananian 1.1.2.1 } 409 cananian 1.1.2.1 boolean MoveRelated(Node n) { 410 cananian 1.1.2.1 return NodeMoves(n)!=null; 411 cananian 1.1.2.1 } 412 cananian 1.1.2.1 NodeList NodeMoves(Node n) { 413 cananian 1.1.2.1 NodeList r = null; 414 cananian 1.1.2.1 // Node is an InterferenceGraph node, corresponding to a temp. 415 cananian 1.1.2.1 // loop through move instruction nodes associated with this temp. 416 cananian 1.1.2.1 for (NodeList nl = (NodeList) moveList.get(n); nl!=null; nl=nl.tail) 417 cananian 1.1.2.1 // if this move is on the activeMoves or worklistMoves lists, 418 cananian 1.1.2.1 // then this (interference graph) node is regarded as 'move-related' 419 cananian 1.1.2.1 if (moves.active.contains(nl.head) || 420 cananian 1.1.2.1 moves.worklist.contains(nl.head)) 421 cananian 1.1.2.1 r = new NodeList(nl.head, r); 422 cananian 1.1.2.1 return r; 423 cananian 1.1.2.1 } 424 cananian 1.1.2.1 425 cananian 1.1.2.1 // More utility functions... 426 cananian 1.1.2.1 427 cananian 1.1.2.1 NodeList union(NodeList a, NodeList b) { 428 cananian 1.1.2.1 NodeList r=a; 429 cananian 1.1.2.1 for( ; b!=null; b=b.tail) { 430 cananian 1.1.2.1 NodeList nlp; 431 cananian 1.1.2.1 for (nlp = a; nlp!=null; nlp=nlp.tail) 432 cananian 1.1.2.1 if (b.head == nlp.head) break; 433 cananian 1.1.2.1 if (nlp==null) 434 cananian 1.1.2.1 r = new NodeList(b.head, r); 435 cananian 1.1.2.1 } 436 cananian 1.1.2.1 return r; 437 cananian 1.1.2.1 } 438 cananian 1.1.2.2 TempList merge(TempList a, TempList b) { 439 cananian 1.1.2.2 TempList p, r=null; 440 cananian 1.1.2.1 for (p=a; p!=null; p=p.tail) { 441 cananian 1.1.2.1 r=new TempList(p.head, r); 442 cananian 1.1.2.1 } 443 cananian 1.1.2.1 for (p=b; p!=null; p=p.tail) { 444 cananian 1.1.2.1 r=new TempList(p.head, r); 445 cananian 1.1.2.1 } 446 cananian 1.1.2.1 return r; 447 cananian 1.1.2.1 } 448 cananian 1.1.2.1 NodeList merge(NodeList a, NodeList b) { 449 cananian 1.1.2.1 NodeList p, r=null; 450 cananian 1.1.2.1 for (p=a; p!=null; p=p.tail) { 451 cananian 1.1.2.1 r=new NodeList(p.head, r); 452 cananian 1.1.2.1 } 453 cananian 1.1.2.1 for (p=b; p!=null; p=p.tail) { 454 cananian 1.1.2.1 r=new NodeList(p.head, r); 455 cananian 1.1.2.1 } 456 cananian 1.1.2.1 return r; 457 cananian 1.1.2.1 } 458 cananian 1.1.2.1 int len(TempList tl) { 459 cananian 1.1.2.1 int n=0; 460 cananian 1.1.2.1 for ( ; tl!=null; tl=tl.tail) 461 cananian 1.1.2.1 n++; 462 cananian 1.1.2.1 return n; 463 cananian 1.1.2.1 } 464 cananian 1.1.2.1 int len(NodeList nl) { 465 cananian 1.1.2.1 int n=0; 466 cananian 1.1.2.1 for ( ; nl!=null; nl=nl.tail) 467 cananian 1.1.2.1 n++; 468 cananian 1.1.2.1 return n; 469 cananian 1.1.2.1 } 470 cananian 1.1.2.1 // check that the 'degree' stored in the hashtable matches the adjacency. 471 cananian 1.1.2.1 void check(Node n) { 472 cananian 1.1.2.11 // CSA 31-mar-2000: we punt degree info for precolored nodes, so 473 cananian 1.1.2.11 // we can't do this check on them. we can check all the rest, tho. 474 cananian 1.1.2.11 if ((!sets.precolored.contains(n)) && len(Adjacent(n)) != Degree(n)) 475 cananian 1.1.2.1 throw new Error("Inconsistent data for node "+ig.gtemp(n).toString()+ 476 cananian 1.1.2.1 ": Adj("+len(Adjacent(n))+") != Degree("+Degree(n)+")"); 477 cananian 1.1.2.1 } 478 cananian 1.1.2.1 void check(NodeList nl) { 479 cananian 1.1.2.1 for ( ; nl!=null; nl=nl.tail) 480 cananian 1.1.2.1 if (!sets.coalesced.contains(nl.head) && 481 cananian 1.1.2.1 !sets.selectStack.contains(nl.head)) 482 cananian 1.1.2.1 check(nl.head); 483 cananian 1.1.2.1 } 484 cananian 1.1.2.1 // perform sanity checks on the sets and the interference graph nodes. 485 cananian 1.1.2.1 void check() { 486 cananian 1.1.2.1 if (debug) { 487 cananian 1.1.2.1 sets.check(); 488 cananian 1.1.2.1 check(ig.nodes()); 489 cananian 1.1.2.5 // check invariants 490 cananian 1.1.2.5 for (NodeList nl=sets.worklist.simplify.nodes(); nl!=null; nl=nl.tail) 491 cananian 1.3.2.1 assert /*(Degree(nl.head) < K) &&*/(NodeMoves(nl.head)==null); 492 cananian 1.1.2.5 for (NodeList nl=sets.worklist.freeze.nodes(); nl!=null; nl=nl.tail) 493 cananian 1.3.2.1 assert (Degree(nl.head) < K) && (NodeMoves(nl.head)!=null); 494 cananian 1.1.2.5 for (NodeList nl=sets.worklist.spill.nodes(); nl!=null; nl=nl.tail) 495 cananian 1.3.2.1 assert Degree(nl.head) >= K; 496 cananian 1.1.2.1 } 497 cananian 1.1.2.1 } 498 cananian 1.2 }