1 cananian 1.1.2.3 // AppelRegAllocClasses.java, created Tue Jun 5 0:02:27 2001 by pnkfelix 2 cananian 1.1.2.3 // Copyright (C) 2001 Felix S. Klock II <pnkfelix@mit.edu> 3 cananian 1.1.2.3 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 pnkfelix 1.1.2.1 package harpoon.Analysis.Instr; 5 pnkfelix 1.1.2.1 6 pnkfelix 1.1.2.1 import harpoon.IR.Assem.Instr; 7 pnkfelix 1.1.2.1 8 pnkfelix 1.1.2.1 import harpoon.Temp.Temp; 9 pnkfelix 1.1.2.1 10 cananian 1.7 import net.cscott.jutil.BitString; 11 cananian 1.7 import net.cscott.jutil.Default; 12 cananian 1.6 import harpoon.Util.Util; 13 cananian 1.6 14 cananian 1.7 import net.cscott.jutil.LinearSet; 15 cananian 1.7 import net.cscott.jutil.UnmodifiableIterator; 16 pnkfelix 1.1.2.1 17 pnkfelix 1.1.2.1 import java.util.Iterator; 18 pnkfelix 1.1.2.1 import java.util.Collection; 19 pnkfelix 1.1.2.1 import java.util.Collections; 20 pnkfelix 1.1.2.7 import java.util.List; 21 pnkfelix 1.1.2.1 import java.util.ArrayList; 22 pnkfelix 1.1.2.1 import java.util.Set; 23 pnkfelix 1.1.2.1 import java.util.HashSet; 24 pnkfelix 1.1.2.1 import java.util.HashMap; 25 pnkfelix 1.1.2.1 26 pnkfelix 1.1.2.1 /** Collects various data structures used by AppelRegAlloc. 27 cananian 1.1.2.3 * @author Felix S. Klock II <pnkfelix@mit.edu> 28 cananian 1.9 * @version $Id: AppelRegAllocClasses.java,v 1.9 2004/02/08 04:55:22 cananian Exp $ 29 pnkfelix 1.1.2.1 */ 30 pnkfelix 1.1.2.1 abstract class AppelRegAllocClasses extends RegAlloc { 31 pnkfelix 1.1.2.5 public static final boolean CHECK_INV = false; 32 pnkfelix 1.1.2.8 33 pnkfelix 1.1.2.9 // FSK: debugging ("mul t0, t1, t2" ==> reg(t0) != reg(t1)) assertion failure by snapshotting extra state 34 pnkfelix 1.1.2.9 private static final boolean PAIRSET_IN_SNAPSHOT = true; 35 pnkfelix 1.1.2.5 36 pnkfelix 1.1.2.1 public AppelRegAllocClasses(harpoon.Backend.Generic.Code code) { 37 pnkfelix 1.1.2.1 super(code); 38 pnkfelix 1.1.2.1 } 39 pnkfelix 1.1.2.7 40 pnkfelix 1.1.2.7 private String lastStateString; 41 pnkfelix 1.1.2.7 /** Saves the current state of <code>this</code> for later 42 pnkfelix 1.1.2.7 retrieval using <code>resetState()</code>. 43 pnkfelix 1.1.2.7 44 pnkfelix 1.1.2.7 Note that <code>this</code> only carries <code>Node</code> and 45 cananian 1.4 <code>Move</code> state; additional state added by subclasses 46 pnkfelix 1.1.2.7 will not be checkpointed unless this method and reset state 47 pnkfelix 1.1.2.7 are overridden. 48 pnkfelix 1.1.2.7 49 pnkfelix 1.1.2.7 */ 50 pnkfelix 1.1.2.7 protected void checkpointState() { 51 pnkfelix 1.1.2.7 if (CHECK_INV) 52 pnkfelix 1.1.2.7 lastStateString = stateString(); 53 pnkfelix 1.1.2.7 saveNodePairSet(); 54 pnkfelix 1.1.2.7 saveNodeSets(); 55 pnkfelix 1.1.2.7 if (CHECK_INV) 56 cananian 1.3.2.1 assert lastStateString.equals(stateString()) : "\n\n" 57 pnkfelix 1.1.2.7 +"last : "+lastStateString+"\n" 58 cananian 1.3.2.1 +"curr : "+stateString()+"\n"; 59 pnkfelix 1.1.2.9 60 pnkfelix 1.1.2.9 // System.out.println(stateString()); 61 pnkfelix 1.1.2.7 } 62 pnkfelix 1.1.2.7 /** Restores the state of <code>this</code> to the state it was in 63 pnkfelix 1.1.2.7 on the last call to <code>checkpointState()</code>. 64 pnkfelix 1.1.2.7 */ 65 pnkfelix 1.1.2.7 protected void resetState() { 66 pnkfelix 1.1.2.9 // System.out.println(stateString()); 67 pnkfelix 1.1.2.7 restoreNodePairSet(); 68 pnkfelix 1.1.2.7 restoreNodeSets(); 69 pnkfelix 1.1.2.7 resetMoveSets(); 70 pnkfelix 1.1.2.7 if (CHECK_INV) 71 cananian 1.3.2.1 assert lastStateString.equals(stateString()) : "\n\n" 72 pnkfelix 1.1.2.7 +"last : "+lastStateString+"\n" 73 cananian 1.3.2.1 +"curr : "+stateString()+"\n"; 74 pnkfelix 1.1.2.9 // System.out.println(stateString()); 75 pnkfelix 1.1.2.7 } 76 pnkfelix 1.1.2.7 77 pnkfelix 1.1.2.11 protected String stateString() { 78 pnkfelix 1.1.2.7 // FSK: should probably sort lists on index number to ensure 79 pnkfelix 1.1.2.7 // determinism on sets. 80 pnkfelix 1.1.2.7 String igraphString = interferenceGraphString(); 81 pnkfelix 1.1.2.7 82 pnkfelix 1.1.2.7 return "\n"+ 83 pnkfelix 1.1.2.7 precolored+"\n"+ 84 pnkfelix 1.1.2.7 initial+"\n"+ 85 pnkfelix 1.1.2.7 simplify_worklist+"\n"+ 86 pnkfelix 1.1.2.7 freeze_worklist+"\n"+ 87 pnkfelix 1.1.2.7 spill_worklist+"\n"+ 88 pnkfelix 1.1.2.7 spilled_nodes+"\n"+ 89 pnkfelix 1.1.2.7 coalesced_nodes+"\n"+ 90 pnkfelix 1.1.2.7 colored_nodes+"\n"+ 91 pnkfelix 1.1.2.7 select_stack+"\n"+ 92 pnkfelix 1.1.2.7 "\n\n"+ 93 pnkfelix 1.1.2.7 coalesced_moves+"\n"+ 94 pnkfelix 1.1.2.7 constrained_moves+"\n"+ 95 pnkfelix 1.1.2.7 frozen_moves+"\n"+ 96 pnkfelix 1.1.2.7 worklist_moves+"\n"+ 97 pnkfelix 1.1.2.7 active_moves+"\n"+ 98 pnkfelix 1.1.2.7 "\n\n"+ 99 pnkfelix 1.1.2.7 igraphString 100 pnkfelix 1.1.2.7 ; 101 pnkfelix 1.1.2.7 } 102 pnkfelix 1.1.2.7 103 pnkfelix 1.1.2.7 String interferenceGraphString() { 104 pnkfelix 1.1.2.7 StringBuffer sb = new StringBuffer(); 105 pnkfelix 1.1.2.7 sb.append("** BEGIN GRAPH **\n"); 106 pnkfelix 1.1.2.14 for(Iterator nodes = allNodes(); nodes.hasNext(); ){ 107 pnkfelix 1.1.2.7 Node n = (Node) nodes.next(); 108 pnkfelix 1.1.2.7 sb.append(n); 109 pnkfelix 1.1.2.7 sb.append(", neighbors:["); 110 pnkfelix 1.1.2.7 for(NodeIter nbors = n.neighbors.iter(); nbors.hasNext();){ 111 pnkfelix 1.1.2.7 sb.append( nbors.next().id ); 112 pnkfelix 1.1.2.9 sb.append(","); 113 pnkfelix 1.1.2.7 } 114 pnkfelix 1.1.2.7 sb.append("]"); 115 pnkfelix 1.1.2.7 sb.append("\n"); 116 pnkfelix 1.1.2.7 } 117 pnkfelix 1.1.2.7 sb.append("** END GRAPH **\n"); 118 pnkfelix 1.1.2.7 119 pnkfelix 1.1.2.7 sb.append("AdjSet: "); 120 pnkfelix 1.1.2.7 java.util.TreeSet sortedPairs = 121 pnkfelix 1.1.2.7 new java.util.TreeSet( new java.util.Comparator() { 122 pnkfelix 1.1.2.7 public int compare(Object o1, Object o2) { 123 pnkfelix 1.1.2.7 List nl_0 = (List) o1; 124 pnkfelix 1.1.2.7 List nl_1 = (List) o2; 125 pnkfelix 1.1.2.7 Node n00 = (Node) nl_0.get(0); 126 pnkfelix 1.1.2.7 Node n01 = (Node) nl_0.get(1); 127 pnkfelix 1.1.2.7 Node n10 = (Node) nl_1.get(0); 128 pnkfelix 1.1.2.7 Node n11 = (Node) nl_1.get(1); 129 pnkfelix 1.1.2.7 130 pnkfelix 1.1.2.9 131 pnkfelix 1.1.2.9 if (Math.max(n00.id,n01.id) == Math.max(n10.id,n11.id)) { 132 pnkfelix 1.1.2.9 return Math.min(n00.id,n01.id) - Math.min(n10.id,n11.id); 133 pnkfelix 1.1.2.7 } else { 134 pnkfelix 1.1.2.9 return Math.max(n00.id,n01.id) - Math.max(n10.id,n11.id); 135 pnkfelix 1.1.2.7 } 136 pnkfelix 1.1.2.7 } 137 pnkfelix 1.1.2.7 }); 138 pnkfelix 1.1.2.12 sortedPairs.addAll( adjSet.pairs() ); 139 pnkfelix 1.1.2.7 sb.append( sortedPairs ); 140 pnkfelix 1.1.2.7 141 pnkfelix 1.1.2.7 return sb.toString(); 142 pnkfelix 1.1.2.7 } 143 pnkfelix 1.1.2.7 144 pnkfelix 1.1.2.7 // Set of <Node, Node> pairs 145 pnkfelix 1.1.2.7 NodePairSet adjSet; 146 pnkfelix 1.1.2.7 147 pnkfelix 1.1.2.1 NodeSet precolored; 148 pnkfelix 1.1.2.1 NodeSet initial; 149 pnkfelix 1.1.2.1 NodeSet simplify_worklist; 150 pnkfelix 1.1.2.1 NodeSet freeze_worklist; 151 pnkfelix 1.1.2.1 NodeSet spill_worklist; 152 pnkfelix 1.1.2.1 NodeSet spilled_nodes; 153 pnkfelix 1.1.2.1 NodeSet coalesced_nodes; 154 pnkfelix 1.1.2.1 NodeSet colored_nodes; 155 pnkfelix 1.1.2.1 NodeSet select_stack; 156 pnkfelix 1.1.2.1 157 pnkfelix 1.1.2.10 protected HashSet dontSpillTheseDefs = new HashSet(); 158 pnkfelix 1.1.2.1 159 pnkfelix 1.1.2.10 class Web { 160 pnkfelix 1.1.2.1 Temp temp; 161 pnkfelix 1.1.2.1 Collection defs, uses; 162 pnkfelix 1.1.2.1 Web(Temp temp, Set defs, Set uses) { 163 pnkfelix 1.1.2.1 this.temp = temp; 164 pnkfelix 1.1.2.1 this.defs = new LinearSet(defs); 165 pnkfelix 1.1.2.1 this.uses = new LinearSet(uses); 166 pnkfelix 1.1.2.1 } 167 pnkfelix 1.1.2.10 168 pnkfelix 1.1.2.10 private int spillable = 0; // 0 is dont-know, 1 is yes, -1 is no. 169 pnkfelix 1.1.2.10 protected boolean isSpillable() { 170 pnkfelix 1.1.2.10 switch (spillable) { 171 pnkfelix 1.1.2.10 case 1 : return true; 172 pnkfelix 1.1.2.10 case -1: return false; 173 pnkfelix 1.1.2.10 default: 174 pnkfelix 1.1.2.10 { 175 cananian 1.8 for(Object dO : defs) { 176 cananian 1.8 Instr d = (Instr) dO; 177 pnkfelix 1.1.2.10 if (d instanceof RestoreProxy || 178 pnkfelix 1.1.2.10 dontSpillTheseDefs.contains(d)) { 179 pnkfelix 1.1.2.10 spillable = -1; 180 pnkfelix 1.1.2.10 return false; 181 pnkfelix 1.1.2.10 } 182 pnkfelix 1.1.2.10 } 183 pnkfelix 1.1.2.10 for(Iterator ui = uses.iterator(); ui.hasNext(); ){ 184 pnkfelix 1.1.2.10 if (ui.next() instanceof SpillProxy) { 185 pnkfelix 1.1.2.10 spillable = -1; 186 pnkfelix 1.1.2.10 return false; 187 pnkfelix 1.1.2.10 } 188 pnkfelix 1.1.2.10 } 189 pnkfelix 1.1.2.10 spillable = 1; 190 pnkfelix 1.1.2.10 return true; 191 pnkfelix 1.1.2.10 } 192 pnkfelix 1.1.2.10 } 193 pnkfelix 1.1.2.10 194 pnkfelix 1.1.2.10 } 195 pnkfelix 1.1.2.1 public String toString() { 196 pnkfelix 1.1.2.1 return "Web<"+temp+ 197 pnkfelix 1.1.2.1 ", defs:"+defs+ 198 pnkfelix 1.1.2.1 ", uses:"+uses+">"; 199 pnkfelix 1.1.2.1 } 200 pnkfelix 1.1.2.1 } 201 pnkfelix 1.1.2.1 202 pnkfelix 1.1.2.1 203 pnkfelix 1.1.2.1 void initializeNodeSets() { 204 pnkfelix 1.1.2.14 nextId = 1; 205 pnkfelix 1.1.2.14 allNodes = new ArrayList(); 206 pnkfelix 1.1.2.14 207 pnkfelix 1.1.2.14 // these sets collectively partition the space of Nodes 208 pnkfelix 1.1.2.1 precolored = new NodeSet("precolored"); 209 pnkfelix 1.1.2.1 initial = new NodeSet("initial"); 210 pnkfelix 1.1.2.1 simplify_worklist = new NodeSet("simplify_worklist"); 211 pnkfelix 1.1.2.1 freeze_worklist = new NodeSet("freeze_worklist"); 212 pnkfelix 1.1.2.1 spill_worklist = new NodeSet("spill_worklist"); 213 pnkfelix 1.1.2.1 spilled_nodes = new NodeSet("spilled_nodes"); 214 pnkfelix 1.1.2.1 coalesced_nodes = new NodeSet("coalesced_nodes"); 215 pnkfelix 1.1.2.1 colored_nodes = new NodeSet("colored_nodes"); 216 pnkfelix 1.1.2.1 select_stack = new NodeSet("select_stack"); 217 pnkfelix 1.1.2.1 } 218 pnkfelix 1.1.2.1 219 pnkfelix 1.1.2.1 class BackupNodeSetInfo { 220 pnkfelix 1.1.2.1 class BackupNodeInfo { 221 pnkfelix 1.1.2.1 // keeps id/web saved 222 pnkfelix 1.1.2.1 final Node origNode; 223 pnkfelix 1.1.2.1 // don't need to save s_prev/s_next/s_rep 224 pnkfelix 1.1.2.7 final int origDegree; 225 pnkfelix 1.1.2.1 final NodeList origNeighbors; 226 pnkfelix 1.1.2.1 final Node origAlias; 227 pnkfelix 1.1.2.7 final MoveList origMoves; // List<Move> 228 pnkfelix 1.1.2.11 final int[] origColor; 229 pnkfelix 1.1.2.1 230 pnkfelix 1.1.2.1 BackupNodeInfo( Node save ){ 231 pnkfelix 1.1.2.1 origNode = save; 232 pnkfelix 1.1.2.7 origDegree = save.degree; 233 pnkfelix 1.1.2.1 origAlias = save.alias; 234 pnkfelix 1.1.2.11 origColor = (int[]) save.color.clone(); 235 pnkfelix 1.1.2.7 origMoves = new MoveList(save.moves.toList()); 236 pnkfelix 1.1.2.7 origNeighbors = new NodeList( save.neighbors.toList() ); 237 pnkfelix 1.1.2.1 } 238 pnkfelix 1.1.2.1 239 pnkfelix 1.1.2.1 void restore() { 240 pnkfelix 1.1.2.7 origNode.degree = origDegree; 241 pnkfelix 1.1.2.1 origNode.alias = origAlias; 242 pnkfelix 1.1.2.11 origNode.color = (int[]) origColor.clone(); 243 pnkfelix 1.1.2.7 origNode.moves = new MoveList( origMoves.toList() ); 244 pnkfelix 1.1.2.7 origNode.neighbors = new NodeList( origNeighbors.toList() ); 245 pnkfelix 1.1.2.1 } 246 pnkfelix 1.1.2.1 } 247 pnkfelix 1.1.2.1 248 pnkfelix 1.1.2.1 final NodeSet origSet; 249 pnkfelix 1.1.2.1 final ArrayList savedState; // List<BackupNodeInfo> 250 pnkfelix 1.1.2.1 251 pnkfelix 1.1.2.1 BackupNodeSetInfo(NodeSet save) { 252 pnkfelix 1.1.2.1 this.origSet = save; 253 pnkfelix 1.1.2.1 savedState = new ArrayList(origSet.size); 254 pnkfelix 1.1.2.1 for(NodeIter nI=save.iter(); nI.hasNext(); ){ 255 pnkfelix 1.1.2.1 savedState.add( new BackupNodeInfo( nI.next() )); 256 pnkfelix 1.1.2.1 } 257 pnkfelix 1.1.2.1 } 258 pnkfelix 1.1.2.7 259 pnkfelix 1.1.2.7 private void clearOrig() { origSet.clear(); } 260 pnkfelix 1.1.2.7 private void restore() { 261 pnkfelix 1.1.2.7 for(int i=savedState.size()-1; i>=0; i--){ 262 pnkfelix 1.1.2.7 BackupNodeInfo bn = (BackupNodeInfo) savedState.get(i); 263 pnkfelix 1.1.2.7 bn.restore(); 264 pnkfelix 1.1.2.7 origSet.add( bn.origNode ); 265 pnkfelix 1.1.2.7 } 266 pnkfelix 1.1.2.7 } 267 pnkfelix 1.1.2.1 } 268 pnkfelix 1.1.2.1 269 pnkfelix 1.1.2.1 BackupNodeSetInfo 270 pnkfelix 1.1.2.7 initialI, // wasn't originally in code... was there a reason? 271 pnkfelix 1.1.2.7 272 pnkfelix 1.1.2.1 simplify_worklistI, freeze_worklistI, 273 pnkfelix 1.1.2.1 spill_worklistI, spilled_nodesI, 274 pnkfelix 1.1.2.1 coalesced_nodesI, colored_nodesI, 275 pnkfelix 1.1.2.1 select_stackI; 276 pnkfelix 1.1.2.1 277 pnkfelix 1.1.2.7 private void saveNodeSets() { 278 pnkfelix 1.1.2.7 initialI = new BackupNodeSetInfo( initial ); 279 pnkfelix 1.1.2.1 simplify_worklistI = new BackupNodeSetInfo( simplify_worklist ); 280 pnkfelix 1.1.2.1 freeze_worklistI = new BackupNodeSetInfo( freeze_worklist ); 281 pnkfelix 1.1.2.1 spill_worklistI = new BackupNodeSetInfo( spill_worklist ); 282 pnkfelix 1.1.2.1 spilled_nodesI = new BackupNodeSetInfo( spilled_nodes ); 283 pnkfelix 1.1.2.1 coalesced_nodesI = new BackupNodeSetInfo( coalesced_nodes ); 284 pnkfelix 1.1.2.1 colored_nodesI = new BackupNodeSetInfo( colored_nodes ); 285 pnkfelix 1.1.2.1 select_stackI = new BackupNodeSetInfo( select_stack ); 286 pnkfelix 1.1.2.1 } 287 pnkfelix 1.1.2.7 private void restoreNodeSets() { 288 pnkfelix 1.1.2.1 // helper array to make traversal code easy 289 pnkfelix 1.1.2.1 BackupNodeSetInfo[] infos = new BackupNodeSetInfo[]{ 290 pnkfelix 1.1.2.7 initialI, 291 pnkfelix 1.1.2.1 simplify_worklistI, freeze_worklistI, 292 pnkfelix 1.1.2.1 spill_worklistI, spilled_nodesI, 293 pnkfelix 1.1.2.1 coalesced_nodesI, colored_nodesI, 294 pnkfelix 1.1.2.1 select_stackI 295 pnkfelix 1.1.2.1 }; 296 pnkfelix 1.1.2.1 297 pnkfelix 1.1.2.1 // must clear all origSets before restoring them 298 pnkfelix 1.1.2.1 for(int i=0; i<infos.length; i++) 299 pnkfelix 1.1.2.7 infos[i].clearOrig(); 300 pnkfelix 1.1.2.1 for(int i=0; i<infos.length; i++) 301 pnkfelix 1.1.2.7 infos[i].restore(); 302 pnkfelix 1.1.2.1 } 303 pnkfelix 1.1.2.1 304 pnkfelix 1.1.2.7 NodePairSet lastAdjSet; 305 pnkfelix 1.1.2.8 private void saveNodePairSet() { 306 pnkfelix 1.1.2.8 if (PAIRSET_IN_SNAPSHOT) 307 pnkfelix 1.1.2.8 lastAdjSet = adjSet.copy(); 308 pnkfelix 1.1.2.8 } 309 pnkfelix 1.1.2.8 private void restoreNodePairSet() { 310 pnkfelix 1.1.2.8 if (PAIRSET_IN_SNAPSHOT) 311 pnkfelix 1.1.2.8 adjSet = lastAdjSet.copy(); 312 pnkfelix 1.1.2.8 } 313 pnkfelix 1.1.2.1 314 pnkfelix 1.1.2.1 abstract static class NodeIter { 315 pnkfelix 1.1.2.1 public abstract boolean hasNext(); 316 pnkfelix 1.1.2.1 public abstract Node next(); 317 pnkfelix 1.1.2.1 } 318 pnkfelix 1.1.2.1 NodeIter combine(final NodeIter[] iters) { 319 pnkfelix 1.1.2.1 return new NodeIter() { 320 pnkfelix 1.1.2.1 int i=0; 321 pnkfelix 1.1.2.1 public boolean hasNext() { 322 pnkfelix 1.1.2.1 while(i < iters.length) { 323 pnkfelix 1.1.2.1 if (iters[i].hasNext()) { 324 pnkfelix 1.1.2.1 return true; 325 pnkfelix 1.1.2.1 } else { 326 pnkfelix 1.1.2.1 i++; 327 pnkfelix 1.1.2.1 continue; 328 pnkfelix 1.1.2.1 } 329 pnkfelix 1.1.2.1 } 330 pnkfelix 1.1.2.1 return false; 331 pnkfelix 1.1.2.1 } 332 pnkfelix 1.1.2.1 public Node next() { 333 pnkfelix 1.1.2.1 hasNext(); 334 pnkfelix 1.1.2.1 return iters[i].next(); } 335 pnkfelix 1.1.2.1 }; 336 pnkfelix 1.1.2.1 } 337 pnkfelix 1.1.2.1 338 pnkfelix 1.1.2.1 final class NodeSet { 339 pnkfelix 1.1.2.1 String name; // for debugging 340 pnkfelix 1.1.2.1 int size; 341 pnkfelix 1.1.2.1 Node head; // dummy element 342 pnkfelix 1.1.2.1 343 pnkfelix 1.1.2.4 void checkRep() { if (true) return; 344 cananian 1.3.2.1 assert size >= 0; 345 cananian 1.3.2.1 assert head != null; 346 pnkfelix 1.1.2.1 Node curr = head; 347 pnkfelix 1.1.2.1 int sz = -1; 348 pnkfelix 1.1.2.1 do { 349 cananian 1.3.2.1 assert curr.s_prev.s_next == curr; 350 cananian 1.3.2.1 assert curr.s_next.s_prev == curr; 351 pnkfelix 1.1.2.1 sz++; 352 pnkfelix 1.1.2.1 curr = curr.s_next; 353 pnkfelix 1.1.2.1 } while (curr != head); 354 cananian 1.3.2.1 assert sz == size; 355 pnkfelix 1.1.2.1 } 356 pnkfelix 1.1.2.1 357 pnkfelix 1.1.2.1 358 pnkfelix 1.1.2.1 NodeSet(String s) { 359 pnkfelix 1.1.2.1 name = s; 360 pnkfelix 1.1.2.1 head = new Node(null); 361 pnkfelix 1.1.2.1 size = 0; 362 pnkfelix 1.1.2.1 checkRep(); 363 pnkfelix 1.1.2.1 } 364 pnkfelix 1.1.2.1 365 pnkfelix 1.1.2.1 NodeIter iter() { 366 pnkfelix 1.1.2.1 checkRep(); 367 pnkfelix 1.1.2.1 return new NodeIter() { 368 pnkfelix 1.1.2.1 Node curr = head; 369 pnkfelix 1.1.2.1 public boolean hasNext() { return curr.s_next != head; } 370 pnkfelix 1.1.2.1 public Node next() { checkRep(); 371 cananian 1.3.2.1 assert hasNext(); 372 pnkfelix 1.1.2.1 Node ret = curr.s_next; curr = ret; 373 pnkfelix 1.1.2.1 checkRep(); 374 pnkfelix 1.1.2.1 return ret; 375 pnkfelix 1.1.2.1 } 376 pnkfelix 1.1.2.1 }; 377 pnkfelix 1.1.2.1 } 378 pnkfelix 1.1.2.1 379 pnkfelix 1.1.2.1 Node pop() { 380 pnkfelix 1.1.2.1 checkRep(); 381 pnkfelix 1.1.2.1 Node n = head.s_next; 382 pnkfelix 1.1.2.1 remove(n); 383 pnkfelix 1.1.2.1 checkRep(); 384 pnkfelix 1.1.2.1 return n; 385 pnkfelix 1.1.2.1 } 386 pnkfelix 1.1.2.1 387 pnkfelix 1.1.2.1 boolean isEmpty() { return size == 0; } 388 pnkfelix 1.1.2.1 void clear() { while( !isEmpty() ) pop(); } 389 pnkfelix 1.1.2.1 390 pnkfelix 1.1.2.1 void remove(Node n) { 391 pnkfelix 1.1.2.1 checkRep(); 392 cananian 1.3.2.1 assert this != precolored : "can't remove regs from precolored"; 393 cananian 1.3.2.1 assert n.s_rep == this : this.name + 394 pnkfelix 1.1.2.1 " tried to remove a node that is in "+ 395 cananian 1.3.2.1 n.s_rep.name; 396 pnkfelix 1.1.2.1 397 cananian 1.3.2.1 assert ! n.locked : "node "+n+" should not be locked"; 398 pnkfelix 1.1.2.1 399 pnkfelix 1.1.2.1 n.s_prev.s_next = n.s_next; 400 pnkfelix 1.1.2.1 n.s_next.s_prev = n.s_prev; 401 pnkfelix 1.1.2.1 size--; 402 pnkfelix 1.1.2.1 n.s_next = n; 403 pnkfelix 1.1.2.1 n.s_prev = n; 404 pnkfelix 1.1.2.1 n.s_rep = null; 405 pnkfelix 1.1.2.1 406 pnkfelix 1.1.2.1 checkRep(); 407 pnkfelix 1.1.2.1 } 408 pnkfelix 1.1.2.1 void add(Node n) { 409 pnkfelix 1.1.2.1 // If select_stack is going to be implemented as a 410 pnkfelix 1.1.2.1 // NodeSet, .add(..) needs to "push" Nodes on FRONT of 411 pnkfelix 1.1.2.1 // set, not the end. 412 pnkfelix 1.1.2.14 413 pnkfelix 1.1.2.1 checkRep(); 414 cananian 1.3.2.1 assert n.s_prev == n; 415 cananian 1.3.2.1 assert n.s_next == n; 416 cananian 1.3.2.1 assert n.s_rep == null; 417 cananian 1.3.2.1 assert n.s_rep != precolored : "can't add regs from precolored"; 418 pnkfelix 1.1.2.1 419 cananian 1.3.2.1 assert ! n.locked : "node "+n+" should not be locked"; 420 pnkfelix 1.1.2.1 421 pnkfelix 1.1.2.1 head.s_next.s_prev = n; 422 pnkfelix 1.1.2.1 n.s_next = head.s_next; 423 pnkfelix 1.1.2.1 n.s_prev = head; 424 pnkfelix 1.1.2.1 head.s_next = n; 425 pnkfelix 1.1.2.1 n.s_rep = this; 426 pnkfelix 1.1.2.1 size++; 427 pnkfelix 1.1.2.1 428 pnkfelix 1.1.2.1 n.nodeSet_history.addFirst(this); 429 pnkfelix 1.1.2.1 430 pnkfelix 1.1.2.1 checkRep(); 431 pnkfelix 1.1.2.1 } 432 pnkfelix 1.1.2.1 433 pnkfelix 1.1.2.1 Set asSet() { return new java.util.AbstractSet() { 434 pnkfelix 1.1.2.1 public int size() { return size; } 435 pnkfelix 1.1.2.1 public Iterator iterator() { 436 pnkfelix 1.1.2.1 final NodeIter ni = iter(); 437 cananian 1.6 return new UnmodifiableIterator() { 438 pnkfelix 1.1.2.1 public boolean hasNext() {return ni.hasNext();} 439 pnkfelix 1.1.2.1 public Object next() {return ni.next();} 440 pnkfelix 1.1.2.1 }; 441 pnkfelix 1.1.2.1 } 442 pnkfelix 1.1.2.1 }; 443 pnkfelix 1.1.2.1 } 444 pnkfelix 1.1.2.7 445 pnkfelix 1.1.2.7 public String toString() { 446 pnkfelix 1.1.2.7 return "NodeSet< "+name+", "+asSet()+" >"; } 447 pnkfelix 1.1.2.1 448 pnkfelix 1.1.2.1 } 449 pnkfelix 1.1.2.1 450 pnkfelix 1.1.2.1 NodeIter adjacent(Node n) { 451 pnkfelix 1.1.2.1 final NodeIter internIter = n.neighbors.iter(); 452 pnkfelix 1.1.2.1 // filter out ( selectStack U coalescedNodes ) 453 pnkfelix 1.1.2.1 return new NodeIter() { 454 pnkfelix 1.1.2.1 Node next = null; 455 pnkfelix 1.1.2.1 public boolean hasNext() { 456 pnkfelix 1.1.2.1 if (next == null) { 457 pnkfelix 1.1.2.1 while(internIter.hasNext()) { 458 pnkfelix 1.1.2.1 next = internIter.next(); 459 pnkfelix 1.1.2.1 if (next.isSelectStack() || next.isCoalesced()) { 460 pnkfelix 1.1.2.1 continue; 461 pnkfelix 1.1.2.1 } else { 462 pnkfelix 1.1.2.1 return true; 463 pnkfelix 1.1.2.1 } 464 pnkfelix 1.1.2.1 } 465 pnkfelix 1.1.2.1 return false; 466 pnkfelix 1.1.2.1 } else { 467 pnkfelix 1.1.2.1 return true; 468 pnkfelix 1.1.2.1 } 469 pnkfelix 1.1.2.1 } 470 pnkfelix 1.1.2.1 public Node next() { 471 pnkfelix 1.1.2.1 hasNext(); 472 pnkfelix 1.1.2.1 Node rtrn = next; 473 pnkfelix 1.1.2.1 next = null; 474 pnkfelix 1.1.2.1 return rtrn; 475 pnkfelix 1.1.2.1 } 476 pnkfelix 1.1.2.1 }; 477 pnkfelix 1.1.2.1 } 478 pnkfelix 1.1.2.12 /** Factory method to allow easier implementation switching later. */ 479 pnkfelix 1.1.2.13 NodePairSet makeNodePairSetOld() { 480 pnkfelix 1.1.2.13 return new NodePairSet__Switching(nextId > 1500); 481 pnkfelix 1.1.2.13 } 482 pnkfelix 1.1.2.12 NodePairSet makeNodePairSet() { 483 pnkfelix 1.1.2.12 return nextId > 2250 ? new NodePairSet__HashBased() 484 pnkfelix 1.1.2.12 : (NodePairSet) new NodePairSet__BitStrBased(); 485 pnkfelix 1.1.2.12 } 486 pnkfelix 1.1.2.12 487 pnkfelix 1.1.2.12 static abstract class NodePairSet { 488 pnkfelix 1.1.2.12 public abstract boolean contains(Node a, Node b); 489 pnkfelix 1.1.2.12 public abstract void add(Node a, Node b); 490 pnkfelix 1.1.2.12 public abstract HashSet pairs(); 491 pnkfelix 1.1.2.12 public abstract NodePairSet copy(); 492 pnkfelix 1.1.2.12 } 493 pnkfelix 1.1.2.12 class NodePairSet__Switching extends NodePairSet { 494 pnkfelix 1.1.2.12 boolean hash; 495 pnkfelix 1.1.2.12 NodePairSet back; 496 pnkfelix 1.1.2.13 // for use by copy only 497 pnkfelix 1.1.2.13 private NodePairSet__Switching() { } 498 pnkfelix 1.1.2.13 private NodePairSet__Switching(boolean startHash) { 499 pnkfelix 1.1.2.13 hash = startHash; 500 pnkfelix 1.1.2.13 if (hash) 501 pnkfelix 1.1.2.13 back = new NodePairSet__HashBased(); 502 pnkfelix 1.1.2.13 else 503 pnkfelix 1.1.2.13 back = new NodePairSet__BitStrBased(); 504 pnkfelix 1.1.2.12 } 505 pnkfelix 1.1.2.12 public boolean contains(Node a, Node b) { return back.contains(a,b); } 506 pnkfelix 1.1.2.13 public void add(Node a, Node b) { 507 pnkfelix 1.1.2.13 if (hash) 508 pnkfelix 1.1.2.13 checkForSwitch(); 509 pnkfelix 1.1.2.13 back.add(a,b); 510 pnkfelix 1.1.2.13 } 511 pnkfelix 1.1.2.13 private void checkForSwitch() { 512 pnkfelix 1.1.2.13 NodePairSet__HashBased h = (NodePairSet__HashBased) back; 513 pnkfelix 1.1.2.13 if ((((double)h.pairs.size()) / 514 pnkfelix 1.1.2.13 ((double)(nextId*nextId))) > 0.008) { 515 pnkfelix 1.1.2.13 hash = false; 516 pnkfelix 1.1.2.13 System.out.println(); 517 pnkfelix 1.1.2.13 System.out.print("Switching on "+h.pairs.size()+" edge"); 518 pnkfelix 1.1.2.13 back = new NodePairSet__BitStrBased(); 519 cananian 1.8 for(Object lO : h.pairs){ 520 cananian 1.8 List l = (List) lO; 521 pnkfelix 1.1.2.13 back.add( (Node)l.get(0), (Node)l.get(1) ); 522 pnkfelix 1.1.2.13 } 523 pnkfelix 1.1.2.13 System.out.println("!!!"); 524 pnkfelix 1.1.2.13 } 525 pnkfelix 1.1.2.13 } 526 pnkfelix 1.1.2.12 public HashSet pairs() { return back.pairs(); } 527 pnkfelix 1.1.2.12 public NodePairSet copy() { 528 pnkfelix 1.1.2.12 NodePairSet__Switching r = new NodePairSet__Switching(); 529 pnkfelix 1.1.2.12 r.hash = hash; 530 pnkfelix 1.1.2.12 r.back = back.copy(); 531 pnkfelix 1.1.2.12 return r; 532 pnkfelix 1.1.2.12 } 533 pnkfelix 1.1.2.12 } 534 pnkfelix 1.1.2.12 class NodePairSet__BitStrBased extends NodePairSet { 535 pnkfelix 1.1.2.12 int off; BitString bs; 536 pnkfelix 1.1.2.12 private NodePairSet__BitStrBased() { 537 pnkfelix 1.1.2.12 off = nextId; 538 pnkfelix 1.1.2.12 int size = off*off; 539 pnkfelix 1.1.2.12 bs = new BitString( size ); 540 pnkfelix 1.1.2.12 } 541 pnkfelix 1.1.2.12 public boolean contains(Node a, Node b) { 542 pnkfelix 1.1.2.12 return bs.get(off*a.id+b.id); 543 pnkfelix 1.1.2.12 } 544 pnkfelix 1.1.2.12 public void add(Node a, Node b) { 545 pnkfelix 1.1.2.12 bs.set(off*a.id+b.id); 546 pnkfelix 1.1.2.12 } 547 pnkfelix 1.1.2.12 public NodePairSet copy() { 548 pnkfelix 1.1.2.12 NodePairSet__BitStrBased c = new NodePairSet__BitStrBased(); 549 pnkfelix 1.1.2.12 c.off = off; 550 pnkfelix 1.1.2.12 c.bs = (BitString) bs.clone(); 551 pnkfelix 1.1.2.12 return c; 552 pnkfelix 1.1.2.12 } 553 pnkfelix 1.1.2.12 public HashSet pairs() { 554 pnkfelix 1.1.2.12 HashSet prs = new HashSet(); 555 pnkfelix 1.1.2.14 for(int i=1; i<off; i++) { 556 pnkfelix 1.1.2.14 for(int j=1; j<off; j++) { 557 pnkfelix 1.1.2.12 if (bs.get(off*i+j)) { 558 pnkfelix 1.1.2.12 prs.add(Default.pair 559 pnkfelix 1.1.2.14 ( getNode(i), 560 pnkfelix 1.1.2.14 getNode(j) )); 561 pnkfelix 1.1.2.12 } 562 pnkfelix 1.1.2.12 } 563 pnkfelix 1.1.2.12 } 564 pnkfelix 1.1.2.12 return prs; 565 pnkfelix 1.1.2.12 } 566 pnkfelix 1.1.2.12 } 567 pnkfelix 1.1.2.12 final class NodePairSet__HashBased extends NodePairSet { 568 pnkfelix 1.1.2.12 HashSet pairs = new HashSet(nextId*20); 569 pnkfelix 1.1.2.12 private NodePairSet__HashBased() { } 570 pnkfelix 1.1.2.1 public boolean contains(Node a, Node b) { 571 pnkfelix 1.1.2.1 return pairs.contains(Default.pair(a,b)); 572 pnkfelix 1.1.2.1 } 573 pnkfelix 1.1.2.1 public void add(Node a, Node b) { 574 pnkfelix 1.1.2.1 pairs.add(Default.pair(a, b)); 575 pnkfelix 1.1.2.1 } 576 pnkfelix 1.1.2.7 public NodePairSet copy() { 577 pnkfelix 1.1.2.12 NodePairSet__HashBased set = new NodePairSet__HashBased(); 578 pnkfelix 1.1.2.7 set.pairs = (HashSet) pairs.clone(); 579 pnkfelix 1.1.2.7 return set; 580 pnkfelix 1.1.2.7 } 581 pnkfelix 1.1.2.12 public HashSet pairs() { return (HashSet) pairs.clone(); } 582 pnkfelix 1.1.2.1 } 583 pnkfelix 1.1.2.1 584 pnkfelix 1.1.2.1 final static class NodeList { 585 pnkfelix 1.1.2.1 final static class Cons { Node elem; Cons next; } 586 pnkfelix 1.1.2.1 int size = 0; 587 pnkfelix 1.1.2.1 Cons first, last; 588 pnkfelix 1.1.2.7 NodeList() {} 589 pnkfelix 1.1.2.7 NodeList(List/*Node*/ ns) { 590 pnkfelix 1.1.2.7 for(Iterator i=ns.iterator(); i.hasNext();) 591 pnkfelix 1.1.2.7 add( (Node) i.next() ); 592 pnkfelix 1.1.2.7 } 593 pnkfelix 1.1.2.1 void add(Node n) { 594 pnkfelix 1.1.2.1 Cons c = new Cons(); 595 pnkfelix 1.1.2.1 c.elem = n; 596 pnkfelix 1.1.2.1 if (first == null) { 597 pnkfelix 1.1.2.1 first = last = c; 598 pnkfelix 1.1.2.1 } else { 599 pnkfelix 1.1.2.1 c.next = first; 600 pnkfelix 1.1.2.1 first = c; 601 pnkfelix 1.1.2.1 } 602 pnkfelix 1.1.2.1 size++; 603 pnkfelix 1.1.2.1 } 604 pnkfelix 1.1.2.1 /** INVALIDATES 'l' */ 605 pnkfelix 1.1.2.1 void append(NodeList l) { 606 pnkfelix 1.1.2.1 last.next = l.first; 607 pnkfelix 1.1.2.1 last = l.last; 608 pnkfelix 1.1.2.1 l.first = null; l.last = null; 609 pnkfelix 1.1.2.1 size += l.size; 610 pnkfelix 1.1.2.1 } 611 pnkfelix 1.1.2.1 void checkRep() { 612 cananian 1.3.2.1 assert last.next == null; 613 pnkfelix 1.1.2.1 for(Cons curr = first; curr != last; curr = curr.next ) 614 cananian 1.3.2.1 assert curr != null; 615 pnkfelix 1.1.2.1 } 616 pnkfelix 1.1.2.1 NodeIter iter() { 617 pnkfelix 1.1.2.1 return new NodeIter() { 618 pnkfelix 1.1.2.1 Cons c = first; 619 pnkfelix 1.1.2.1 public boolean hasNext() { return c != null; } 620 pnkfelix 1.1.2.1 public Node next() { 621 pnkfelix 1.1.2.1 Node n = c.elem; c = c.next; return n; 622 pnkfelix 1.1.2.1 } 623 pnkfelix 1.1.2.1 }; 624 pnkfelix 1.1.2.1 } 625 pnkfelix 1.1.2.7 List toList() { 626 pnkfelix 1.1.2.7 ArrayList l = new ArrayList(size); 627 pnkfelix 1.1.2.7 for(NodeIter i=iter(); i.hasNext();) 628 pnkfelix 1.1.2.7 l.add(i.next()); 629 pnkfelix 1.1.2.7 return l; 630 pnkfelix 1.1.2.7 } 631 pnkfelix 1.1.2.7 public String toString() { return "NodeList< "+toList()+" >"; } 632 pnkfelix 1.1.2.9 public String toStringWithIds() { 633 pnkfelix 1.1.2.9 StringBuffer sb = new StringBuffer(); 634 pnkfelix 1.1.2.9 sb.append("["); 635 pnkfelix 1.1.2.9 for(NodeIter nbors = this.iter(); nbors.hasNext();){ 636 pnkfelix 1.1.2.9 sb.append( nbors.next().id ); 637 pnkfelix 1.1.2.9 sb.append(","); 638 pnkfelix 1.1.2.9 } 639 pnkfelix 1.1.2.9 sb.append("]"); 640 pnkfelix 1.1.2.9 return sb.toString(); 641 pnkfelix 1.1.2.9 } 642 pnkfelix 1.1.2.1 } 643 pnkfelix 1.1.2.1 644 pnkfelix 1.1.2.14 // these are setup in initializeNodeSets() 645 pnkfelix 1.1.2.14 private int nextId; 646 pnkfelix 1.1.2.14 private ArrayList allNodes; 647 pnkfelix 1.1.2.14 protected Node getNode(int i) { return (Node) allNodes.get(i-1); } 648 pnkfelix 1.1.2.14 private void addNode(Node n) { allNodes.add(n); } 649 pnkfelix 1.1.2.14 protected Iterator allNodes() { return allNodes.iterator(); } 650 pnkfelix 1.1.2.14 651 pnkfelix 1.1.2.14 protected final class Node { 652 pnkfelix 1.1.2.1 final int id; 653 pnkfelix 1.1.2.1 654 pnkfelix 1.1.2.1 // prev and next pointers for this node's set 655 pnkfelix 1.1.2.1 Node s_prev, s_next; 656 pnkfelix 1.1.2.1 657 pnkfelix 1.1.2.1 // Set Representative 658 pnkfelix 1.1.2.1 NodeSet s_rep; 659 pnkfelix 1.1.2.1 660 pnkfelix 1.1.2.1 // the degree of this in the interference graph 661 pnkfelix 1.1.2.1 int degree = 0; 662 pnkfelix 1.1.2.1 663 pnkfelix 1.1.2.1 // linked list of neighbors of this in interference graph 664 pnkfelix 1.1.2.1 NodeList neighbors = new NodeList(); 665 pnkfelix 1.1.2.1 666 pnkfelix 1.1.2.1 // when a move (u,v) has been coalesced and v put into 667 pnkfelix 1.1.2.1 // coalescedNodes, then v.alias = u 668 pnkfelix 1.1.2.1 Node alias = null; 669 pnkfelix 1.1.2.1 670 pnkfelix 1.1.2.1 // list of moves this node is associated with 671 pnkfelix 1.1.2.1 MoveList moves = new MoveList(); 672 pnkfelix 1.1.2.1 673 pnkfelix 1.1.2.11 // color of this, ( forall c in color, 0 <= c < K when assigned ) 674 pnkfelix 1.1.2.11 // [ an array because some allocators associate multiple colors 675 pnkfelix 1.1.2.11 // with a node ] 676 pnkfelix 1.1.2.11 int[] color = new int[]{ -1 }; 677 pnkfelix 1.1.2.1 678 pnkfelix 1.1.2.1 // Web for this (null if this is dummy header element) 679 pnkfelix 1.1.2.1 final Web web; 680 pnkfelix 1.1.2.1 681 pnkfelix 1.1.2.1 // for debugging purposes: a sequence of the node sets this 682 pnkfelix 1.1.2.1 // has been a member of during its lifetime 683 pnkfelix 1.1.2.1 java.util.LinkedList nodeSet_history = new java.util.LinkedList(); 684 pnkfelix 1.1.2.1 685 pnkfelix 1.1.2.1 // special case for dummy nodes (for which 'w == null') 686 pnkfelix 1.1.2.1 public Node(Web w) { 687 pnkfelix 1.1.2.7 id = nextId; nextId++; s_prev = s_next = this; web = w; 688 pnkfelix 1.1.2.14 689 pnkfelix 1.1.2.14 addNode(this); 690 cananian 1.3.2.1 assert getNode(this.id) == this : this; 691 pnkfelix 1.1.2.14 } 692 pnkfelix 1.1.2.1 693 pnkfelix 1.1.2.1 public Node(NodeSet which, Web w) { 694 pnkfelix 1.1.2.1 this(w); 695 pnkfelix 1.1.2.1 which.add(this); 696 pnkfelix 1.1.2.1 } 697 pnkfelix 1.1.2.1 698 pnkfelix 1.1.2.1 boolean locked = false; 699 pnkfelix 1.1.2.1 700 pnkfelix 1.1.2.1 // machine registers, preassigned a color 701 pnkfelix 1.1.2.1 public boolean isPrecolored() { 702 pnkfelix 1.1.2.1 boolean r = s_rep == precolored; 703 cananian 1.3.2.1 if (r) assert color.length == 1 && color[0] != -1; 704 pnkfelix 1.1.2.1 return r; 705 pnkfelix 1.1.2.1 } 706 pnkfelix 1.1.2.1 707 pnkfelix 1.1.2.1 // temporary registers, not precolored and not yet processed 708 pnkfelix 1.1.2.1 public boolean isInitial() { return s_rep == initial; } 709 pnkfelix 1.1.2.1 710 pnkfelix 1.1.2.1 // list of low-degree non-move-related nodes 711 pnkfelix 1.1.2.1 public boolean isSimplifyWorkL() { return s_rep == simplify_worklist;} 712 pnkfelix 1.1.2.1 713 pnkfelix 1.1.2.1 // low-degree move-related nodes 714 pnkfelix 1.1.2.1 public boolean isFreezeWorkL() { return s_rep == freeze_worklist; } 715 pnkfelix 1.1.2.1 716 pnkfelix 1.1.2.1 // high-degree nodes 717 pnkfelix 1.1.2.1 public boolean isSpillWorkL() { return s_rep == spill_worklist; } 718 pnkfelix 1.1.2.1 719 pnkfelix 1.1.2.1 // nodes marked for spilling during this round 720 pnkfelix 1.1.2.1 public boolean isSpilled() { return s_rep == spilled_nodes; } 721 pnkfelix 1.1.2.1 722 pnkfelix 1.1.2.1 // registers that have been coalesced; when u <- v is 723 pnkfelix 1.1.2.1 // coalesced, v is added ot this set and u put back on some 724 pnkfelix 1.1.2.1 // work-list (or vice versa) 725 pnkfelix 1.1.2.1 public boolean isCoalesced() { return s_rep == coalesced_nodes; } 726 pnkfelix 1.1.2.1 727 pnkfelix 1.1.2.1 // nodes successfully colored 728 pnkfelix 1.1.2.1 public boolean isColored() { 729 pnkfelix 1.1.2.1 boolean r = s_rep == colored_nodes; 730 cananian 1.3.2.1 if (r) for(int i=0; i<color.length; i++) assert color[i] != -1; 731 pnkfelix 1.1.2.1 return r; 732 pnkfelix 1.1.2.1 } 733 pnkfelix 1.1.2.1 734 pnkfelix 1.1.2.1 // nodes on select stack 735 pnkfelix 1.1.2.1 public boolean isSelectStack() { return s_rep == select_stack; } 736 pnkfelix 1.1.2.1 737 pnkfelix 1.1.2.1 public String toString() { 738 pnkfelix 1.1.2.1 return "Node<"+ 739 pnkfelix 1.1.2.1 "id:"+id+ 740 pnkfelix 1.1.2.1 ", deg:"+degree+ 741 pnkfelix 1.1.2.1 ", alias:"+alias+ 742 pnkfelix 1.1.2.1 ", temp:"+((web==null)?"none":web.temp+"")+ 743 pnkfelix 1.1.2.7 // ", history:"+nodeSet_history+ 744 pnkfelix 1.1.2.1 ">"; 745 pnkfelix 1.1.2.1 } 746 pnkfelix 1.1.2.1 } 747 pnkfelix 1.1.2.1 748 pnkfelix 1.1.2.5 749 pnkfelix 1.1.2.5 750 pnkfelix 1.1.2.5 751 pnkfelix 1.1.2.5 final class Move { 752 pnkfelix 1.1.2.5 Collection dsts() { return Collections.singleton(dst); } 753 pnkfelix 1.1.2.5 Collection srcs() { return Collections.singleton(src); } 754 pnkfelix 1.1.2.5 Node dst, src; 755 pnkfelix 1.1.2.5 Move s_prev, s_next; 756 pnkfelix 1.1.2.5 MoveSet s_rep; // Set Representative 757 pnkfelix 1.1.2.5 Instr instr = null; // null for dummy header Moves 758 pnkfelix 1.1.2.5 759 pnkfelix 1.1.2.5 // dummy ctor 760 pnkfelix 1.1.2.5 Move() { s_prev = s_next = this; } 761 pnkfelix 1.1.2.5 762 pnkfelix 1.1.2.5 Move(Instr i, Node dest, Node source) { 763 pnkfelix 1.1.2.5 this(); 764 pnkfelix 1.1.2.5 instr = i; 765 pnkfelix 1.1.2.5 this.dst = dest; 766 pnkfelix 1.1.2.5 this.src = source; 767 pnkfelix 1.1.2.5 } 768 pnkfelix 1.1.2.5 public boolean isCoalesced() { return s_rep == coalesced_moves; } 769 pnkfelix 1.1.2.5 public boolean isConstrained() { return s_rep == constrained_moves; } 770 pnkfelix 1.1.2.5 public boolean isFrozen() { return s_rep == frozen_moves; } 771 pnkfelix 1.1.2.5 public boolean isWorklist() { return s_rep == worklist_moves; } 772 pnkfelix 1.1.2.5 public boolean isActive() { return s_rep == active_moves; } 773 pnkfelix 1.1.2.5 774 pnkfelix 1.1.2.5 public String toString() { 775 pnkfelix 1.1.2.5 // remove package info cruft from identity-based String 776 pnkfelix 1.1.2.5 String s = super.toString(); 777 pnkfelix 1.1.2.5 int i = s.indexOf("Move"); 778 pnkfelix 1.1.2.5 return 779 pnkfelix 1.1.2.5 s.substring(i)+ 780 pnkfelix 1.1.2.9 " set:"+s_rep.name+ 781 pnkfelix 1.1.2.5 " instr:"+instr; 782 pnkfelix 1.1.2.5 } 783 pnkfelix 1.1.2.5 } 784 pnkfelix 1.1.2.5 785 pnkfelix 1.1.2.5 MoveSet coalesced_moves; 786 pnkfelix 1.1.2.5 MoveSet constrained_moves; 787 pnkfelix 1.1.2.5 MoveSet frozen_moves; 788 pnkfelix 1.1.2.5 MoveSet worklist_moves; 789 pnkfelix 1.1.2.5 MoveSet active_moves; 790 pnkfelix 1.1.2.5 void checkMoveSets() { 791 pnkfelix 1.1.2.5 if( ! CHECK_INV ) 792 pnkfelix 1.1.2.5 return; 793 pnkfelix 1.1.2.5 794 pnkfelix 1.1.2.5 MoveSet[] sets = new MoveSet[]{ 795 pnkfelix 1.1.2.5 coalesced_moves,constrained_moves, 796 pnkfelix 1.1.2.5 frozen_moves,worklist_moves, 797 pnkfelix 1.1.2.5 active_moves 798 pnkfelix 1.1.2.5 }; 799 pnkfelix 1.1.2.5 for(int i=0; i<sets.length; i++) 800 pnkfelix 1.1.2.5 sets[i].checkRep(); 801 pnkfelix 1.1.2.5 } 802 pnkfelix 1.1.2.5 803 pnkfelix 1.1.2.5 // these sets collectively partition the space of Moves 804 pnkfelix 1.1.2.5 void initializeMoveSets() { 805 pnkfelix 1.1.2.5 coalesced_moves = new MoveSet("coalesced_moves"); 806 pnkfelix 1.1.2.5 constrained_moves = new MoveSet("constrained_moves"); 807 pnkfelix 1.1.2.5 frozen_moves = new MoveSet("frozen_moves"); 808 pnkfelix 1.1.2.5 worklist_moves = new MoveSet("worklist_moves"); 809 pnkfelix 1.1.2.5 active_moves = new MoveSet("active_moves"); 810 pnkfelix 1.1.2.5 } 811 pnkfelix 1.1.2.5 812 pnkfelix 1.1.2.7 private void resetMoveSets() { 813 pnkfelix 1.1.2.5 // all sets except worklist_moves 814 pnkfelix 1.1.2.5 MoveSet[] sets = new MoveSet[]{ 815 pnkfelix 1.1.2.5 coalesced_moves,constrained_moves, 816 pnkfelix 1.1.2.5 frozen_moves,active_moves 817 pnkfelix 1.1.2.5 }; 818 pnkfelix 1.1.2.5 for(int i=0; i<sets.length; i++) 819 pnkfelix 1.1.2.5 while( ! sets[i].isEmpty() ) { 820 pnkfelix 1.1.2.5 sets[i].checkRep(); 821 pnkfelix 1.1.2.5 worklist_moves.add( sets[i].pop() ); 822 pnkfelix 1.1.2.5 } 823 pnkfelix 1.1.2.5 } 824 pnkfelix 1.1.2.5 825 pnkfelix 1.1.2.5 final class MoveSet { 826 pnkfelix 1.1.2.5 private int size; 827 pnkfelix 1.1.2.5 private Move head; // dummy element 828 pnkfelix 1.1.2.5 final String name; 829 pnkfelix 1.1.2.5 MoveSet(String name) { 830 pnkfelix 1.1.2.5 this.name = name; 831 pnkfelix 1.1.2.5 head = new Move(); 832 pnkfelix 1.1.2.5 add_no_check_rep(head); 833 pnkfelix 1.1.2.5 size = 0; 834 pnkfelix 1.1.2.5 checkRep(); 835 pnkfelix 1.1.2.5 } 836 pnkfelix 1.1.2.5 837 pnkfelix 1.1.2.5 void checkRep() { 838 pnkfelix 1.1.2.5 if( ! CHECK_INV ) 839 pnkfelix 1.1.2.5 return; 840 pnkfelix 1.1.2.5 841 pnkfelix 1.1.2.5 Move curr = head; 842 pnkfelix 1.1.2.5 int checkSize = -1; 843 pnkfelix 1.1.2.5 do { 844 pnkfelix 1.1.2.5 checkSize++; 845 cananian 1.3.2.1 assert curr.s_next.s_prev == curr; 846 cananian 1.3.2.1 assert curr.s_next.s_prev == curr; 847 cananian 1.3.2.1 assert curr.s_rep == this; 848 pnkfelix 1.1.2.5 curr = curr.s_next; 849 pnkfelix 1.1.2.5 } while(curr != head); 850 pnkfelix 1.1.2.5 if (CHECK_INV) 851 cananian 1.3.2.1 assert size == checkSize : "size should be "+checkSize+" not "+size; 852 pnkfelix 1.1.2.5 } 853 pnkfelix 1.1.2.5 Iterator iter() { 854 cananian 1.6 return new UnmodifiableIterator() { 855 pnkfelix 1.1.2.5 Move curr = head; 856 pnkfelix 1.1.2.5 public boolean hasNext() { return curr.s_next != head; } 857 pnkfelix 1.1.2.5 public Object next() { 858 pnkfelix 1.1.2.5 Move n = curr.s_next; 859 pnkfelix 1.1.2.5 curr = curr.s_next; 860 pnkfelix 1.1.2.5 return n; 861 pnkfelix 1.1.2.5 } 862 pnkfelix 1.1.2.5 }; 863 pnkfelix 1.1.2.5 } 864 pnkfelix 1.1.2.5 boolean isEmpty() { return size == 0; } 865 pnkfelix 1.1.2.5 Move pop() { 866 cananian 1.3.2.1 assert !isEmpty() : "should not be empty"; 867 pnkfelix 1.1.2.5 Move n = head.s_next; 868 pnkfelix 1.1.2.5 if (CHECK_INV) 869 cananian 1.3.2.1 assert n!=head : "should not return head, "+ 870 cananian 1.3.2.1 "size:"+size+" set:"+asSet(); 871 pnkfelix 1.1.2.5 remove(n); 872 pnkfelix 1.1.2.5 return n; 873 pnkfelix 1.1.2.5 } 874 pnkfelix 1.1.2.5 875 pnkfelix 1.1.2.5 void remove(Move n) { 876 pnkfelix 1.1.2.5 checkRep(); 877 pnkfelix 1.1.2.5 if (CHECK_INV) 878 cananian 1.3.2.1 assert n.s_rep == this : ("called "+this+".remove(..) "+ 879 cananian 1.3.2.1 "on move:"+n+" in "+n.s_rep); 880 cananian 1.3.2.1 assert size != 0; 881 pnkfelix 1.1.2.5 n.s_prev.s_next = n.s_next; 882 pnkfelix 1.1.2.5 n.s_next.s_prev = n.s_prev; 883 pnkfelix 1.1.2.5 n.s_rep = null; n.s_prev = null; n.s_next = null; 884 pnkfelix 1.1.2.5 size--; 885 pnkfelix 1.1.2.5 checkRep(); 886 pnkfelix 1.1.2.5 } 887 pnkfelix 1.1.2.5 void add(Move n) { 888 pnkfelix 1.1.2.5 checkRep(); 889 pnkfelix 1.1.2.5 add_no_check_rep(n); 890 pnkfelix 1.1.2.5 checkRep(); 891 pnkfelix 1.1.2.5 } 892 pnkfelix 1.1.2.5 private void add_no_check_rep(Move n){ 893 pnkfelix 1.1.2.5 Move prev = head.s_prev; 894 pnkfelix 1.1.2.5 prev.s_next = n; 895 pnkfelix 1.1.2.5 n.s_prev = prev; n.s_next = head; 896 pnkfelix 1.1.2.5 n.s_rep = this; 897 pnkfelix 1.1.2.5 head.s_prev = n; 898 pnkfelix 1.1.2.5 size++; 899 pnkfelix 1.1.2.5 } 900 pnkfelix 1.1.2.5 Set asSet() { 901 pnkfelix 1.1.2.5 HashSet rtn = new HashSet(); 902 pnkfelix 1.1.2.5 for(Iterator iter=iter(); iter.hasNext();) 903 pnkfelix 1.1.2.5 rtn.add(iter.next()); 904 pnkfelix 1.1.2.5 return rtn; 905 pnkfelix 1.1.2.5 } 906 pnkfelix 1.1.2.9 Set asSortedSet() { 907 pnkfelix 1.1.2.9 java.util.TreeSet rtn = new java.util.TreeSet(new java.util.Comparator(){ 908 pnkfelix 1.1.2.9 public int compare(Object o1, Object o2) { 909 pnkfelix 1.1.2.9 Move m1 = (Move) o1; 910 pnkfelix 1.1.2.9 Move m2 = (Move) o2; 911 pnkfelix 1.1.2.9 return m1.instr.getID() - m2.instr.getID(); 912 pnkfelix 1.1.2.9 }}); 913 pnkfelix 1.1.2.9 rtn.addAll( asSet() ); 914 pnkfelix 1.1.2.9 return rtn; 915 pnkfelix 1.1.2.9 } 916 pnkfelix 1.1.2.9 public String toString() { return "MoveSet< "+name+", "+asSortedSet()+" >"; } 917 pnkfelix 1.1.2.5 } 918 cananian 1.9 static final class MoveList implements Iterable<Move> { 919 pnkfelix 1.1.2.5 final static class Cons { Move elem; Cons next; } 920 pnkfelix 1.1.2.5 Cons first; 921 pnkfelix 1.1.2.5 int size = 0; 922 pnkfelix 1.1.2.5 boolean isEmpty() { 923 pnkfelix 1.1.2.5 return size == 0; 924 pnkfelix 1.1.2.5 } 925 pnkfelix 1.1.2.7 MoveList() {} 926 pnkfelix 1.1.2.7 MoveList(List/*Move*/ ms) { 927 pnkfelix 1.1.2.7 for(Iterator i=ms.iterator(); i.hasNext();) 928 pnkfelix 1.1.2.7 add( (Move) i.next() ); 929 pnkfelix 1.1.2.7 } 930 pnkfelix 1.1.2.5 void add(Move m) { 931 pnkfelix 1.1.2.5 Cons c = new Cons(); 932 pnkfelix 1.1.2.5 c.elem = m; 933 pnkfelix 1.1.2.5 if (first == null) { 934 pnkfelix 1.1.2.5 first = c; 935 pnkfelix 1.1.2.5 } else { 936 pnkfelix 1.1.2.5 c.next = first; 937 pnkfelix 1.1.2.5 first = c; 938 pnkfelix 1.1.2.5 } 939 pnkfelix 1.1.2.5 size++; 940 pnkfelix 1.1.2.5 } 941 pnkfelix 1.1.2.5 /** INVALIDATES 'l' */ 942 pnkfelix 1.1.2.5 void append(MoveList l) { 943 pnkfelix 1.1.2.5 Cons last = first; 944 pnkfelix 1.1.2.5 while(last.next != null) 945 pnkfelix 1.1.2.5 last = last.next; 946 pnkfelix 1.1.2.5 947 pnkfelix 1.1.2.5 last.next = l.first; 948 pnkfelix 1.1.2.5 size += l.size; 949 pnkfelix 1.1.2.5 950 pnkfelix 1.1.2.5 l.first = null; 951 pnkfelix 1.1.2.5 l.size = -1; 952 pnkfelix 1.1.2.5 } 953 cananian 1.9 public Iterator<Move> iterator() { 954 cananian 1.9 return new UnmodifiableIterator<Move>() { 955 pnkfelix 1.1.2.5 Cons c = first; 956 pnkfelix 1.1.2.5 public boolean hasNext() { return c != null; } 957 cananian 1.9 public Move next() { Move m=c.elem; c=c.next; return m;} 958 pnkfelix 1.1.2.5 }; 959 pnkfelix 1.1.2.5 } 960 cananian 1.9 public List<Move> toList() { 961 cananian 1.9 java.util.ArrayList<Move> l = new java.util.ArrayList<Move>(); 962 cananian 1.9 for(Iterator<Move> m=iterator(); m.hasNext(); ){ 963 pnkfelix 1.1.2.5 l.add(m.next()); 964 pnkfelix 1.1.2.5 } 965 cananian 1.9 l.trimToSize(); 966 pnkfelix 1.1.2.7 return l; 967 pnkfelix 1.1.2.5 } 968 pnkfelix 1.1.2.7 public String toString() { return "MoveList< "+toList()+" >"; } 969 pnkfelix 1.1.2.5 } 970 pnkfelix 1.1.2.1 971 pnkfelix 1.1.2.1 972 cananian 1.2 }