1 pnkfelix 1.1.2.1  // GraphColoringRegAlloc.java, created Mon Jul 17 16:39:13 2000 by pnkfelix
   2 cananian 1.1.2.44 // Copyright (C) 2000 Felix S. Klock II <pnkfelix@mit.edu>
   3 pnkfelix 1.1.2.1  // 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.Analysis.Maps.Derivation;
   7 pnkfelix 1.1.2.20 import harpoon.Backend.Maps.BackendDerivation;
   8 pnkfelix 1.1.2.10 import harpoon.Analysis.DataFlow.LiveTemps;
   9 pnkfelix 1.1.2.29 import harpoon.Analysis.DataFlow.SpaceHeavyLiveTemps;
  10 pnkfelix 1.1.2.3  import harpoon.Analysis.ReachingDefs;
  11 pnkfelix 1.1.2.4  import harpoon.Analysis.ReachingDefsAltImpl;
  12 pnkfelix 1.1.2.5  import harpoon.Analysis.GraphColoring.AbstractGraph;
  13 pnkfelix 1.1.2.5  import harpoon.Analysis.GraphColoring.ColorableGraph;
  14 pnkfelix 1.1.2.5  import harpoon.Analysis.GraphColoring.Color;
  15 pnkfelix 1.1.2.5  import harpoon.Analysis.GraphColoring.GraphColorer;
  16 pnkfelix 1.1.2.11 import harpoon.Analysis.GraphColoring.OptimisticGraphColorer;
  17 pnkfelix 1.1.2.5  import harpoon.Analysis.GraphColoring.SimpleGraphColorer;
  18 pnkfelix 1.1.2.5  import harpoon.Analysis.GraphColoring.UnableToColorGraph;
  19 pnkfelix 1.1.2.1  import harpoon.Backend.Generic.Code;
  20 pnkfelix 1.1.2.5  import harpoon.Backend.Generic.RegFileInfo;
  21 pnkfelix 1.1.2.20 import harpoon.ClassFile.HClass;
  22 pnkfelix 1.1.2.20 import harpoon.ClassFile.HCodeElement;
  23 pnkfelix 1.1.2.2  import harpoon.IR.Assem.Instr;
  24 pnkfelix 1.1.2.31 import harpoon.IR.Assem.InstrFactory;
  25 pnkfelix 1.1.2.2  import harpoon.Temp.Temp;
  26 pnkfelix 1.1.2.31 import harpoon.Temp.TempMap;
  27 pnkfelix 1.1.2.4  import harpoon.Util.Util;
  28 cananian 1.5      import net.cscott.jutil.CombineIterator;
  29 cananian 1.5      import net.cscott.jutil.FilterIterator;
  30 cananian 1.5      import net.cscott.jutil.Default;
  31 pnkfelix 1.1.2.5  import harpoon.Util.ArraySet;
  32 cananian 1.5      import net.cscott.jutil.ListFactory;
  33 cananian 1.5      import net.cscott.jutil.Factories;
  34 cananian 1.5      import net.cscott.jutil.LinearSet;
  35 cananian 1.5      import net.cscott.jutil.MultiMap;
  36 cananian 1.5      import net.cscott.jutil.GenericMultiMap;
  37 cananian 1.5      import net.cscott.jutil.InvertibleMap;
  38 cananian 1.5      import net.cscott.jutil.GenericInvertibleMap;
  39 pnkfelix 1.1.2.1  
  40 pnkfelix 1.1.2.5  import java.util.Arrays;
  41 pnkfelix 1.1.2.2  import java.util.Map;
  42 pnkfelix 1.1.2.2  import java.util.HashMap;
  43 pnkfelix 1.1.2.2  import java.util.Set;
  44 pnkfelix 1.1.2.5  import java.util.AbstractSet;
  45 pnkfelix 1.1.2.2  import java.util.HashSet;
  46 pnkfelix 1.1.2.2  import java.util.List;
  47 pnkfelix 1.1.2.6  import java.util.AbstractList;
  48 pnkfelix 1.1.2.4  import java.util.ArrayList;
  49 pnkfelix 1.1.2.2  import java.util.LinkedList;
  50 pnkfelix 1.1.2.2  import java.util.Iterator;
  51 pnkfelix 1.1.2.2  import java.util.Collection;
  52 pnkfelix 1.1.2.8  import java.util.AbstractCollection;
  53 pnkfelix 1.1.2.2  import java.util.Collections;
  54 pnkfelix 1.1.2.33 import java.util.Date;
  55 pnkfelix 1.1.2.6  
  56 pnkfelix 1.1.2.1  /**
  57 pnkfelix 1.1.2.6   * <code>GraphColoringRegAlloc</code> uses graph coloring heuristics
  58 pnkfelix 1.1.2.6   * to find a register assignment for a Code.
  59 pnkfelix 1.1.2.1   * 
  60 cananian 1.1.2.44  * @author  Felix S. Klock II <pnkfelix@mit.edu>
  61 cananian 1.6       * @version $Id: GraphColoringRegAlloc.java,v 1.6 2004/02/08 03:19:37 cananian Exp $
  62 pnkfelix 1.1.2.1   */
  63 pnkfelix 1.1.2.1  public class GraphColoringRegAlloc extends RegAlloc {
  64 pnkfelix 1.1.2.24 
  65 pnkfelix 1.1.2.36     // Information output control flags
  66 pnkfelix 1.1.2.36     private static final boolean TIME = false;
  67 pnkfelix 1.1.2.19     private static final boolean RESULTS = false;
  68 pnkfelix 1.1.2.28     private static final boolean SPILL_INFO = false;
  69 pnkfelix 1.1.2.23     private static final boolean STATS = false;
  70 pnkfelix 1.1.2.32     private static final boolean COALESCE_STATS = false;
  71 pnkfelix 1.1.2.34     private static final boolean SCARY_OUTPUT = false;
  72 pnkfelix 1.1.2.38     private static final boolean UNIFY_INFO = false;
  73 pnkfelix 1.1.2.34 
  74 pnkfelix 1.1.2.36     // Code output control flags
  75 pnkfelix 1.1.2.39     private static final boolean DEF_COALESCE_MOVES = true;
  76 pnkfelix 1.1.2.41     private static final boolean COALESCE_MACH_REGS = false;
  77 pnkfelix 1.1.2.39 
  78 pnkfelix 1.1.2.39     private boolean COALESCE_MOVES = DEF_COALESCE_MOVES;
  79 pnkfelix 1.1.2.39 
  80 pnkfelix 1.1.2.39     static RegAlloc.Factory BRAINDEAD_FACTORY = 
  81 pnkfelix 1.1.2.39         new RegAlloc.Factory() {
  82 pnkfelix 1.1.2.39             public RegAlloc makeRegAlloc(Code c) {
  83 pnkfelix 1.1.2.39                 GraphColorer gc;
  84 pnkfelix 1.1.2.39                 
  85 pnkfelix 1.1.2.39                 // gc = new SimpleGraphColorer();
  86 pnkfelix 1.1.2.39 
  87 pnkfelix 1.1.2.39                 // TODO: Implement a Node Selector that will not
  88 pnkfelix 1.1.2.39                 // select nodes that have already been spilled in the
  89 pnkfelix 1.1.2.39                 // code, and pass it in here...
  90 pnkfelix 1.1.2.39                 NodeSelector ns = new NodeSelector();
  91 pnkfelix 1.1.2.39                 gc = new OptimisticGraphColorer(ns);
  92 pnkfelix 1.1.2.39                 ns.gcra = new GraphColoringRegAlloc(c, gc, true);
  93 pnkfelix 1.1.2.39                 ns.gcra.COALESCE_MOVES = false;
  94 pnkfelix 1.1.2.39                 return ns.gcra;
  95 pnkfelix 1.1.2.39             }
  96 pnkfelix 1.1.2.39             };
  97 pnkfelix 1.1.2.36 
  98 pnkfelix 1.1.2.34     static RegAlloc.Factory AGGRESSIVE_FACTORY = 
  99 pnkfelix 1.1.2.34         new RegAlloc.Factory() {
 100 pnkfelix 1.1.2.34             public RegAlloc makeRegAlloc(Code c) {
 101 pnkfelix 1.1.2.34                 GraphColorer gc;
 102 pnkfelix 1.1.2.34 
 103 pnkfelix 1.1.2.34                 // gc = new SimpleGraphColorer();
 104 pnkfelix 1.1.2.34 
 105 pnkfelix 1.1.2.34                 // TODO: Implement a Node Selector that will not
 106 pnkfelix 1.1.2.34                 // select nodes that have already been spilled in the
 107 pnkfelix 1.1.2.34                 // code, and pass it in here...
 108 pnkfelix 1.1.2.34                 NodeSelector ns = new NodeSelector();
 109 pnkfelix 1.1.2.34                 gc = new OptimisticGraphColorer(ns);
 110 pnkfelix 1.1.2.34                 ns.gcra = new GraphColoringRegAlloc(c, gc, true);
 111 pnkfelix 1.1.2.34                 
 112 pnkfelix 1.1.2.34                 return ns.gcra;
 113 pnkfelix 1.1.2.34             }
 114 pnkfelix 1.1.2.34         };
 115 pnkfelix 1.1.2.34 
 116 pnkfelix 1.1.2.5      public static RegAlloc.Factory FACTORY =
 117 pnkfelix 1.1.2.5          new RegAlloc.Factory() {
 118 pnkfelix 1.1.2.5              public RegAlloc makeRegAlloc(Code c) {
 119 pnkfelix 1.1.2.11                 GraphColorer gc;
 120 pnkfelix 1.1.2.11 
 121 pnkfelix 1.1.2.11                 // gc = new SimpleGraphColorer();
 122 pnkfelix 1.1.2.11 
 123 pnkfelix 1.1.2.28                 // TODO: Implement a Node Selector that will not
 124 pnkfelix 1.1.2.28                 // select nodes that have already been spilled in the
 125 pnkfelix 1.1.2.28                 // code, and pass it in here...
 126 pnkfelix 1.1.2.28                 NodeSelector ns = new NodeSelector();
 127 pnkfelix 1.1.2.28                 gc = new OptimisticGraphColorer(ns);
 128 pnkfelix 1.1.2.28                 ns.gcra = new GraphColoringRegAlloc(c, gc);
 129 pnkfelix 1.1.2.28                 
 130 pnkfelix 1.1.2.28                 return ns.gcra;
 131 pnkfelix 1.1.2.4              }
 132 pnkfelix 1.1.2.5          };
 133 pnkfelix 1.1.2.5  
 134 pnkfelix 1.1.2.28     static class NodeSelector extends OptimisticGraphColorer.SimpleSelector {
 135 pnkfelix 1.1.2.28         GraphColoringRegAlloc gcra;
 136 pnkfelix 1.1.2.30         public boolean allowedToRemove(Object n, ColorableGraph g) {
 137 pnkfelix 1.1.2.31             return gcra.isAvailableToSpill( n );
 138 pnkfelix 1.1.2.30         }
 139 pnkfelix 1.1.2.29         public Object chooseNodeForHiding(ColorableGraph g) {
 140 pnkfelix 1.1.2.29             HashSet l = new HashSet();
 141 pnkfelix 1.1.2.29             Object n = super.chooseNodeForHiding(g);
 142 pnkfelix 1.1.2.31             while (!gcra.isAvailableToSpill(n)) {
 143 pnkfelix 1.1.2.29                 // delay hiding spilled nodes as long as possible
 144 pnkfelix 1.1.2.33                 // System.out.println("DELAY "+n);
 145 pnkfelix 1.1.2.29                 g.hide(n);
 146 pnkfelix 1.1.2.29                 l.add(n);
 147 pnkfelix 1.1.2.29                 Object _n = super.chooseNodeForHiding(g);
 148 pnkfelix 1.1.2.29                 if (_n == null) 
 149 pnkfelix 1.1.2.29                     break;
 150 pnkfelix 1.1.2.29                 else 
 151 pnkfelix 1.1.2.29                     n = _n;
 152 pnkfelix 1.1.2.29             }
 153 pnkfelix 1.1.2.29             Object _n; if (!l.isEmpty()) do {
 154 pnkfelix 1.1.2.29                 _n = g.replace();
 155 pnkfelix 1.1.2.29             } while(l.contains(_n));
 156 pnkfelix 1.1.2.31             //System.out.println("HIDE:"+n);
 157 pnkfelix 1.1.2.29             return n;
 158 pnkfelix 1.1.2.29         }
 159 pnkfelix 1.1.2.29         
 160 pnkfelix 1.1.2.28         public Object chooseNodeForRemoval(ColorableGraph g) {
 161 pnkfelix 1.1.2.28             Object spillChoice = null;
 162 pnkfelix 1.1.2.28             Set nset = g.nodeSet();
 163 pnkfelix 1.1.2.28             int maxDegree = -1;
 164 pnkfelix 1.1.2.28             for(Iterator ns=nset.iterator(); ns.hasNext(); ) {
 165 pnkfelix 1.1.2.28                 Object n = ns.next();
 166 pnkfelix 1.1.2.28                 if (g.getColor(n) == null &&
 167 pnkfelix 1.1.2.28                     g.getDegree(n) > maxDegree) {
 168 pnkfelix 1.1.2.31                     if (gcra.isAvailableToSpill(n)) { // <= THIS IS KEY
 169 pnkfelix 1.1.2.28                         spillChoice = n;
 170 pnkfelix 1.1.2.28                         maxDegree = g.getDegree(n);
 171 pnkfelix 1.1.2.29                     } 
 172 pnkfelix 1.1.2.29                 }
 173 pnkfelix 1.1.2.29             }
 174 pnkfelix 1.1.2.29             if(spillChoice == null) {
 175 pnkfelix 1.1.2.29                 // backup strategy : spill COLORED nodes
 176 pnkfelix 1.1.2.29                 for(Iterator ns=nset.iterator(); ns.hasNext(); ) {
 177 pnkfelix 1.1.2.29                     Object n = ns.next();
 178 pnkfelix 1.1.2.29                     if (g.getDegree(n) > maxDegree) {
 179 pnkfelix 1.1.2.31                         if (gcra.isAvailableToSpill(n)) { // <= THIS IS KEY
 180 pnkfelix 1.1.2.29                             spillChoice = n;
 181 pnkfelix 1.1.2.29                             maxDegree = g.getDegree(n);
 182 pnkfelix 1.1.2.29                         } else {
 183 pnkfelix 1.1.2.34                             if (SCARY_OUTPUT) System.out.println
 184 pnkfelix 1.1.2.29                                 ("SKIP (2) "+n+" (already spilled)");
 185 pnkfelix 1.1.2.29                         }
 186 pnkfelix 1.1.2.29                     }
 187 pnkfelix 1.1.2.29                 }
 188 pnkfelix 1.1.2.29             }
 189 pnkfelix 1.1.2.29             if(spillChoice == null) {
 190 pnkfelix 1.1.2.29                 // backup strategy : spill HIDDEN node
 191 pnkfelix 1.1.2.29                 LinkedList rehide = new LinkedList();
 192 pnkfelix 1.1.2.29                 for(Object n=g.replace(); n!=null; n=g.replace()) {
 193 pnkfelix 1.1.2.29                     rehide.addLast(n);
 194 pnkfelix 1.1.2.29                     if (g.getDegree(n) > maxDegree) {
 195 pnkfelix 1.1.2.31                         if (gcra.isAvailableToSpill(n)) {
 196 pnkfelix 1.1.2.29                             spillChoice = n;
 197 pnkfelix 1.1.2.29                             maxDegree = g.getDegree(n);
 198 pnkfelix 1.1.2.29                         } else {
 199 pnkfelix 1.1.2.34                             if (SCARY_OUTPUT) System.out.println
 200 pnkfelix 1.1.2.29                                 ("SKIP (3) "+n+" (already spilled)");
 201 pnkfelix 1.1.2.29                         }
 202 pnkfelix 1.1.2.28                     }
 203 pnkfelix 1.1.2.28                 }
 204 pnkfelix 1.1.2.29                 while(!rehide.isEmpty()) {
 205 pnkfelix 1.1.2.29                     g.hide(rehide.removeLast());
 206 pnkfelix 1.1.2.29                 }
 207 pnkfelix 1.1.2.28             }
 208 pnkfelix 1.1.2.28             if(spillChoice == null) {
 209 pnkfelix 1.1.2.29                 // wtf?  Are ALL the nodes spilled?
 210 pnkfelix 1.1.2.29                 for(Iterator ns=g.nodeSet().iterator();ns.hasNext();){
 211 pnkfelix 1.1.2.29                     Object n = ns.next();
 212 cananian 1.3.2.1                      assert !gcra.isAvailableToSpill(n);
 213 pnkfelix 1.1.2.29                 }
 214 pnkfelix 1.1.2.29                 LinkedList rehide = new LinkedList();
 215 pnkfelix 1.1.2.29                 for(Object n=g.replace(); n!=null; n=g.replace()) {
 216 pnkfelix 1.1.2.29                     rehide.addLast(n);
 217 cananian 1.3.2.1                      assert !gcra.isAvailableToSpill(n);
 218 pnkfelix 1.1.2.29                 }
 219 pnkfelix 1.1.2.29                 while(!rehide.isEmpty()) {
 220 pnkfelix 1.1.2.29                     g.hide(rehide.removeLast());
 221 pnkfelix 1.1.2.29                 }
 222 pnkfelix 1.1.2.28             }
 223 pnkfelix 1.1.2.31             //System.out.println("SPILL:"+spillChoice);
 224 pnkfelix 1.1.2.28             return spillChoice;
 225 pnkfelix 1.1.2.28         }
 226 pnkfelix 1.1.2.28     }
 227 pnkfelix 1.1.2.28 
 228 pnkfelix 1.1.2.5      private static final int INITIAL_DISPLACEMENT = 0;
 229 pnkfelix 1.1.2.4  
 230 pnkfelix 1.1.2.2      double defWt, useWt, copyWt;
 231 pnkfelix 1.1.2.5      int baseReg;
 232 pnkfelix 1.1.2.2      int disp = INITIAL_DISPLACEMENT, argReg;
 233 pnkfelix 1.1.2.2      List stack; // List<Integer>
 234 pnkfelix 1.1.2.6      Map realReg; // Integer -> Integer
 235 pnkfelix 1.1.2.1  
 236 pnkfelix 1.1.2.5      final RegFileInfo rfi;
 237 pnkfelix 1.1.2.9      ReachingDefs rdefs;
 238 pnkfelix 1.1.2.10     LiveTemps liveTemps;
 239 pnkfelix 1.1.2.5  
 240 pnkfelix 1.1.2.13     // TYPES IN COMMENTS
 241 pnkfelix 1.1.2.13     // Reg    : All r in Temp such that isRegister(r)
 242 pnkfelix 1.1.2.13     // VReg   : Temp - Reg
 243 pnkfelix 1.1.2.13     // AReg   : All r such that Exists some t in Temp such that
 244 pnkfelix 1.1.2.13     //                rfi.getRegAssignments(t) contains some
 245 pnkfelix 1.1.2.13     //                List<Reg>, l, such that r is in l. 
 246 pnkfelix 1.1.2.13     // Assign : List<AReg>
 247 pnkfelix 1.1.2.13     // SysReg : Reg - AReg
 248 pnkfelix 1.1.2.5  
 249 pnkfelix 1.1.2.13     MultiMap regToDefs; // Reg -> Instr
 250 pnkfelix 1.1.2.13     MultiMap regToUses; // Reg -> Instr
 251 pnkfelix 1.1.2.15 
 252 pnkfelix 1.1.2.29     // used to associate a VReg with the available register
 253 pnkfelix 1.1.2.29     // assignments for its components. 
 254 pnkfelix 1.1.2.29     // VReg maps to an array of Maps, where the array-indices
 255 pnkfelix 1.1.2.29     // correspond to component indices in the assignment.
 256 pnkfelix 1.1.2.29     Map implicitAssigns; // VReg -> (AReg -> Assign)[]
 257 pnkfelix 1.1.2.15 
 258 pnkfelix 1.1.2.15 
 259 pnkfelix 1.1.2.27     InvertibleMap webPrecolor; // WebRecord -> AReg
 260 pnkfelix 1.1.2.13     Map regToColor;  // AReg -> RegColor
 261 pnkfelix 1.1.2.27     Map regToWeb; // AReg -> RegWebRecord
 262 pnkfelix 1.1.2.5  
 263 pnkfelix 1.1.2.18     Map ixtToWebPreCombine; // Instr x VReg -> WebRecord    
 264 pnkfelix 1.1.2.18     Map ixtToWeb; // Instr x VReg -> WebRecord
 265 pnkfelix 1.1.2.6      List webRecords; // List<WebRecord>
 266 pnkfelix 1.1.2.6  
 267 pnkfelix 1.1.2.6      List tempWebRecords; // List<TempWebRecord>
 268 pnkfelix 1.1.2.13     List regWebRecords; // List<RegWebRecord>
 269 pnkfelix 1.1.2.5      
 270 pnkfelix 1.1.2.11     GraphColorer colorer;
 271 pnkfelix 1.1.2.11 
 272 pnkfelix 1.1.2.34     private boolean aggressivelyCoalesce;
 273 pnkfelix 1.1.2.34 
 274 pnkfelix 1.1.2.26     private WebRecord getWR(Instr i, Temp t) {
 275 pnkfelix 1.1.2.26         if (isRegister(t)) {
 276 cananian 1.6                  for(Object rO : regWebRecords){ 
 277 cananian 1.6                      WebRecord r = (WebRecord) rO;
 278 pnkfelix 1.1.2.26                 if (r.temp().equals(t)) 
 279 pnkfelix 1.1.2.26                     return r;
 280 pnkfelix 1.1.2.26             }
 281 pnkfelix 1.1.2.26             return null;
 282 pnkfelix 1.1.2.26         } else {
 283 pnkfelix 1.1.2.26             return (WebRecord) ixtToWeb.get(Default.pair(i,t)); 
 284 pnkfelix 1.1.2.26         }
 285 pnkfelix 1.1.2.26     }
 286 pnkfelix 1.1.2.26 
 287 pnkfelix 1.1.2.11     /** Creates a <code>GraphColoringRegAlloc</code>, assigning `gc'
 288 pnkfelix 1.1.2.34         as its graph coloring strategy and using a overly conservative
 289 pnkfelix 1.1.2.34         move coalescing strategy. 
 290 pnkfelix 1.1.2.11     */
 291 pnkfelix 1.1.2.11     public GraphColoringRegAlloc(Code code, GraphColorer gc) {
 292 pnkfelix 1.1.2.34         this(code, gc, false);
 293 pnkfelix 1.1.2.34     }
 294 pnkfelix 1.1.2.34 
 295 pnkfelix 1.1.2.34     /** Creates a <code>GraphColoringRegAlloc</code>, assigning `gc'
 296 pnkfelix 1.1.2.34         as its graph coloring strategy.  If
 297 pnkfelix 1.1.2.34         <code>aggressiveCoalesce</code> is true, will choose to
 298 pnkfelix 1.1.2.34         coalesce moves in the face of increased memory traffic. 
 299 pnkfelix 1.1.2.34     */
 300 pnkfelix 1.1.2.34     public GraphColoringRegAlloc(Code code, GraphColorer gc, 
 301 pnkfelix 1.1.2.34                                  boolean aggressiveCoalesce) { 
 302 pnkfelix 1.1.2.1          super(code);
 303 pnkfelix 1.1.2.5          rfi = frame.getRegFileInfo();
 304 pnkfelix 1.1.2.11         colorer = gc;
 305 pnkfelix 1.1.2.34         aggressivelyCoalesce = aggressiveCoalesce;
 306 pnkfelix 1.1.2.1      }
 307 pnkfelix 1.1.2.34 
 308 pnkfelix 1.1.2.37     private LinkedList replOrigPairs = new LinkedList(); 
 309 pnkfelix 1.1.2.43     protected void replace(Instr orig, Instr repl) {
 310 pnkfelix 1.1.2.43         super.replace(orig, repl);
 311 pnkfelix 1.1.2.37         replOrigPairs.addFirst(Default.pair(repl, orig));
 312 pnkfelix 1.1.2.31     }
 313 pnkfelix 1.1.2.31     private void undoCoalescing() {
 314 pnkfelix 1.1.2.34         if (SCARY_OUTPUT) System.out.print(" UNDO");
 315 cananian 1.6              for(Object prO : replOrigPairs){
 316 cananian 1.6                  List pr = (List) prO;
 317 pnkfelix 1.1.2.37             Instr repl = (Instr) pr.get(0);
 318 pnkfelix 1.1.2.37             Instr orig = (Instr) pr.get(1);
 319 pnkfelix 1.1.2.36             // System.out.println("UNDO: replacing "+repl+" w/ "+orig);
 320 pnkfelix 1.1.2.36             // System.out.println("==:"+(repl==orig)+" equls:"+repl.equals(orig));
 321 pnkfelix 1.1.2.31             Instr.replace(repl, orig);
 322 pnkfelix 1.1.2.31         }
 323 pnkfelix 1.1.2.37         replOrigPairs.clear();
 324 pnkfelix 1.1.2.31         willRemoveLater.clear();
 325 pnkfelix 1.1.2.32         webPrecolor.clear();
 326 pnkfelix 1.1.2.32         // remap = EqTempSets.make(this, false);
 327 pnkfelix 1.1.2.32         remap = new EqWebRecords();
 328 pnkfelix 1.1.2.28     }
 329 pnkfelix 1.1.2.28 
 330 pnkfelix 1.1.2.5      protected Derivation getDerivation() {
 331 pnkfelix 1.1.2.20         final Derivation oldD = code.getDerivation();
 332 pnkfelix 1.1.2.20         return new BackendDerivation() {
 333 pnkfelix 1.1.2.20             private HCodeElement orig(HCodeElement h){
 334 pnkfelix 1.1.2.20                 return getBack((Instr)h);
 335 pnkfelix 1.1.2.20             }
 336 pnkfelix 1.1.2.28             private Temp orig(HCodeElement h, Temp t) {
 337 cananian 1.3.2.1                  assert false;
 338 pnkfelix 1.1.2.28                 Temp t2 = null;
 339 pnkfelix 1.1.2.28                 Instr inst = (Instr) orig(h);
 340 pnkfelix 1.1.2.28                 Iterator rs = new
 341 pnkfelix 1.1.2.28                     CombineIterator(inst.defC().iterator(),
 342 pnkfelix 1.1.2.28                                     inst.useC().iterator());
 343 pnkfelix 1.1.2.28                 while(rs.hasNext()) {
 344 pnkfelix 1.1.2.28                     t2 = (Temp) rs.next();
 345 pnkfelix 1.1.2.32                     // if (remap.tempMap(t2).equals(t)) 
 346 pnkfelix 1.1.2.28                         break;
 347 pnkfelix 1.1.2.28                 }
 348 cananian 1.3.2.1                  assert t2 != null;
 349 pnkfelix 1.1.2.28                 return t2;
 350 pnkfelix 1.1.2.28             }
 351 pnkfelix 1.1.2.20             public HClass typeMap(HCodeElement hce, Temp t) {
 352 pnkfelix 1.1.2.20                 HCodeElement hce2 = orig(hce); 
 353 pnkfelix 1.1.2.28                 Temp t2 = orig(hce, t);
 354 pnkfelix 1.1.2.28                 return oldD.typeMap(hce2, t2);
 355 pnkfelix 1.1.2.20             }
 356 pnkfelix 1.1.2.20             public Derivation.DList derivation(HCodeElement hce, Temp t) {
 357 pnkfelix 1.1.2.20                 HCodeElement hce2 = orig(hce); 
 358 pnkfelix 1.1.2.28                 Temp t2 = orig(hce, t);
 359 pnkfelix 1.1.2.28                 try {
 360 pnkfelix 1.1.2.28                     return Derivation.DList.rename
 361 pnkfelix 1.1.2.32                         (oldD.derivation(hce2, t2), null); // remap);
 362 pnkfelix 1.1.2.28                 } catch (TypeNotKnownException e) {
 363 pnkfelix 1.1.2.28                     System.out.println("called derivation("+hce+","+t+")");
 364 pnkfelix 1.1.2.28                     System.out.println("die on derivation("+hce2+","+t2+")");
 365 pnkfelix 1.1.2.28                     throw e;
 366 pnkfelix 1.1.2.28                 }
 367 pnkfelix 1.1.2.20             }
 368 pnkfelix 1.1.2.20             public BackendDerivation.Register
 369 pnkfelix 1.1.2.20                 calleeSaveRegister(HCodeElement hce, Temp t) { 
 370 pnkfelix 1.1.2.20                 hce = orig(hce);
 371 pnkfelix 1.1.2.20                 return ((BackendDerivation)oldD).calleeSaveRegister(hce, t);
 372 pnkfelix 1.1.2.20             }
 373 pnkfelix 1.1.2.20         };
 374 pnkfelix 1.1.2.5      }
 375 pnkfelix 1.1.2.5  
 376 pnkfelix 1.1.2.10     /** Returns a new Collection cr, where
 377 pnkfelix 1.1.2.10         for all e element of edges 
 378 pnkfelix 1.1.2.10            there exists a unique c element of cr such that 
 379 pnkfelix 1.1.2.10            c = [nodeToNum(e.get(0)), nodeToNum(e.get(1))]
 380 pnkfelix 1.1.2.10     */
 381 pnkfelix 1.1.2.28     private static Collection readableEdges(final Collection edges, 
 382 pnkfelix 1.1.2.28                                             final Map nodeToNum) {
 383 pnkfelix 1.1.2.10         return new AbstractCollection() {
 384 pnkfelix 1.1.2.10             public int size() { return edges.size(); }
 385 pnkfelix 1.1.2.10             public Iterator iterator() { 
 386 pnkfelix 1.1.2.29                 final int sz = size();
 387 pnkfelix 1.1.2.10                 return new FilterIterator 
 388 pnkfelix 1.1.2.10                     (edges.iterator(),
 389 pnkfelix 1.1.2.10                      new FilterIterator.Filter() {
 390 pnkfelix 1.1.2.10                         public Object map(Object o) {
 391 pnkfelix 1.1.2.10                             List l=(List)o;
 392 pnkfelix 1.1.2.10                             return Default.pair(nodeToNum.get(l.get(0)),
 393 pnkfelix 1.1.2.10                                                 nodeToNum.get(l.get(1)));
 394 pnkfelix 1.1.2.10                         }});
 395 pnkfelix 1.1.2.10             }
 396 pnkfelix 1.1.2.10         };
 397 pnkfelix 1.1.2.10     }
 398 pnkfelix 1.1.2.28     private static Collection readableNodes(final Collection nodes,
 399 pnkfelix 1.1.2.28                                             final Map nodeToNum) {
 400 pnkfelix 1.1.2.11         return new AbstractCollection() {
 401 pnkfelix 1.1.2.11             public int size() { return nodes.size(); }
 402 pnkfelix 1.1.2.11             public Iterator iterator() {
 403 pnkfelix 1.1.2.11                 return new FilterIterator
 404 pnkfelix 1.1.2.11                     (nodes.iterator(),
 405 pnkfelix 1.1.2.11                      new FilterIterator.Filter() {
 406 pnkfelix 1.1.2.11                         public Object map(Object o) {
 407 pnkfelix 1.1.2.11                             return nodeToNum.get(o);
 408 pnkfelix 1.1.2.11                         }
 409 pnkfelix 1.1.2.11                     });
 410 pnkfelix 1.1.2.11             }
 411 pnkfelix 1.1.2.11         };
 412 pnkfelix 1.1.2.11     }
 413 pnkfelix 1.1.2.11 
 414 pnkfelix 1.1.2.10 
 415 pnkfelix 1.1.2.1      protected void generateRegAssignment() {
 416 pnkfelix 1.1.2.1          boolean success, coalesced;
 417 pnkfelix 1.1.2.28         AdjMtx adjMtx = null;
 418 pnkfelix 1.1.2.28         
 419 pnkfelix 1.1.2.36         boolean doCoalescing = COALESCE_MOVES; // HACK
 420 pnkfelix 1.1.2.28         
 421 pnkfelix 1.1.2.24         if (TIME) System.out.println();
 422 pnkfelix 1.1.2.22 
 423 pnkfelix 1.1.2.27 
 424 pnkfelix 1.1.2.1          do {
 425 pnkfelix 1.1.2.1              do {
 426 pnkfelix 1.1.2.26                 buildRegAssigns();
 427 pnkfelix 1.1.2.41                 if (TIME) System.out.println("ReachingDefs \t\t"+new Date());
 428 pnkfelix 1.1.2.26                 rdefs = new ReachingDefsAltImpl(code);
 429 pnkfelix 1.1.2.41                 if (TIME) System.out.println("LiveTemps \t\t"+new Date());
 430 pnkfelix 1.1.2.29                 liveTemps = SpaceHeavyLiveTemps.make(code, rfi.liveOnExit());
 431 pnkfelix 1.1.2.26                 ixtToWeb = new HashMap();
 432 pnkfelix 1.1.2.26                 ixtToWebPreCombine = new HashMap();
 433 pnkfelix 1.1.2.27                 webPrecolor = new GenericInvertibleMap();
 434 pnkfelix 1.1.2.18 
 435 pnkfelix 1.1.2.33                 if (TIME) System.out.println("Making Webs \t\t"+new Date());
 436 pnkfelix 1.1.2.11 
 437 pnkfelix 1.1.2.5                  makeWebs(rdefs); 
 438 pnkfelix 1.1.2.21 
 439 pnkfelix 1.1.2.21                 // ASSERTION CHECKING LOOPS
 440 pnkfelix 1.1.2.21                 for(int k=0; k<webRecords.size(); k++) {
 441 cananian 1.3.2.1                      assert ((WebRecord)webRecords.get(k)).sreg() == k;
 442 pnkfelix 1.1.2.21                 }
 443 pnkfelix 1.1.2.12                 for(Iterator is=code.getElementsI(); is.hasNext();){
 444 pnkfelix 1.1.2.12                     Instr i = (Instr) is.next();
 445 pnkfelix 1.1.2.26                     
 446 cananian 1.6                          for(Object tO : i.defC()) {
 447 cananian 1.6                              Temp t = (Temp) tO;
 448 pnkfelix 1.1.2.12                         if (! isRegister(t) ) {
 449 pnkfelix 1.1.2.12                             List ixt = Default.pair(i,t);
 450 pnkfelix 1.1.2.12                             WebRecord web = (WebRecord)ixtToWeb.get(ixt);
 451 pnkfelix 1.1.2.12                             if (web == null) {
 452 cananian 1.3.2.1                                  assert ixtToWebPreCombine.get(ixt)==null : "There was a web for "+ixt+
 453 pnkfelix 1.1.2.12                                             " pre-combination! "+
 454 cananian 1.3.2.1                                              ixtToWebPreCombine.get(ixt);
 455 cananian 1.3.2.1                                  assert false : ("no web for i:"+i+", t:"+t);
 456 pnkfelix 1.1.2.12                             }
 457 pnkfelix 1.1.2.12                         }
 458 pnkfelix 1.1.2.12                     }
 459 cananian 1.6                          for(Object tO : i.useC()) {
 460 cananian 1.6                              Temp t = (Temp) tO;
 461 pnkfelix 1.1.2.12                         if (! isRegister(t) ) {
 462 pnkfelix 1.1.2.12                             WebRecord web = (WebRecord) 
 463 pnkfelix 1.1.2.12                                 ixtToWeb.get(Default.pair(i,t));
 464 cananian 1.3.2.1                              assert web != null : ("no web for i:"+i+", t:"+t);
 465 pnkfelix 1.1.2.12                         }
 466 pnkfelix 1.1.2.12                     }
 467 pnkfelix 1.1.2.21                 } 
 468 pnkfelix 1.1.2.21                 // END ASSERTION CHECKING LOOPS
 469 pnkfelix 1.1.2.21                 
 470 pnkfelix 1.1.2.7                  // System.out.println("webs: "+webRecords);
 471 pnkfelix 1.1.2.5  
 472 pnkfelix 1.1.2.33                 if(TIME)System.out.println("Building Matrix \t"+new Date());
 473 pnkfelix 1.1.2.11 
 474 pnkfelix 1.1.2.28                 
 475 pnkfelix 1.1.2.41                 adjMtx = buildAdjMatrix();
 476 pnkfelix 1.1.2.33                 
 477 pnkfelix 1.1.2.41                 if(TIME)printConflictTime();
 478 pnkfelix 1.1.2.41 
 479 pnkfelix 1.1.2.33                 if(TIME)System.out.println("Adjacency Matrix Built \t"+new Date());
 480 pnkfelix 1.1.2.7                  // System.out.println(adjMtx);
 481 pnkfelix 1.1.2.28                 if (doCoalescing) {
 482 pnkfelix 1.1.2.33                     if(TIME)System.out.println("Coalescing Registers \t"+new Date());
 483 pnkfelix 1.1.2.28                     Set coal = coalesceRegs(adjMtx);
 484 pnkfelix 1.1.2.31                     coalesced = !coal.isEmpty();
 485 pnkfelix 1.1.2.28                 } else {
 486 pnkfelix 1.1.2.28                     coalesced = false;
 487 pnkfelix 1.1.2.28                 }
 488 pnkfelix 1.1.2.41                 if(TIME)printConflictTime();
 489 pnkfelix 1.1.2.1              } while (coalesced);
 490 pnkfelix 1.1.2.5  
 491 pnkfelix 1.1.2.33             if(TIME)System.out.println("Building Lists \t\t"+new Date());
 492 pnkfelix 1.1.2.11 
 493 pnkfelix 1.1.2.6              WebRecord[] adjLsts = buildAdjLists(adjMtx); 
 494 pnkfelix 1.1.2.18 
 495 pnkfelix 1.1.2.5              adjMtx = null;
 496 pnkfelix 1.1.2.5  
 497 pnkfelix 1.1.2.21             // STAT GATHERING LOOPS
 498 pnkfelix 1.1.2.21             Iterator wri;
 499 pnkfelix 1.1.2.21             StatGather regStat = new StatGather();
 500 pnkfelix 1.1.2.21             for(wri=regWebRecords.iterator(); wri.hasNext();) {
 501 pnkfelix 1.1.2.21                 RegWebRecord rwr = (RegWebRecord) wri.next();
 502 pnkfelix 1.1.2.21                 int deg = rwr.adjnds.size();
 503 pnkfelix 1.1.2.21                 regStat.add(deg);
 504 pnkfelix 1.1.2.21             }
 505 pnkfelix 1.1.2.21             StatGather tmpStat = new StatGather();
 506 pnkfelix 1.1.2.21             for(wri=tempWebRecords.iterator(); wri.hasNext();) {
 507 pnkfelix 1.1.2.21                 TempWebRecord twr = (TempWebRecord) wri.next();
 508 pnkfelix 1.1.2.21                 int deg = twr.adjnds.size();
 509 pnkfelix 1.1.2.21                 tmpStat.add(deg);
 510 pnkfelix 1.1.2.21             }
 511 pnkfelix 1.1.2.24             if(STATS)System.out.println("\nRegDeg"+regStat + " TmpDeg"+tmpStat );
 512 pnkfelix 1.1.2.21             // END STAT GATHERING LOOPS
 513 pnkfelix 1.1.2.18 
 514 pnkfelix 1.1.2.7              // System.out.println(Arrays.asList(adjLsts));
 515 pnkfelix 1.1.2.5  
 516 pnkfelix 1.1.2.1              computeSpillCosts();
 517 pnkfelix 1.1.2.5  
 518 pnkfelix 1.1.2.33             if(TIME)System.out.println("Building Graph \t\t"+new Date());
 519 pnkfelix 1.1.2.11 
 520 pnkfelix 1.1.2.15             final Graph graph = buildGraph(adjLsts);
 521 pnkfelix 1.1.2.28 
 522 pnkfelix 1.1.2.28             Map nodeToNum = printGraph(graph, RESULTS);
 523 pnkfelix 1.1.2.5              
 524 pnkfelix 1.1.2.24             if(STATS)System.out.println(" |g.V|:"+graph.nodeSet().size() + 
 525 pnkfelix 1.1.2.24                   " |g.E|:"+graph.edges().size());
 526 pnkfelix 1.1.2.19 
 527 pnkfelix 1.1.2.5              try {
 528 pnkfelix 1.1.2.6                  List colors = new ArrayList(regToColor.values());
 529 pnkfelix 1.1.2.10                 // System.out.println("colors:"+colors);
 530 pnkfelix 1.1.2.6                  colorer.color(graph, colors);
 531 pnkfelix 1.1.2.18                 
 532 pnkfelix 1.1.2.17                 for(int j=0; j<adjLsts.length; j++) {
 533 pnkfelix 1.1.2.17                     WebRecord wr = adjLsts[j];
 534 pnkfelix 1.1.2.22 
 535 pnkfelix 1.1.2.22                     if (isRegister(wr.temp())) continue;
 536 pnkfelix 1.1.2.22 
 537 pnkfelix 1.1.2.17                     Iterator wrs;
 538 pnkfelix 1.1.2.17                     for(wrs=wr.adjnds.iterator(); wrs.hasNext();){
 539 pnkfelix 1.1.2.17                         WebRecord nb = (WebRecord) wrs.next();
 540 pnkfelix 1.1.2.18                         HashSet nbl = new HashSet(graph.regs(nb));
 541 pnkfelix 1.1.2.17 
 542 cananian 1.3.2.1                          assert !nbl.isEmpty() : "no regs for "+nb;
 543 cananian 1.3.2.1                          assert !graph.regs(wr).isEmpty() : "no regs for "+wr;
 544 pnkfelix 1.1.2.17 
 545 pnkfelix 1.1.2.17                         nbl.retainAll(graph.regs(wr));
 546 pnkfelix 1.1.2.28 
 547 pnkfelix 1.1.2.28 
 548 cananian 1.3.2.1                          assert nbl.isEmpty() : "conflict detected: "+
 549 pnkfelix 1.1.2.28                                     wr+"("+graph.regs(wr)+
 550 pnkfelix 1.1.2.28                                     ",precol:"+webPrecolor.containsKey(wr)+
 551 pnkfelix 1.1.2.28                                     ")"+
 552 pnkfelix 1.1.2.28                                     
 553 pnkfelix 1.1.2.17                                     " and "+
 554 pnkfelix 1.1.2.28                                     nb+"("+graph.regs(nb)+
 555 pnkfelix 1.1.2.28                                     ",precol:"+webPrecolor.containsKey(wr)+
 556 pnkfelix 1.1.2.28                                     ")"+
 557 cananian 1.3.2.1                                      "";
 558 pnkfelix 1.1.2.17                         
 559 cananian 1.3.2.1                          assert rfi.getRegAssignments(wr.temp()).
 560 cananian 1.3.2.1                                      contains(graph.regs(wr)) : rfi.getRegAssignments(wr.temp())+
 561 cananian 1.3.2.1                                      " does not contain "+graph.regs(wr);
 562 pnkfelix 1.1.2.17                                                           
 563 pnkfelix 1.1.2.17                     }
 564 pnkfelix 1.1.2.17                 }
 565 pnkfelix 1.1.2.17 
 566 pnkfelix 1.1.2.10                 MultiMap c2n = new GenericMultiMap();
 567 pnkfelix 1.1.2.9                  for(Iterator nds=graph.nodeSet().iterator();nds.hasNext();){
 568 pnkfelix 1.1.2.9                      Object nd = nds.next();
 569 pnkfelix 1.1.2.10                     c2n.add(graph.getColor(nd), nd);
 570 pnkfelix 1.1.2.10                 }
 571 pnkfelix 1.1.2.22                 
 572 pnkfelix 1.1.2.22                 if (RESULTS) 
 573 pnkfelix 1.1.2.22                 for(Iterator cs=c2n.keySet().iterator();cs.hasNext();){ 
 574 pnkfelix 1.1.2.10                     Object col=cs.next();
 575 pnkfelix 1.1.2.24                     System.out.println(col + " nodes: "+
 576 pnkfelix 1.1.2.24                             readableNodes(c2n.getValues(col),nodeToNum));
 577 pnkfelix 1.1.2.9                  }
 578 pnkfelix 1.1.2.22                 
 579 pnkfelix 1.1.2.15                 modifyCode(graph);
 580 pnkfelix 1.1.2.28 
 581 pnkfelix 1.1.2.33                 // OptimisticGraphColorer.MONITOR = false;
 582 pnkfelix 1.1.2.5                  success = true;
 583 pnkfelix 1.1.2.11             } catch (UnableToColorGraph u) {
 584 pnkfelix 1.1.2.33                 // OptimisticGraphColorer.MONITOR = true;
 585 pnkfelix 1.1.2.5                  success = false;
 586 pnkfelix 1.1.2.34                 if (!aggressivelyCoalesce && doCoalescing) {
 587 pnkfelix 1.1.2.28                     doCoalescing = false;
 588 pnkfelix 1.1.2.31                     undoCoalescing();
 589 pnkfelix 1.1.2.28                 } else {
 590 pnkfelix 1.1.2.32                     // doCoalescing = true;
 591 pnkfelix 1.1.2.28                     genSpillCode(u, graph);
 592 pnkfelix 1.1.2.28                 }
 593 pnkfelix 1.1.2.1              }
 594 pnkfelix 1.1.2.1          } while (!success);
 595 pnkfelix 1.1.2.18 
 596 pnkfelix 1.1.2.18         fixupSpillCode();
 597 cananian 1.6              for(Object iO : willRemoveLater){
 598 cananian 1.6                  Instr i = (Instr) iO;
 599 pnkfelix 1.1.2.28             Temp sym;
 600 pnkfelix 1.1.2.28             if (isRegister(i.def()[0])) {
 601 pnkfelix 1.1.2.28                 sym = i.use()[0];
 602 pnkfelix 1.1.2.28             } else { 
 603 pnkfelix 1.1.2.28                 sym = i.def()[0];
 604 pnkfelix 1.1.2.28             }
 605 pnkfelix 1.1.2.28             InstrMOVEproxy proxy = new InstrMOVEproxy(i);           
 606 pnkfelix 1.1.2.28             replace(i, proxy);
 607 pnkfelix 1.1.2.28             code.assignRegister(proxy, sym, code.getRegisters(i, sym));
 608 pnkfelix 1.1.2.28         }
 609 pnkfelix 1.1.2.1      }
 610 pnkfelix 1.1.2.2  
 611 pnkfelix 1.1.2.13     // sets regToColor, regToDefs, regToUses, implicitAssigns
 612 pnkfelix 1.1.2.5      private void buildRegAssigns() {
 613 pnkfelix 1.1.2.13         HashSet assigns; // Set<Assign>
 614 pnkfelix 1.1.2.13         HashMap asnSetToImplc; // Set<Assign> -> Reg -> Assign
 615 pnkfelix 1.1.2.13         
 616 pnkfelix 1.1.2.13         // local vars
 617 pnkfelix 1.1.2.13         assigns = new HashSet();
 618 pnkfelix 1.1.2.13         asnSetToImplc = new HashMap();
 619 pnkfelix 1.1.2.5  
 620 pnkfelix 1.1.2.13         // global vars
 621 pnkfelix 1.1.2.13         implicitAssigns = new HashMap();
 622 pnkfelix 1.1.2.13         regToColor = new HashMap();
 623 pnkfelix 1.1.2.5          regToDefs = new GenericMultiMap();
 624 pnkfelix 1.1.2.9          regToUses = new GenericMultiMap();
 625 pnkfelix 1.1.2.13         
 626 pnkfelix 1.1.2.5          for(Iterator instrs=code.getElementsI(); instrs.hasNext();){
 627 pnkfelix 1.1.2.29             Instr inst = (Instr) instrs.next();
 628 pnkfelix 1.1.2.29             Iterator tmps = new CombineIterator(inst.defC().iterator(),
 629 pnkfelix 1.1.2.29                                                 inst.useC().iterator());
 630 pnkfelix 1.1.2.5              while(tmps.hasNext()) {
 631 pnkfelix 1.1.2.5                  Temp t = (Temp) tmps.next();
 632 pnkfelix 1.1.2.5                  if (rfi.isRegister(t)) {
 633 pnkfelix 1.1.2.29                     if (inst.defC().contains(t)) regToDefs.add(t, inst);
 634 pnkfelix 1.1.2.29                     if (inst.useC().contains(t)) regToUses.add(t, inst);
 635 pnkfelix 1.1.2.13                     
 636 pnkfelix 1.1.2.13                     // do not make a color for `t' here; otherwise
 637 pnkfelix 1.1.2.13                     // system registers (PC, SP, etc) get colors 
 638 pnkfelix 1.1.2.13                     continue;
 639 pnkfelix 1.1.2.13                 } 
 640 pnkfelix 1.1.2.13                 
 641 pnkfelix 1.1.2.13                 Set suggRegs = rfi.getRegAssignments(t);
 642 pnkfelix 1.1.2.13                 assigns.addAll(suggRegs);
 643 pnkfelix 1.1.2.13                 
 644 pnkfelix 1.1.2.13                 // incorporate into regToColor
 645 cananian 1.6                      for(Object rLO : suggRegs){
 646 cananian 1.6                          List rL = (List) rLO;
 647 cananian 1.6                          for(Object regO : rL){
 648 cananian 1.6                              Temp reg = (Temp) regO;
 649 pnkfelix 1.1.2.13                         regToColor(reg); 
 650 pnkfelix 1.1.2.13                     }
 651 pnkfelix 1.1.2.13                 }
 652 pnkfelix 1.1.2.13                 
 653 pnkfelix 1.1.2.13                 if (!implicitAssigns.keySet().contains(t)) {
 654 pnkfelix 1.1.2.13                     if (!asnSetToImplc.keySet().contains(suggRegs)) {
 655 pnkfelix 1.1.2.29                         // build (Reg -> Assign)[] for suggRegs
 656 pnkfelix 1.1.2.29                         Map[] i2r2a = null;
 657 cananian 1.6                              for(Object asnO : suggRegs){
 658 cananian 1.6                                  List asn = (List) asnO;
 659 pnkfelix 1.1.2.29                             if (i2r2a == null) {
 660 pnkfelix 1.1.2.29                                 i2r2a = new Map[asn.size()]; 
 661 pnkfelix 1.1.2.29                                 for(int j=0; j<i2r2a.length; j++) {
 662 pnkfelix 1.1.2.29                                     i2r2a[j] = new HashMap(10);
 663 pnkfelix 1.1.2.29                                 }
 664 pnkfelix 1.1.2.29                             }
 665 pnkfelix 1.1.2.29                             for(int i=0; i<asn.size(); i++) {
 666 pnkfelix 1.1.2.29                                 Temp reg = (Temp) asn.get(i);
 667 pnkfelix 1.1.2.29                                 i2r2a[i].put(reg, asn);
 668 pnkfelix 1.1.2.13                             }
 669 pnkfelix 1.1.2.5                          }
 670 pnkfelix 1.1.2.29                         asnSetToImplc.put(suggRegs, i2r2a);
 671 pnkfelix 1.1.2.5                      }
 672 pnkfelix 1.1.2.13 
 673 pnkfelix 1.1.2.13                     // add to implicitAssigns
 674 pnkfelix 1.1.2.29                     Object i2r2a = asnSetToImplc.get(suggRegs);
 675 pnkfelix 1.1.2.29                     implicitAssigns.put(t, i2r2a);
 676 pnkfelix 1.1.2.5                  }
 677 pnkfelix 1.1.2.5              }
 678 pnkfelix 1.1.2.5          }
 679 pnkfelix 1.1.2.5      }
 680 pnkfelix 1.1.2.5      
 681 pnkfelix 1.1.2.16     private RegColor regToColor(Temp reg) {
 682 pnkfelix 1.1.2.16         RegColor c = (RegColor) regToColor.get(reg);
 683 pnkfelix 1.1.2.5          if (c == null) {
 684 pnkfelix 1.1.2.5              c = new RegColor(reg);
 685 pnkfelix 1.1.2.5              regToColor.put(reg, c);
 686 pnkfelix 1.1.2.5          }
 687 pnkfelix 1.1.2.5          return c;
 688 pnkfelix 1.1.2.5      }
 689 pnkfelix 1.1.2.2  
 690 pnkfelix 1.1.2.5      class RegColor extends Color {
 691 pnkfelix 1.1.2.5          final Temp reg;
 692 pnkfelix 1.1.2.5          RegColor(Temp r) {
 693 pnkfelix 1.1.2.5              this.reg = r;
 694 pnkfelix 1.1.2.5          }
 695 pnkfelix 1.1.2.6          public String toString() { 
 696 pnkfelix 1.1.2.6              return "c:"+reg;
 697 pnkfelix 1.1.2.6          }
 698 pnkfelix 1.1.2.17         public boolean equals(Object o) {
 699 pnkfelix 1.1.2.17             return ((RegColor)o).reg.equals(this.reg);
 700 pnkfelix 1.1.2.17         }
 701 pnkfelix 1.1.2.5      }
 702 pnkfelix 1.1.2.5      
 703 pnkfelix 1.1.2.4      /**
 704 pnkfelix 1.1.2.5         nwebs is set after this method returns.
 705 pnkfelix 1.1.2.21        regWebRecords, tempWebRecords, and webRecords are set
 706 pnkfelix 1.1.2.5         after this method returns.
 707 pnkfelix 1.1.2.4       */
 708 pnkfelix 1.1.2.3      private void makeWebs(ReachingDefs rdefs) {
 709 pnkfelix 1.1.2.12         Set webSet = new HashSet(), tmp1; // Set<TempWebRecord>
 710 pnkfelix 1.1.2.5          TempWebRecord web1, web2;
 711 pnkfelix 1.1.2.4          List sd; // [Temp, Def]
 712 pnkfelix 1.1.2.2          int i, oldnwebs;
 713 pnkfelix 1.1.2.2          
 714 pnkfelix 1.1.2.3          for(Iterator instrs = code.getElementsI();instrs.hasNext();){ 
 715 pnkfelix 1.1.2.3              Instr inst = (Instr) instrs.next();
 716 cananian 1.6                  for(Object tO : inst.useC()){ 
 717 cananian 1.6                      Temp t = (Temp) tO;
 718 pnkfelix 1.1.2.22 
 719 pnkfelix 1.1.2.24                 if (isRegister(t)) continue;
 720 pnkfelix 1.1.2.8  
 721 pnkfelix 1.1.2.5                  TempWebRecord web = 
 722 pnkfelix 1.1.2.5                      new TempWebRecord
 723 pnkfelix 1.1.2.5                      (t, new LinearSet(rdefs.reachingDefs(inst,t)),
 724 pnkfelix 1.1.2.5                       new LinearSet(Collections.singleton(inst)));
 725 pnkfelix 1.1.2.3                  webSet.add(web);
 726 pnkfelix 1.1.2.12 
 727 pnkfelix 1.1.2.12                 List ixt = Default.pair(inst, t);
 728 pnkfelix 1.1.2.12                 if (!ixtToWebPreCombine.keySet().contains(ixt)) {
 729 pnkfelix 1.1.2.12                     ixtToWebPreCombine.put(ixt, web);
 730 pnkfelix 1.1.2.12                 }
 731 pnkfelix 1.1.2.3              }
 732 pnkfelix 1.1.2.7  
 733 pnkfelix 1.1.2.7              // in practice, the remainder of the web building should
 734 pnkfelix 1.1.2.12             // work w/o the following loop.  but if there is a def w/o
 735 pnkfelix 1.1.2.7              // a corresponding use, the system breaks.
 736 pnkfelix 1.1.2.12 
 737 cananian 1.6                  for(Object tO : inst.defC()){
 738 cananian 1.6                      Temp t = (Temp) tO;
 739 pnkfelix 1.1.2.22                 
 740 pnkfelix 1.1.2.24                 if (isRegister(t)) continue;
 741 pnkfelix 1.1.2.40 
 742 pnkfelix 1.1.2.40                 // FSK: shouldn't this be kept in the else-block
 743 pnkfelix 1.1.2.40                 // alone?  Leaving alone for now... (XP style)
 744 pnkfelix 1.1.2.7                  TempWebRecord web =
 745 pnkfelix 1.1.2.7                      new TempWebRecord
 746 pnkfelix 1.1.2.7                      (t, new LinearSet(Collections.singleton(inst)),
 747 pnkfelix 1.1.2.7                       new LinearSet(Collections.EMPTY_SET));
 748 pnkfelix 1.1.2.7                  webSet.add(web);
 749 pnkfelix 1.1.2.12                 
 750 pnkfelix 1.1.2.12                 List ixt = Default.pair(inst, t);
 751 pnkfelix 1.1.2.12                 if (ixtToWebPreCombine.keySet().contains(ixt)) {
 752 pnkfelix 1.1.2.12                     TempWebRecord wr = (TempWebRecord) 
 753 pnkfelix 1.1.2.12                         ixtToWebPreCombine.get(ixt);
 754 pnkfelix 1.1.2.12                     wr.defs.add(inst);
 755 pnkfelix 1.1.2.12                 } else {
 756 pnkfelix 1.1.2.40 
 757 pnkfelix 1.1.2.12                     ixtToWebPreCombine.put(ixt, web);
 758 pnkfelix 1.1.2.12                 }
 759 pnkfelix 1.1.2.7              }
 760 pnkfelix 1.1.2.2          }
 761 pnkfelix 1.1.2.5  
 762 pnkfelix 1.1.2.7          // System.out.println("pre-duchain-combination");
 763 pnkfelix 1.1.2.7          // System.out.println("webSet: "+webSet);
 764 pnkfelix 1.1.2.5  
 765 pnkfelix 1.1.2.40         boolean changed; 
 766 pnkfelix 1.1.2.2          do {
 767 pnkfelix 1.1.2.2              // combine du-chains for the same symbol and that have a
 768 pnkfelix 1.1.2.7              // def in common to make webs  
 769 pnkfelix 1.1.2.5              changed = false;
 770 pnkfelix 1.1.2.3              tmp1 = new HashSet(webSet);
 771 pnkfelix 1.1.2.40 
 772 pnkfelix 1.1.2.2              while(!tmp1.isEmpty()) {
 773 pnkfelix 1.1.2.5                  web1 = (TempWebRecord) tmp1.iterator().next();
 774 pnkfelix 1.1.2.2                  tmp1.remove(web1);
 775 pnkfelix 1.1.2.12 
 776 pnkfelix 1.1.2.40                 // put webs to be removed post-iteration here
 777 pnkfelix 1.1.2.40                 HashSet removeFromTmp1 = new HashSet(); 
 778 pnkfelix 1.1.2.40 
 779 pnkfelix 1.1.2.12                 for(Iterator t2s=tmp1.iterator(); t2s.hasNext(); ){
 780 pnkfelix 1.1.2.12                     web2 = (TempWebRecord) t2s.next();
 781 pnkfelix 1.1.2.40                     
 782 pnkfelix 1.1.2.2                      if (web1.sym.equals(web2.sym)) {
 783 pnkfelix 1.1.2.9                          boolean combineWebs;
 784 pnkfelix 1.1.2.3                          Set ns = new HashSet(web1.defs);
 785 pnkfelix 1.1.2.3                          ns.retainAll(web2.defs);
 786 pnkfelix 1.1.2.9                          combineWebs = !ns.isEmpty();
 787 pnkfelix 1.1.2.9                          
 788 pnkfelix 1.1.2.9                          if (!combineWebs) {
 789 pnkfelix 1.1.2.9                              // IMPORTANT: current temp->reg assignment
 790 pnkfelix 1.1.2.9                              // design breaks if an instr needs two
 791 pnkfelix 1.1.2.9                              // different regs for the same temp in the
 792 pnkfelix 1.1.2.22                             // uses and defines.  Take this clause out
 793 pnkfelix 1.1.2.22                             // after that is fixed. 
 794 pnkfelix 1.1.2.9                              Set s1 = new HashSet(web1.defs);
 795 pnkfelix 1.1.2.9                              s1.retainAll(web2.uses);
 796 pnkfelix 1.1.2.9                              
 797 pnkfelix 1.1.2.9                              Set s2 = new HashSet(web2.defs);
 798 pnkfelix 1.1.2.9                              s2.retainAll(web1.uses);
 799 pnkfelix 1.1.2.9                              combineWebs = (!s1.isEmpty() || !s2.isEmpty());
 800 pnkfelix 1.1.2.9                          }
 801 pnkfelix 1.1.2.9                          
 802 pnkfelix 1.1.2.22                         if (false) System.out.println
 803 pnkfelix 1.1.2.22                                        (combineWebs?
 804 pnkfelix 1.1.2.22                                         "combining "+web1+" & "+web2:
 805 pnkfelix 1.1.2.22                                         "NOT combining "+web1+" & "+web2);
 806 pnkfelix 1.1.2.9                          
 807 pnkfelix 1.1.2.9                          if (combineWebs) {
 808 pnkfelix 1.1.2.2                              web1.defs.addAll(web2.defs);
 809 pnkfelix 1.1.2.2                              web1.uses.addAll(web2.uses);
 810 pnkfelix 1.1.2.2                              webSet.remove(web2);
 811 pnkfelix 1.1.2.40                             removeFromTmp1.add(web2);
 812 pnkfelix 1.1.2.5                              changed = true;
 813 pnkfelix 1.1.2.2                          }
 814 pnkfelix 1.1.2.2                      }
 815 pnkfelix 1.1.2.2                  }
 816 pnkfelix 1.1.2.40                 
 817 pnkfelix 1.1.2.40                 tmp1.removeAll(removeFromTmp1);
 818 pnkfelix 1.1.2.40 
 819 pnkfelix 1.1.2.2              }
 820 pnkfelix 1.1.2.5          } while ( changed );
 821 pnkfelix 1.1.2.5          
 822 pnkfelix 1.1.2.7          // System.out.println("post-duchain-combination");
 823 pnkfelix 1.1.2.7          // System.out.println("webSet: "+webSet);
 824 pnkfelix 1.1.2.2          
 825 pnkfelix 1.1.2.13         
 826 pnkfelix 1.1.2.13         regWebRecords = new ArrayList(regToColor.keySet().size());
 827 pnkfelix 1.1.2.13         
 828 pnkfelix 1.1.2.27         regToWeb = new HashMap();
 829 pnkfelix 1.1.2.13         Iterator rs = regToColor.keySet().iterator();
 830 pnkfelix 1.1.2.13         for(i=0; rs.hasNext(); i++) {
 831 pnkfelix 1.1.2.13             Temp reg = (Temp) rs.next();
 832 pnkfelix 1.1.2.13             WebRecord w = new RegWebRecord(reg);
 833 pnkfelix 1.1.2.5              w.sreg(i);
 834 pnkfelix 1.1.2.13             regWebRecords.add(w);
 835 pnkfelix 1.1.2.27             regToWeb.put(reg, w);
 836 pnkfelix 1.1.2.5          }
 837 pnkfelix 1.1.2.5          tempWebRecords = new ArrayList(webSet.size());
 838 pnkfelix 1.1.2.5          for(Iterator webs = webSet.iterator(); webs.hasNext(); i++) {
 839 pnkfelix 1.1.2.5              WebRecord w = (TempWebRecord) webs.next();
 840 pnkfelix 1.1.2.5              w.sreg(i);
 841 pnkfelix 1.1.2.5              tempWebRecords.add(w);
 842 pnkfelix 1.1.2.5          }
 843 pnkfelix 1.1.2.5          webRecords = ListFactory.concatenate
 844 pnkfelix 1.1.2.13             (Default.pair(regWebRecords, tempWebRecords));
 845 pnkfelix 1.1.2.12 
 846 cananian 1.6              for(Object wrO : tempWebRecords){
 847 cananian 1.6                  WebRecord wr = (WebRecord) wrO;
 848 pnkfelix 1.1.2.13             Temp t = wr.temp();
 849 pnkfelix 1.1.2.35 
 850 pnkfelix 1.1.2.13             Iterator is = new
 851 pnkfelix 1.1.2.13                 CombineIterator(wr.defs().iterator(),
 852 pnkfelix 1.1.2.13                                 wr.uses().iterator()); 
 853 pnkfelix 1.1.2.13             while( is.hasNext() ) {
 854 pnkfelix 1.1.2.13                 Instr inst = (Instr) is.next();
 855 pnkfelix 1.1.2.13                 List ixt = Default.pair(inst,t);
 856 pnkfelix 1.1.2.13                 WebRecord prior = (WebRecord) ixtToWeb.get(ixt);
 857 cananian 1.3.2.1                  assert prior == null || prior == wr;
 858 pnkfelix 1.1.2.13                 ixtToWeb.put(ixt, wr);
 859 pnkfelix 1.1.2.12             }
 860 pnkfelix 1.1.2.12         }
 861 pnkfelix 1.1.2.21 
 862 pnkfelix 1.1.2.21         // ASSERTION EQUALITY CHECK (with feedback info)
 863 pnkfelix 1.1.2.12         if(!ixtToWeb.keySet().equals(ixtToWebPreCombine.keySet())) {
 864 pnkfelix 1.1.2.12             HashSet postMinusPre = new HashSet(ixtToWeb.keySet());
 865 pnkfelix 1.1.2.12             HashSet preMinusPost = new HashSet(ixtToWebPreCombine.keySet());
 866 pnkfelix 1.1.2.12             postMinusPre.removeAll(ixtToWebPreCombine.keySet());
 867 pnkfelix 1.1.2.12             preMinusPost.removeAll(ixtToWeb.keySet());
 868 pnkfelix 1.1.2.12             
 869 pnkfelix 1.1.2.12             System.out.println("PRE - POST: " + preMinusPost);
 870 pnkfelix 1.1.2.12             System.out.println();
 871 pnkfelix 1.1.2.12             System.out.println("POST - PRE: " + postMinusPre);
 872 pnkfelix 1.1.2.12             System.out.println();
 873 cananian 1.3.2.1              assert false;
 874 pnkfelix 1.1.2.12         }
 875 pnkfelix 1.1.2.5      }
 876 pnkfelix 1.1.2.33     
 877 pnkfelix 1.1.2.5      private AdjMtx buildAdjMatrix() { 
 878 pnkfelix 1.1.2.18         HashSet visited = new HashSet();
 879 pnkfelix 1.1.2.18 
 880 pnkfelix 1.1.2.5          AdjMtx adjMtx = new AdjMtx(webRecords);
 881 pnkfelix 1.1.2.2          int i, j;
 882 pnkfelix 1.1.2.18         int sz = webRecords.size();
 883 pnkfelix 1.1.2.25 
 884 pnkfelix 1.1.2.18         for(i=0; i<sz; i++) {
 885 pnkfelix 1.1.2.11             WebRecord wr1 = (WebRecord) webRecords.get(i);
 886 pnkfelix 1.1.2.18             visited.add(wr1);
 887 pnkfelix 1.1.2.33             
 888 pnkfelix 1.1.2.18             for(j=i+1; j<sz; j++) {
 889 pnkfelix 1.1.2.5                  WebRecord wr2 = (WebRecord) webRecords.get(j);
 890 pnkfelix 1.1.2.33                 
 891 pnkfelix 1.1.2.33                 adjMtx.set(wr1.sreg(),wr2.sreg(),wr1.conflictsWith(wr2));
 892 pnkfelix 1.1.2.2              }
 893 pnkfelix 1.1.2.2          }
 894 pnkfelix 1.1.2.25 
 895 pnkfelix 1.1.2.5          return adjMtx;
 896 pnkfelix 1.1.2.2      }
 897 pnkfelix 1.1.2.28 
 898 pnkfelix 1.1.2.32     Set willRemoveLater = new HashSet(); // Set<Instr>
 899 pnkfelix 1.1.2.32     // EqTempSets remap = EqTempSets.make(this, false);
 900 pnkfelix 1.1.2.32     EqWebRecords remap = new EqWebRecords();
 901 pnkfelix 1.1.2.32 
 902 pnkfelix 1.1.2.28     /** returns the set of removed Instrs. */
 903 pnkfelix 1.1.2.28     private Set coalesceRegs(AdjMtx adjMtx) { 
 904 pnkfelix 1.1.2.32         // RESET DATA STRUCTURES
 905 pnkfelix 1.1.2.28         HashSet willRemoveNow = new HashSet(); // Set<Instr>
 906 pnkfelix 1.1.2.32         willRemoveLater.clear();
 907 pnkfelix 1.1.2.32         webPrecolor.clear();
 908 pnkfelix 1.1.2.32         // remap = EqTempSets.make(this, false);
 909 pnkfelix 1.1.2.32         remap = new EqWebRecords();
 910 pnkfelix 1.1.2.28 
 911 pnkfelix 1.1.2.26         // ANALYZE
 912 pnkfelix 1.1.2.26         for(Iterator is=code.getElementsI(); is.hasNext();) {
 913 pnkfelix 1.1.2.26             Instr i = (Instr) is.next();
 914 pnkfelix 1.1.2.41 
 915 pnkfelix 1.1.2.41             // System.out.println("Instr: "+i);
 916 pnkfelix 1.1.2.41 
 917 pnkfelix 1.1.2.26             if (i instanceof harpoon.IR.Assem.InstrMOVE) {
 918 pnkfelix 1.1.2.27                 Temp use = i.use()[0];
 919 pnkfelix 1.1.2.27                 Temp def = i.def()[0];
 920 pnkfelix 1.1.2.27                 WebRecord wUse = getWR(i, use);
 921 pnkfelix 1.1.2.27                 WebRecord wDef = getWR(i, def);
 922 pnkfelix 1.1.2.31 
 923 pnkfelix 1.1.2.31                 // this assertion seems like it should hold, but
 924 pnkfelix 1.1.2.31                 // doesn't.  Need to review conflictsWith code and
 925 pnkfelix 1.1.2.31                 // change to update adjMtx accordingly
 926 pnkfelix 1.1.2.31                 if (false) 
 927 cananian 1.3.2.1                      assert wUse.conflictsWith(wDef) ==
 928 cananian 1.3.2.1                                   adjMtx.get(wUse.sreg(), wDef.sreg()) : " conflictsWith:"+wUse.conflictsWith(wDef)+
 929 pnkfelix 1.1.2.31                                  " adjMtx.get:"+adjMtx.get(wUse.sreg(), 
 930 cananian 1.3.2.1                                                             wDef.sreg());
 931 pnkfelix 1.1.2.31                 
 932 pnkfelix 1.1.2.35                 // if (adjMtx.get(wUse.sreg(), wDef.sreg())) {
 933 pnkfelix 1.1.2.35                 // if (wUse.conflictsWith(wDef)) {
 934 pnkfelix 1.1.2.41                 
 935 pnkfelix 1.1.2.41                 long start_time = System.currentTimeMillis();
 936 pnkfelix 1.1.2.41 
 937 pnkfelix 1.1.2.41                 boolean remapConflicting = remap.conflicting(wDef, wUse);
 938 pnkfelix 1.1.2.41 
 939 pnkfelix 1.1.2.41                 if (false)System.out.println("remapConflict compute time:"+
 940 pnkfelix 1.1.2.41                                    (System.currentTimeMillis() - start_time));
 941 pnkfelix 1.1.2.41 
 942 pnkfelix 1.1.2.41                 if (remapConflicting) {
 943 pnkfelix 1.1.2.35 
 944 pnkfelix 1.1.2.35                 } else {
 945 pnkfelix 1.1.2.27                     if (def.equals(use)) {
 946 pnkfelix 1.1.2.27                         // (nothing special to update)
 947 pnkfelix 1.1.2.28                         willRemoveNow.add(i);
 948 pnkfelix 1.1.2.27                     } else if (isRegister(def)) {
 949 pnkfelix 1.1.2.41                         if (!COALESCE_MACH_REGS) continue; // FSK investigated scalability problems
 950 pnkfelix 1.1.2.41 
 951 pnkfelix 1.1.2.35                         //if (webPrecolor.containsKey(wUse)) continue;
 952 pnkfelix 1.1.2.35                         if (remap.anyConflicting
 953 pnkfelix 1.1.2.35                             (wUse,webPrecolor.invert().getValues(def))){
 954 pnkfelix 1.1.2.27                             continue;
 955 pnkfelix 1.1.2.35                         }
 956 pnkfelix 1.1.2.27                         webPrecolor.put(wUse, def);
 957 pnkfelix 1.1.2.28                         willRemoveLater.add(i);
 958 pnkfelix 1.1.2.27                     } else if (isRegister(use)) {
 959 pnkfelix 1.1.2.41                         if (!COALESCE_MACH_REGS) continue; // FSK investigated scalability problems
 960 pnkfelix 1.1.2.41 
 961 pnkfelix 1.1.2.35                         // if (webPrecolor.containsKey(wUse)) continue;
 962 pnkfelix 1.1.2.35                         if (remap.anyConflicting
 963 pnkfelix 1.1.2.35                             (wDef,webPrecolor.invert().getValues(use))){
 964 pnkfelix 1.1.2.27                             continue;
 965 pnkfelix 1.1.2.35                         }
 966 pnkfelix 1.1.2.27                         webPrecolor.put(wDef, use);
 967 pnkfelix 1.1.2.28                         willRemoveLater.add(i);
 968 pnkfelix 1.1.2.26                     } else {
 969 cananian 1.3.2.1                          assert !wDef.equals(wUse);
 970 pnkfelix 1.1.2.32                         remap.union(wDef, wUse);
 971 pnkfelix 1.1.2.28                         willRemoveNow.add(i);
 972 pnkfelix 1.1.2.26                     }
 973 pnkfelix 1.1.2.26                 }
 974 pnkfelix 1.1.2.26             }
 975 pnkfelix 1.1.2.26         }
 976 pnkfelix 1.1.2.26 
 977 pnkfelix 1.1.2.26         // TRANSFORM
 978 pnkfelix 1.1.2.28         if (!willRemoveNow.isEmpty()) {
 979 pnkfelix 1.1.2.27             for(Iterator is=code.getElementsI(); is.hasNext();) {
 980 pnkfelix 1.1.2.27                 Instr i= (Instr) is.next();
 981 pnkfelix 1.1.2.28                 if (willRemoveNow.contains(i)) {
 982 pnkfelix 1.1.2.32                     replace(i, new InstrMOVEproxy(remap.rename(i)));
 983 pnkfelix 1.1.2.27                 } else {
 984 pnkfelix 1.1.2.27                     Iterator itr = new
 985 pnkfelix 1.1.2.27                         CombineIterator(i.useC().iterator(),
 986 pnkfelix 1.1.2.27                                         i.defC().iterator());
 987 pnkfelix 1.1.2.27                     while(itr.hasNext()) {
 988 pnkfelix 1.1.2.27                         Temp t = (Temp) itr.next();
 989 pnkfelix 1.1.2.32                         
 990 pnkfelix 1.1.2.32                         //if (!remap.tempMap(t).equals(t)) {
 991 pnkfelix 1.1.2.32                         if (remap.containsTemp(t)) {
 992 pnkfelix 1.1.2.32                             Instr repl = remap.rename(i);
 993 pnkfelix 1.1.2.31                             replace(i, repl);
 994 pnkfelix 1.1.2.32                             if (willRemoveLater.contains(i)) {
 995 pnkfelix 1.1.2.32                                 willRemoveLater.remove(i);
 996 pnkfelix 1.1.2.31                                 willRemoveLater.add(repl);
 997 pnkfelix 1.1.2.32                             }
 998 pnkfelix 1.1.2.27                             break;
 999 pnkfelix 1.1.2.2                          }
1000 pnkfelix 1.1.2.2                      }
1001 pnkfelix 1.1.2.2                  }
1002 pnkfelix 1.1.2.2              }
1003 pnkfelix 1.1.2.28             if (COALESCE_STATS)
1004 pnkfelix 1.1.2.28                 System.out.print("R:"+ willRemoveNow.size()   );
1005 pnkfelix 1.1.2.28         } else if (!willRemoveLater.isEmpty()) {
1006 pnkfelix 1.1.2.28             if (COALESCE_STATS)
1007 pnkfelix 1.1.2.28                 System.out.print("R:"+ willRemoveLater.size() );
1008 pnkfelix 1.1.2.2          }
1009 pnkfelix 1.1.2.28         return willRemoveNow;
1010 pnkfelix 1.1.2.2      }
1011 pnkfelix 1.1.2.35     
1012 pnkfelix 1.1.2.6      private WebRecord[] buildAdjLists(AdjMtx adjMtx) { 
1013 pnkfelix 1.1.2.2          int i, j;
1014 pnkfelix 1.1.2.5          final int nwebs = webRecords.size();
1015 pnkfelix 1.1.2.6          final WebRecord[] adjLsts = new WebRecord[nwebs];
1016 pnkfelix 1.1.2.13         for(i=0; i<regWebRecords.size(); i++) {
1017 pnkfelix 1.1.2.13             adjLsts[i] = (WebRecord) regWebRecords.get(i);
1018 pnkfelix 1.1.2.2              adjLsts[i].spcost =  Double.POSITIVE_INFINITY;
1019 pnkfelix 1.1.2.2          }
1020 pnkfelix 1.1.2.13         int offset = regWebRecords.size();
1021 pnkfelix 1.1.2.6          for(i=0; i<tempWebRecords.size(); i++) {
1022 pnkfelix 1.1.2.6              adjLsts[offset+i]= (WebRecord) tempWebRecords.get(i);
1023 pnkfelix 1.1.2.2          }
1024 pnkfelix 1.1.2.5          for(i=1; i < nwebs; i++) {
1025 pnkfelix 1.1.2.5              for(j=0; j < i; j++) {
1026 pnkfelix 1.1.2.18                 WebRecord wr1, wr2;
1027 pnkfelix 1.1.2.18                 wr1 = adjLsts[i];
1028 pnkfelix 1.1.2.18                 wr2 = adjLsts[j];
1029 pnkfelix 1.1.2.31                 
1030 pnkfelix 1.1.2.31                 //FSK: using this test breaks (i suspect due to
1031 pnkfelix 1.1.2.31                 //FSK: modifying instr-sequence concurrently with
1032 pnkfelix 1.1.2.31                 //FSK: analysis) 
1033 pnkfelix 1.1.2.28                 // if (wr1.conflictsWith(wr2)) {                
1034 pnkfelix 1.1.2.18                 if (adjMtx.get(wr1.sreg(),wr2.sreg())) {
1035 pnkfelix 1.1.2.28 
1036 pnkfelix 1.1.2.18                     wr1.adjnds.add(wr2);
1037 pnkfelix 1.1.2.18                     wr2.adjnds.add(wr1);
1038 pnkfelix 1.1.2.18                     wr1.nints++;
1039 pnkfelix 1.1.2.18                     wr2.nints++;
1040 pnkfelix 1.1.2.2                  }
1041 pnkfelix 1.1.2.2              }
1042 pnkfelix 1.1.2.2          }
1043 pnkfelix 1.1.2.5          return adjLsts;
1044 pnkfelix 1.1.2.2      }
1045 pnkfelix 1.1.2.2  
1046 pnkfelix 1.1.2.2      private void computeSpillCosts() { 
1047 pnkfelix 1.1.2.2          
1048 pnkfelix 1.1.2.2      }
1049 pnkfelix 1.1.2.2  
1050 pnkfelix 1.1.2.13     private Graph buildGraph(WebRecord[] adjLsts) {
1051 pnkfelix 1.1.2.14         Graph g = new Graph();
1052 pnkfelix 1.1.2.14         for(int i=0; i<adjLsts.length; i++) {
1053 pnkfelix 1.1.2.14             g.add(adjLsts[i]);
1054 pnkfelix 1.1.2.14         }
1055 pnkfelix 1.1.2.14         return g;
1056 pnkfelix 1.1.2.2      }
1057 pnkfelix 1.1.2.2  
1058 pnkfelix 1.1.2.42     private Set defRegSet( Instr i ){
1059 pnkfelix 1.1.2.42         LinearSet regs = new LinearSet();
1060 cananian 1.6              for(Object dO : i.defC()){
1061 cananian 1.6                  Temp d = (Temp) dO;
1062 pnkfelix 1.1.2.42             if (code.registerAssigned(i,d))
1063 pnkfelix 1.1.2.42                 regs.addAll( code.getRegisters(i,d) );
1064 pnkfelix 1.1.2.42         }
1065 pnkfelix 1.1.2.42         return regs;
1066 pnkfelix 1.1.2.42     }
1067 pnkfelix 1.1.2.42 
1068 pnkfelix 1.1.2.15     private void modifyCode(Graph g) { 
1069 cananian 1.6              for(Object wrO : tempWebRecords){
1070 cananian 1.6                  TempWebRecord wr = (TempWebRecord) wrO;
1071 pnkfelix 1.1.2.6              Iterator instrs;
1072 pnkfelix 1.1.2.6              for(instrs = wr.defs.iterator(); instrs.hasNext();) {
1073 pnkfelix 1.1.2.6                  Instr i = (Instr) instrs.next();
1074 pnkfelix 1.1.2.42 
1075 pnkfelix 1.1.2.42                 // assert def-sets are disjoint for a given instruction
1076 pnkfelix 1.1.2.42                 Set regs = defRegSet(i);
1077 pnkfelix 1.1.2.42                 regs.retainAll( g.regs(wr) );
1078 cananian 1.3.2.1                  assert regs.isEmpty() : "def-sets should be disjoint!";
1079 pnkfelix 1.1.2.42 
1080 pnkfelix 1.1.2.15                 code.assignRegister(i, wr.sym, g.regs(wr));
1081 pnkfelix 1.1.2.6              }
1082 pnkfelix 1.1.2.6              for(instrs = wr.uses.iterator(); instrs.hasNext();) {
1083 pnkfelix 1.1.2.6                  Instr i = (Instr) instrs.next();
1084 pnkfelix 1.1.2.15                 code.assignRegister(i, wr.sym, g.regs(wr));
1085 pnkfelix 1.1.2.6              }
1086 pnkfelix 1.1.2.6          }
1087 pnkfelix 1.1.2.2      } 
1088 pnkfelix 1.1.2.2  
1089 pnkfelix 1.1.2.18 
1090 pnkfelix 1.1.2.18     HashSet spilled = new HashSet();
1091 pnkfelix 1.1.2.28     
1092 pnkfelix 1.1.2.28     private boolean isPrecolored(Object n) { 
1093 pnkfelix 1.1.2.28         Graph.Node node = (Graph.Node) n;
1094 pnkfelix 1.1.2.28         if (node.wr instanceof RegWebRecord) 
1095 pnkfelix 1.1.2.28             return true;
1096 pnkfelix 1.1.2.28         if (webPrecolor.containsKey(node.wr)) 
1097 pnkfelix 1.1.2.28             return true;
1098 pnkfelix 1.1.2.28         return false;
1099 pnkfelix 1.1.2.28     }
1100 pnkfelix 1.1.2.28 
1101 pnkfelix 1.1.2.31     private boolean isAvailableToSpill(Object n) {
1102 pnkfelix 1.1.2.28         Graph.Node node = (Graph.Node) n;
1103 pnkfelix 1.1.2.29         if (isRegister(node.wr.temp())) 
1104 pnkfelix 1.1.2.31             return false;
1105 cananian 1.6              for(Object splO : spilled){ 
1106 cananian 1.6                  WebRecord spl = (WebRecord) splO;
1107 pnkfelix 1.1.2.29             if (spl.temp().equals(node.wr.temp()) &&
1108 pnkfelix 1.1.2.29                 spl.overlaps(node.wr)) 
1109 pnkfelix 1.1.2.31                 return false;
1110 pnkfelix 1.1.2.28         }
1111 pnkfelix 1.1.2.31         return true;
1112 pnkfelix 1.1.2.28     }
1113 pnkfelix 1.1.2.28         
1114 pnkfelix 1.1.2.28 
1115 pnkfelix 1.1.2.28     private void genSpillCode(UnableToColorGraph u, Graph g) { 
1116 pnkfelix 1.1.2.28         Collection remove = u.getRemovalSuggestions();
1117 pnkfelix 1.1.2.22         HashSet spillThese = new HashSet(remove.size());
1118 pnkfelix 1.1.2.28 
1119 cananian 1.6              for(Object nodeO : remove) {
1120 cananian 1.6                  Graph.Node node = (Graph.Node) nodeO;
1121 pnkfelix 1.1.2.28 
1122 pnkfelix 1.1.2.31             if (!isAvailableToSpill(node)) {
1123 pnkfelix 1.1.2.34                 if (SCARY_OUTPUT) System.out.println("SKIP ONE (1)");
1124 pnkfelix 1.1.2.28             }
1125 pnkfelix 1.1.2.28             
1126 pnkfelix 1.1.2.22             spillThese.add(node);
1127 pnkfelix 1.1.2.22         }
1128 pnkfelix 1.1.2.34         if (SCARY_OUTPUT) System.out.println("HIT1:"+spillThese.size());
1129 pnkfelix 1.1.2.28         
1130 pnkfelix 1.1.2.28         if (spillThese.isEmpty()) {
1131 pnkfelix 1.1.2.28             System.out.println(" remove:" +remove+ " contains nothing new");
1132 pnkfelix 1.1.2.28             Collection removeLrg = u.getRemovalSuggestionsBackup();
1133 pnkfelix 1.1.2.28             removeLrg = new HashSet(removeLrg);
1134 pnkfelix 1.1.2.28             removeLrg.removeAll(remove);
1135 pnkfelix 1.1.2.28         nextNode:
1136 cananian 1.6                  for(Object nodeO : removeLrg) {
1137 cananian 1.6                      Graph.Node node = (Graph.Node) nodeO;
1138 pnkfelix 1.1.2.28 
1139 pnkfelix 1.1.2.31                 if (!isAvailableToSpill(node)) {
1140 pnkfelix 1.1.2.34                     if (SCARY_OUTPUT) System.out.println("SKIP ONE (2)");
1141 pnkfelix 1.1.2.28                     continue nextNode;
1142 pnkfelix 1.1.2.28                 }
1143 pnkfelix 1.1.2.28 
1144 pnkfelix 1.1.2.28                 spillThese.add(node);
1145 pnkfelix 1.1.2.28             }
1146 pnkfelix 1.1.2.28 
1147 pnkfelix 1.1.2.34             if (SCARY_OUTPUT) System.out.println("HIT2:"+spillThese.size());
1148 pnkfelix 1.1.2.29 
1149 pnkfelix 1.1.2.28             if (spillThese.isEmpty())
1150 pnkfelix 1.1.2.34                 if (SCARY_OUTPUT) System.out.println
1151 pnkfelix 1.1.2.28                     (" remove:" +removeLrg+ " contains nothing new");
1152 pnkfelix 1.1.2.28         }
1153 pnkfelix 1.1.2.28 
1154 pnkfelix 1.1.2.28 
1155 pnkfelix 1.1.2.22         if (spillThese.isEmpty()) {
1156 pnkfelix 1.1.2.22             // choose a node independently of the suggested ones, since
1157 pnkfelix 1.1.2.22             // those are all already spilled...
1158 pnkfelix 1.1.2.22             HashSet nset = new HashSet(g.nodeSet());
1159 pnkfelix 1.1.2.22             nset.removeAll(spilled);
1160 pnkfelix 1.1.2.22             int md = -1; Object mn=null;
1161 cananian 1.6                  for(Object nO : nset) {
1162 cananian 1.6                      Graph.Node n = (Graph.Node) nO;
1163 pnkfelix 1.1.2.22                 if (g.getDegree(n) > md &&
1164 pnkfelix 1.1.2.22                     !isRegister(n.wr.temp()) &&
1165 pnkfelix 1.1.2.31                     isAvailableToSpill(n)) {
1166 pnkfelix 1.1.2.22                     mn = n;
1167 pnkfelix 1.1.2.22                     md = g.getDegree(n);
1168 pnkfelix 1.1.2.22                 }
1169 pnkfelix 1.1.2.22             }
1170 pnkfelix 1.1.2.29             if (mn != null)
1171 pnkfelix 1.1.2.29                 spillThese.add(mn);
1172 pnkfelix 1.1.2.22         }
1173 pnkfelix 1.1.2.22         
1174 cananian 1.3.2.1          assert !spillThese.isEmpty();
1175 cananian 1.3.2.1          assert !spillThese.contains(null);
1176 pnkfelix 1.1.2.29 
1177 cananian 1.6              for(Object nodeO : spillThese) {
1178 cananian 1.6                  Graph.Node node = (Graph.Node) nodeO;
1179 pnkfelix 1.1.2.18             spilled.add(node.wr);
1180 pnkfelix 1.1.2.18             
1181 pnkfelix 1.1.2.18             TempWebRecord wr = (TempWebRecord) node.wr;
1182 cananian 1.3.2.1              assert !isRegister(wr.temp());
1183 pnkfelix 1.1.2.22             
1184 pnkfelix 1.1.2.28             if (SPILL_INFO)
1185 pnkfelix 1.1.2.28                 System.out.print("\nSpilling "+wr);
1186 pnkfelix 1.1.2.22             
1187 pnkfelix 1.1.2.18             Temp t = wr.temp();
1188 cananian 1.6                  for(Object iO : wr.defs) {
1189 cananian 1.6                      Instr i = (Instr) iO;
1190 pnkfelix 1.1.2.36 
1191 pnkfelix 1.1.2.36                 if (i.isDummy()) 
1192 pnkfelix 1.1.2.36                     continue;
1193 pnkfelix 1.1.2.36 
1194 pnkfelix 1.1.2.18                 Instr n = i.getNext();
1195 pnkfelix 1.1.2.42 
1196 pnkfelix 1.1.2.42                 // FSK: checking if <n> is a dummy and
1197 pnkfelix 1.1.2.42                 // shifting the spill down if so...
1198 pnkfelix 1.1.2.42                 while( n.isDummy()) {
1199 pnkfelix 1.1.2.42                     i = n;
1200 pnkfelix 1.1.2.42                     n = i.getNext();
1201 pnkfelix 1.1.2.42                 }
1202 pnkfelix 1.1.2.42                 
1203 cananian 1.3.2.1                  assert i.canFallThrough &&
1204 cananian 1.3.2.1                              i.getTargets().isEmpty() : "can't insert spill at <"+i+" , "+n+">";
1205 pnkfelix 1.1.2.18                 SpillProxy sp = new SpillProxy(i, t);
1206 pnkfelix 1.1.2.18                 sp.layout(i, n);
1207 pnkfelix 1.1.2.18             }
1208 cananian 1.6                  for(Object iO : wr.uses) {
1209 cananian 1.6                      Instr i = (Instr) iO;
1210 pnkfelix 1.1.2.36 
1211 pnkfelix 1.1.2.36                 if (i.isDummy()) 
1212 pnkfelix 1.1.2.36                     continue;
1213 pnkfelix 1.1.2.36 
1214 pnkfelix 1.1.2.18                 Instr p = i.getPrev();
1215 cananian 1.3.2.1                  assert p.canFallThrough &&
1216 pnkfelix 1.1.2.18                             p.getTargets().isEmpty() &&
1217 cananian 1.3.2.1                              i.predC().size() == 1 : "can't insert restore at<"+p+" , "+i+">";
1218 pnkfelix 1.1.2.18                 RestoreProxy rp = new RestoreProxy(i, t);
1219 pnkfelix 1.1.2.18                 rp.layout(p, i);
1220 pnkfelix 1.1.2.18             }
1221 pnkfelix 1.1.2.18         }
1222 pnkfelix 1.1.2.18 
1223 pnkfelix 1.1.2.34         if (SCARY_OUTPUT) System.out.print("*** SPILLED ("+spilled.size()+")"+
1224 pnkfelix 1.1.2.34                                            (true?"":(": " + spilled)));
1225 pnkfelix 1.1.2.5      }
1226 pnkfelix 1.1.2.5      
1227 pnkfelix 1.1.2.28     /** returns nodeToNum. */
1228 pnkfelix 1.1.2.28     public static Map printGraph(ColorableGraph graph, boolean PRINT) {
1229 pnkfelix 1.1.2.28         final Map nodeToNum = new HashMap(); 
1230 pnkfelix 1.1.2.28         if(PRINT)System.out.println("nodes of graph");
1231 pnkfelix 1.1.2.28         int i=0;
1232 pnkfelix 1.1.2.28         for(Iterator nodes=graph.nodeSet().iterator();nodes.hasNext();){
1233 pnkfelix 1.1.2.28             i++;
1234 pnkfelix 1.1.2.28             Object n=nodes.next();
1235 pnkfelix 1.1.2.28             nodeToNum.put(n, new Integer(i));
1236 pnkfelix 1.1.2.28             if(PRINT)System.out.println(i+"\t"+n);
1237 pnkfelix 1.1.2.28         }
1238 pnkfelix 1.1.2.28         if (PRINT){
1239 pnkfelix 1.1.2.29             String s = ""+graph.edges();
1240 pnkfelix 1.1.2.28             Collection readEdges = readableEdges(graph.edges(),nodeToNum);
1241 pnkfelix 1.1.2.28             System.out.println("edges of graph "+readEdges);
1242 pnkfelix 1.1.2.28         }
1243 pnkfelix 1.1.2.28         return nodeToNum;
1244 pnkfelix 1.1.2.28     }
1245 pnkfelix 1.1.2.14 
1246 pnkfelix 1.1.2.5      /** Graph is a graph view of the adjacency lists in this. 
1247 pnkfelix 1.1.2.13         There is a many-to-one mapping from Nodes to WebRecords. 
1248 pnkfelix 1.1.2.15         Note that when a Node is hidden or colored, its association
1249 pnkfelix 1.1.2.15         with the WebRecord it maps to may cause other nodes to be
1250 pnkfelix 1.1.2.15         hidden or colored (nb: need to think this through more
1251 pnkfelix 1.1.2.15         carefully; algorithms depend on a particular semantics for
1252 pnkfelix 1.1.2.15         replace()'s behavior...)
1253 pnkfelix 1.1.2.13     */
1254 pnkfelix 1.1.2.5      class Graph extends AbstractGraph implements ColorableGraph {
1255 pnkfelix 1.1.2.29         private LinkedList nodes;  // LinkedList<Node>
1256 pnkfelix 1.1.2.15         private LinkedList hidden; // List<WebRecord>
1257 pnkfelix 1.1.2.15         private MultiMap wr2node;  // WebRecord -> Node
1258 pnkfelix 1.1.2.15 
1259 pnkfelix 1.1.2.15         /** Node is a record class representing the 
1260 pnkfelix 1.1.2.15             Node -> WebRecord mapping.  
1261 pnkfelix 1.1.2.15             It also holds the color for the node. 
1262 pnkfelix 1.1.2.14         */
1263 pnkfelix 1.1.2.14         class Node {
1264 pnkfelix 1.1.2.14             final WebRecord wr;
1265 pnkfelix 1.1.2.14             final int index; 
1266 pnkfelix 1.1.2.14             RegColor color;
1267 pnkfelix 1.1.2.29             
1268 pnkfelix 1.1.2.29             LinearSet  adjR;
1269 pnkfelix 1.1.2.29             LinkedList adjT;
1270 pnkfelix 1.1.2.29 
1271 pnkfelix 1.1.2.29             Node(WebRecord w, int i) { 
1272 pnkfelix 1.1.2.29                 wr = w; 
1273 pnkfelix 1.1.2.29                 index = i; 
1274 pnkfelix 1.1.2.29                 adjT = new LinkedList();
1275 pnkfelix 1.1.2.29                 adjR = new LinearSet();
1276 pnkfelix 1.1.2.29 
1277 pnkfelix 1.1.2.29                 nodes.add(this);
1278 pnkfelix 1.1.2.29                 wr2node.add(w, this);
1279 pnkfelix 1.1.2.29                 
1280 pnkfelix 1.1.2.29                 if (w instanceof TempWebRecord) {
1281 pnkfelix 1.1.2.29                     Map[] i2r2a = (Map[]) implicitAssigns.get(w.temp());
1282 pnkfelix 1.1.2.29                     Set conflictRegs = new LinearSet(regToWeb.keySet());
1283 pnkfelix 1.1.2.29                     Set possibleRegs = i2r2a[index].keySet();
1284 pnkfelix 1.1.2.29                     conflictRegs.removeAll(possibleRegs);
1285 pnkfelix 1.1.2.29                     for(Iterator cnf=conflictRegs.iterator();cnf.hasNext();){
1286 pnkfelix 1.1.2.29                         adjR.add(wr2node.get(regToWeb.get(cnf.next())));
1287 pnkfelix 1.1.2.29                     }
1288 pnkfelix 1.1.2.29                 }
1289 cananian 1.6                      for(Object _wrO : wr.adjnds){
1290 cananian 1.6                          WebRecord _wr = (WebRecord) _wrO;
1291 pnkfelix 1.1.2.29                     if (!wr2node.containsKey(_wr)) 
1292 pnkfelix 1.1.2.29                         continue;
1293 pnkfelix 1.1.2.29 
1294 cananian 1.6                          for (Object _nO : wr2node.getValues(_wr)) {
1295 cananian 1.6                              Node _n = (Node) _nO;
1296 pnkfelix 1.1.2.29                         if (_n.wr instanceof TempWebRecord) {
1297 pnkfelix 1.1.2.29                             adjT.add(_n);
1298 pnkfelix 1.1.2.29                         } else if (_n.wr instanceof RegWebRecord) {
1299 pnkfelix 1.1.2.29                             adjR.add(_n);
1300 pnkfelix 1.1.2.29                         } else {
1301 cananian 1.3.2.1                              assert false;
1302 pnkfelix 1.1.2.29                         }
1303 pnkfelix 1.1.2.29 
1304 pnkfelix 1.1.2.29                         if (w instanceof RegWebRecord) {
1305 pnkfelix 1.1.2.29                             _n.adjR.add(this);
1306 pnkfelix 1.1.2.29                         } else {
1307 pnkfelix 1.1.2.29                             _n.adjT.add(this);
1308 pnkfelix 1.1.2.29                         }
1309 pnkfelix 1.1.2.29                     }
1310 pnkfelix 1.1.2.29                 }
1311 pnkfelix 1.1.2.29                 
1312 pnkfelix 1.1.2.29             }
1313 pnkfelix 1.1.2.16             public String toString() {
1314 pnkfelix 1.1.2.16                 return "n:<"+wr+","+index+","+color+">";
1315 pnkfelix 1.1.2.16             }
1316 pnkfelix 1.1.2.14         }
1317 pnkfelix 1.1.2.14         
1318 pnkfelix 1.1.2.15         /** Helper function for resolving the WebRecord -> Node
1319 pnkfelix 1.1.2.15             relation.
1320 pnkfelix 1.1.2.15         */
1321 pnkfelix 1.1.2.15         private Collection nodes(Object wr) {
1322 pnkfelix 1.1.2.14             return wr2node.getValues(wr); 
1323 pnkfelix 1.1.2.14         }
1324 pnkfelix 1.1.2.14         
1325 pnkfelix 1.1.2.14         Graph() {
1326 pnkfelix 1.1.2.14             this.nodes = new LinkedList();
1327 pnkfelix 1.1.2.6              hidden = new LinkedList();
1328 pnkfelix 1.1.2.14             wr2node = new GenericMultiMap();
1329 pnkfelix 1.1.2.14         }
1330 pnkfelix 1.1.2.15 
1331 pnkfelix 1.1.2.15         /** Adds nodes and edges representing `wr' and its conflicts
1332 pnkfelix 1.1.2.15             to this graph. 
1333 pnkfelix 1.1.2.15         */
1334 pnkfelix 1.1.2.14         void add(WebRecord wr) {
1335 pnkfelix 1.1.2.22             if (isRegister(wr.temp())) {
1336 pnkfelix 1.1.2.15                 Node n = new Node(wr, 0);
1337 pnkfelix 1.1.2.16                 n.color = regToColor(wr.temp());
1338 pnkfelix 1.1.2.27             } else if (webPrecolor.keySet().contains(wr)) {
1339 pnkfelix 1.1.2.29                 // FSK: wrong for Precolored Doubles (fix later)
1340 pnkfelix 1.1.2.27                 Node n = new Node(wr, 0);
1341 pnkfelix 1.1.2.27                 n.color = regToColor((Temp)webPrecolor.get(wr));
1342 pnkfelix 1.1.2.15             } else {
1343 pnkfelix 1.1.2.29                 Map[] i2r2a = (Map[]) implicitAssigns.get(wr.temp());
1344 pnkfelix 1.1.2.29                 Map r2a = i2r2a[0];
1345 cananian 1.3.2.1                  assert r2a != null : "no implicit assigns for "+wr.temp();
1346 pnkfelix 1.1.2.15                 List rl = (List) r2a.values().iterator().next();
1347 pnkfelix 1.1.2.15                 for(int j=0; j<rl.size(); j++) {
1348 pnkfelix 1.1.2.15                     Node n = new Node(wr, j);
1349 pnkfelix 1.1.2.15                 }
1350 pnkfelix 1.1.2.15             }
1351 pnkfelix 1.1.2.15         }
1352 pnkfelix 1.1.2.15 
1353 pnkfelix 1.1.2.15         /** Returns the Assignment that has been given to `wr'. 
1354 pnkfelix 1.1.2.15             requires: this has been colored.
1355 pnkfelix 1.1.2.15         */
1356 pnkfelix 1.1.2.15         List regs(WebRecord wr) {
1357 pnkfelix 1.1.2.17             if (wr instanceof RegWebRecord) {
1358 pnkfelix 1.1.2.17                 return Collections.nCopies(1, wr.temp());
1359 pnkfelix 1.1.2.17             }
1360 pnkfelix 1.1.2.17 
1361 pnkfelix 1.1.2.15             Collection c = wr2node.getValues(wr);
1362 pnkfelix 1.1.2.15             List a = new ArrayList(c);
1363 cananian 1.6                  for(Object nO : c) {
1364 cananian 1.6                      Node n = (Node) nO;
1365 pnkfelix 1.1.2.15                 a.set(n.index, n.color.reg);
1366 pnkfelix 1.1.2.14             }
1367 pnkfelix 1.1.2.15             return a;
1368 pnkfelix 1.1.2.5          }
1369 pnkfelix 1.1.2.15 
1370 pnkfelix 1.1.2.5          public Set nodeSet() { 
1371 pnkfelix 1.1.2.5              return new AbstractSet() {
1372 pnkfelix 1.1.2.14                 public int size() { return nodes.size(); }
1373 pnkfelix 1.1.2.5                  public Iterator iterator() {
1374 pnkfelix 1.1.2.14                     return nodes.iterator();
1375 pnkfelix 1.1.2.5                  }
1376 pnkfelix 1.1.2.5              };
1377 pnkfelix 1.1.2.5          }
1378 pnkfelix 1.1.2.15 
1379 pnkfelix 1.1.2.29         public Collection neighborsOf(final Object n) { 
1380 pnkfelix 1.1.2.29             if (true) {
1381 pnkfelix 1.1.2.29                 // System.out.println("neighborsOf("+n+") : "+((Node)n).adjs);
1382 pnkfelix 1.1.2.29                 return new AbstractCollection() {
1383 pnkfelix 1.1.2.29                     Node nd = (Node) n;
1384 pnkfelix 1.1.2.29                     public int size() { 
1385 pnkfelix 1.1.2.29                         return nd.adjT.size() + nd.adjR.size();
1386 pnkfelix 1.1.2.29                     }
1387 pnkfelix 1.1.2.29                     public Iterator iterator() {
1388 pnkfelix 1.1.2.29                         return new CombineIterator
1389 pnkfelix 1.1.2.29                             (nd.adjT.iterator(), nd.adjR.iterator());
1390 pnkfelix 1.1.2.29                     }
1391 pnkfelix 1.1.2.29                 };
1392 pnkfelix 1.1.2.29 
1393 pnkfelix 1.1.2.29             }
1394 pnkfelix 1.1.2.29 
1395 pnkfelix 1.1.2.29             
1396 pnkfelix 1.1.2.14             if (!(n instanceof Node))
1397 pnkfelix 1.1.2.5                  throw new IllegalArgumentException();
1398 pnkfelix 1.1.2.28             final Node node = (Node) n;
1399 pnkfelix 1.1.2.14             return new AbstractCollection() {
1400 pnkfelix 1.1.2.28                 private Iterator wrs() { 
1401 pnkfelix 1.1.2.28                     Iterator prependIter;
1402 pnkfelix 1.1.2.28                     if (!(node.wr instanceof RegWebRecord)) {
1403 pnkfelix 1.1.2.28                         Iterator regWebIter = regToWeb.values().iterator();
1404 pnkfelix 1.1.2.29                         final Map[] i2r2a =
1405 pnkfelix 1.1.2.29                             (Map[])implicitAssigns.get(node.wr.temp());
1406 pnkfelix 1.1.2.29                         final Map r2a = i2r2a[node.index];
1407 pnkfelix 1.1.2.29                             
1408 pnkfelix 1.1.2.29                         FilterIterator.Filter RWFltr = 
1409 pnkfelix 1.1.2.28                             new FilterIterator.Filter() {
1410 pnkfelix 1.1.2.28                                 public boolean isElement(Object o) {
1411 pnkfelix 1.1.2.28                                     RegWebRecord rwr = (RegWebRecord) o;
1412 pnkfelix 1.1.2.28                                     return 
1413 pnkfelix 1.1.2.28                                     !r2a.containsKey(rwr.temp()) && 
1414 pnkfelix 1.1.2.28                                     !node.wr.adjnds.contains(rwr);
1415 pnkfelix 1.1.2.28                                 }
1416 pnkfelix 1.1.2.28                             };
1417 pnkfelix 1.1.2.29                         prependIter = 
1418 pnkfelix 1.1.2.29                             new FilterIterator(regWebIter,RWFltr);
1419 pnkfelix 1.1.2.28                     } else {
1420 pnkfelix 1.1.2.28                         prependIter = Default.nullIterator;
1421 pnkfelix 1.1.2.28                     }
1422 pnkfelix 1.1.2.28                     return new CombineIterator
1423 pnkfelix 1.1.2.28                         (prependIter, node.wr.adjnds.iterator());
1424 pnkfelix 1.1.2.28                 }
1425 pnkfelix 1.1.2.14                 public int size() {
1426 pnkfelix 1.1.2.14                     int s=0;
1427 pnkfelix 1.1.2.29                     for(Iterator wrs = wrs(); wrs.hasNext(); ) {
1428 pnkfelix 1.1.2.29                         Object wr = wrs.next();
1429 pnkfelix 1.1.2.29                         s += nodes(wr).size(); 
1430 pnkfelix 1.1.2.29                     }
1431 pnkfelix 1.1.2.14                     return s; 
1432 pnkfelix 1.1.2.14                 }
1433 pnkfelix 1.1.2.14 
1434 pnkfelix 1.1.2.14                 FilterIterator.Filter TO_NODE_ITER = 
1435 pnkfelix 1.1.2.14                     new FilterIterator.Filter() {
1436 pnkfelix 1.1.2.14                         public Object map(Object o) { 
1437 pnkfelix 1.1.2.14                             return nodes(o).iterator();
1438 pnkfelix 1.1.2.14                         }
1439 pnkfelix 1.1.2.14                     };
1440 pnkfelix 1.1.2.14                 public Iterator iterator() {
1441 pnkfelix 1.1.2.14                     Iterator iters = 
1442 pnkfelix 1.1.2.14                         new FilterIterator(wrs(), TO_NODE_ITER);
1443 pnkfelix 1.1.2.29                     return new CombineIterator(iters) {
1444 pnkfelix 1.1.2.29                         public boolean hasNext() {
1445 pnkfelix 1.1.2.29                             return super.hasNext();
1446 pnkfelix 1.1.2.29                         }
1447 pnkfelix 1.1.2.29                         public Object next() {
1448 pnkfelix 1.1.2.29                             return super.next();
1449 pnkfelix 1.1.2.29                         }
1450 pnkfelix 1.1.2.29                     };
1451 pnkfelix 1.1.2.14                 }
1452 pnkfelix 1.1.2.14             };
1453 pnkfelix 1.1.2.5          }
1454 pnkfelix 1.1.2.14 
1455 pnkfelix 1.1.2.16         public void hide(Object o) { 
1456 pnkfelix 1.1.2.16             if (! (o instanceof Node)) 
1457 pnkfelix 1.1.2.16                 throw new IllegalArgumentException(o+" not in node-set");
1458 pnkfelix 1.1.2.16             Node n = (Node) o;
1459 pnkfelix 1.1.2.29             
1460 pnkfelix 1.1.2.29             doHide(n.wr);
1461 pnkfelix 1.1.2.29         }
1462 pnkfelix 1.1.2.29         
1463 pnkfelix 1.1.2.29         private void doHide(WebRecord wr) {
1464 pnkfelix 1.1.2.29             if (hidden.contains(wr)) {
1465 pnkfelix 1.1.2.16                 return;
1466 pnkfelix 1.1.2.16             }
1467 pnkfelix 1.1.2.29             nodes.removeAll( nodes(wr) );
1468 pnkfelix 1.1.2.16             Iterator nbors;
1469 pnkfelix 1.1.2.29             for(nbors=wr.adjnds.iterator(); nbors.hasNext();){ 
1470 pnkfelix 1.1.2.16                 WebRecord nbor = (WebRecord) nbors.next();
1471 pnkfelix 1.1.2.29                 nbor.adjnds.remove(wr);
1472 pnkfelix 1.1.2.29             }
1473 pnkfelix 1.1.2.29             hidden.addLast(wr);
1474 pnkfelix 1.1.2.29 
1475 cananian 1.6                  for(Object nO : nodes(wr)) {
1476 cananian 1.6                      Node n = (Node) nO;
1477 cananian 1.6                      for(Object _nO : n.adjT) {
1478 cananian 1.6                          Node _n = (Node) _nO;
1479 cananian 1.3.2.1                      assert _n.wr instanceof TempWebRecord : _n.wr;
1480 pnkfelix 1.1.2.29                     _n.adjT.remove(n);
1481 pnkfelix 1.1.2.29                 }
1482 pnkfelix 1.1.2.6              }
1483 pnkfelix 1.1.2.6          }
1484 pnkfelix 1.1.2.15 
1485 pnkfelix 1.1.2.6          public Object replace() { 
1486 pnkfelix 1.1.2.14             WebRecord wr;
1487 pnkfelix 1.1.2.6              try {
1488 pnkfelix 1.1.2.14                 wr = (WebRecord) hidden.removeLast();
1489 pnkfelix 1.1.2.6              } catch (java.util.NoSuchElementException e) {
1490 pnkfelix 1.1.2.16                 return null;
1491 pnkfelix 1.1.2.6              }
1492 pnkfelix 1.1.2.29             nodes.addAll( nodes(wr) );
1493 cananian 1.6                  for(Object nborO : wr.adjnds){ 
1494 cananian 1.6                      WebRecord nbor = (WebRecord) nborO;
1495 pnkfelix 1.1.2.29                 if (!nbor.adjnds.contains(wr)) {
1496 pnkfelix 1.1.2.29                     nbor.adjnds.add(wr);
1497 pnkfelix 1.1.2.29                 }
1498 pnkfelix 1.1.2.29             }
1499 pnkfelix 1.1.2.16             
1500 cananian 1.6                  for(Object nO : nodes(wr)){
1501 cananian 1.6                      Node n = (Node) nO;
1502 cananian 1.6                      for(Object _nO : n.adjT) {
1503 cananian 1.6                          Node _n = (Node) _nO;
1504 cananian 1.3.2.1                      assert _n.wr instanceof TempWebRecord;
1505 pnkfelix 1.1.2.29                     _n.adjT.add(n);
1506 pnkfelix 1.1.2.29                 }
1507 pnkfelix 1.1.2.29             }
1508 pnkfelix 1.1.2.29 
1509 cananian 1.6                  for(Object nO : nodes(wr)){ 
1510 cananian 1.6                      Node n = (Node) nO;
1511 pnkfelix 1.1.2.16                 if (n.index == 0) return n;
1512 pnkfelix 1.1.2.16             }
1513 pnkfelix 1.1.2.16             
1514 pnkfelix 1.1.2.16             throw new RuntimeException();
1515 pnkfelix 1.1.2.6          }
1516 pnkfelix 1.1.2.6          public void replaceAll() {
1517 pnkfelix 1.1.2.6              while(!hidden.isEmpty()) {
1518 pnkfelix 1.1.2.6                  replace();
1519 pnkfelix 1.1.2.6              }
1520 pnkfelix 1.1.2.6          }
1521 pnkfelix 1.1.2.6          public Color getColor(Object n) { 
1522 pnkfelix 1.1.2.29             Node nd;
1523 pnkfelix 1.1.2.29             try { nd = (Node) n; return nd.color;
1524 pnkfelix 1.1.2.17             } catch (ClassCastException e) {
1525 pnkfelix 1.1.2.17                 throw new IllegalArgumentException();
1526 pnkfelix 1.1.2.6              }
1527 pnkfelix 1.1.2.6          }
1528 pnkfelix 1.1.2.6  
1529 pnkfelix 1.1.2.6          public void resetColors() { 
1530 pnkfelix 1.1.2.6              Iterator ns;
1531 pnkfelix 1.1.2.14             for(ns = nodes.iterator(); ns.hasNext();) {
1532 pnkfelix 1.1.2.15                 ((Node) ns.next()).color = null;
1533 pnkfelix 1.1.2.6              }
1534 pnkfelix 1.1.2.16             for(Iterator wrs = hidden.iterator(); wrs.hasNext();) {
1535 pnkfelix 1.1.2.16                 for(ns=nodes((WebRecord)wrs.next()).iterator();ns.hasNext();){
1536 pnkfelix 1.1.2.16                     ((Node) ns.next()).color = null;
1537 pnkfelix 1.1.2.16                 }
1538 pnkfelix 1.1.2.6              }
1539 pnkfelix 1.1.2.6          }
1540 pnkfelix 1.1.2.6  
1541 pnkfelix 1.1.2.30         public void unsetColor(Object o) {
1542 pnkfelix 1.1.2.30             try {
1543 pnkfelix 1.1.2.30                 Node nd = (Node) o;
1544 cananian 1.6                      for(Object nO : nodes(nd.wr)){
1545 cananian 1.6                          Node n = (Node) nO;
1546 pnkfelix 1.1.2.30                     n.color = null;
1547 pnkfelix 1.1.2.30                 }
1548 pnkfelix 1.1.2.30             } catch (ClassCastException e) {
1549 pnkfelix 1.1.2.30                 throw new IllegalArgumentException();
1550 pnkfelix 1.1.2.30             }
1551 pnkfelix 1.1.2.30         }
1552 pnkfelix 1.1.2.30 
1553 pnkfelix 1.1.2.16         public void setColor(Object o, Color col) 
1554 pnkfelix 1.1.2.16             throws ColorableGraph.IllegalColor { 
1555 cananian 1.3.2.1              assert col != null;
1556 pnkfelix 1.1.2.6              try {
1557 pnkfelix 1.1.2.16                 Node node = (Node) o;
1558 cananian 1.3.2.1                  assert node.index == 0 : "setColor on bad node "+node;
1559 pnkfelix 1.1.2.16                 RegColor rc = (RegColor) col;
1560 pnkfelix 1.1.2.16                 Collection nds = nodes(node.wr);
1561 pnkfelix 1.1.2.29                 Map[] i2r2a = (Map[]) implicitAssigns.get(node.wr.temp());
1562 pnkfelix 1.1.2.29                 Map r2a = i2r2a[node.index];
1563 pnkfelix 1.1.2.16                 if (!r2a.keySet().contains(rc.reg)) 
1564 pnkfelix 1.1.2.16                     throw new ColorableGraph.IllegalColor(o, col);
1565 pnkfelix 1.1.2.16                 List assign = (List) r2a.get(rc.reg);
1566 pnkfelix 1.1.2.17 
1567 pnkfelix 1.1.2.17                 // verify all color choices
1568 cananian 1.6                      for(Object nO : nds) {
1569 cananian 1.6                          Node n = (Node) nO;
1570 pnkfelix 1.1.2.17                     Temp t = (Temp) assign.get(n.index);
1571 pnkfelix 1.1.2.17                     rc = regToColor(t);
1572 pnkfelix 1.1.2.17                     Iterator nbs;
1573 pnkfelix 1.1.2.17                     for(nbs=neighborsOf(n).iterator();nbs.hasNext();){
1574 pnkfelix 1.1.2.17                         Node nb = (Node) nbs.next();
1575 pnkfelix 1.1.2.22                         if (nb.color != null && 
1576 pnkfelix 1.1.2.22                             nb.color.equals(rc)) {
1577 pnkfelix 1.1.2.17                             throw new ColorableGraph.IllegalColor(n,rc);
1578 pnkfelix 1.1.2.17                         }
1579 pnkfelix 1.1.2.17                     }
1580 pnkfelix 1.1.2.17                     if (false) System.out.println
1581 pnkfelix 1.1.2.17                                    (n+" passed verify for "+rc+
1582 pnkfelix 1.1.2.17                                     ", neighbors:"+neighborsOf(n));
1583 pnkfelix 1.1.2.17                 }
1584 pnkfelix 1.1.2.17 
1585 pnkfelix 1.1.2.17                 // got here, colors passed verification
1586 cananian 1.6                      for(Object nO : nds){
1587 cananian 1.6                          Node n = (Node) nO;
1588 pnkfelix 1.1.2.16                     Temp t = (Temp) assign.get(n.index);
1589 pnkfelix 1.1.2.16                     rc = regToColor(t);
1590 pnkfelix 1.1.2.16                     n.color = rc;
1591 pnkfelix 1.1.2.16                     if (false) System.out.println("set color of "+n);
1592 pnkfelix 1.1.2.16                 }
1593 pnkfelix 1.1.2.6              } catch (ClassCastException e) {
1594 pnkfelix 1.1.2.6                  throw new IllegalArgumentException();
1595 pnkfelix 1.1.2.6              }
1596 pnkfelix 1.1.2.6          }
1597 pnkfelix 1.1.2.5      }
1598 pnkfelix 1.1.2.5  
1599 pnkfelix 1.1.2.21     class StatGather {
1600 pnkfelix 1.1.2.21         int sum=0; int sumSq=0; int cnt=0;
1601 pnkfelix 1.1.2.21         void add(int elem) { cnt++; sum+=elem; sumSq+=elem*elem; } 
1602 pnkfelix 1.1.2.21         int size() { return cnt; }
1603 pnkfelix 1.1.2.21         int mean() { return sum / cnt; }
1604 pnkfelix 1.1.2.21         int variance() { int m=mean(); return sumSq/cnt - m*m; } 
1605 pnkfelix 1.1.2.21         public String toString() { 
1606 pnkfelix 1.1.2.21             return "Stat<size:"+size()+" mean:"+mean()+" var:"+variance()+">"; 
1607 pnkfelix 1.1.2.21         }
1608 pnkfelix 1.1.2.21     }
1609 pnkfelix 1.1.2.21 
1610 pnkfelix 1.1.2.41     static void printConflictTime() { 
1611 pnkfelix 1.1.2.41         System.out.println("conflict time -"+
1612 pnkfelix 1.1.2.41                            " tnr: "+rntwrNumChecks+
1613 pnkfelix 1.1.2.41                            " (num:"+rnrwrNumChecks+
1614 pnkfelix 1.1.2.41                            " ave:"+(rntwrNumChecks/rnrwrNumChecks)+")"+
1615 pnkfelix 1.1.2.41                            " twr: "+twrConflictTime+
1616 pnkfelix 1.1.2.41                            " (num:"+twrNumConflicts+
1617 pnkfelix 1.1.2.41                             " ave:"+(twrConflictTime/twrNumConflicts)+")"+
1618 pnkfelix 1.1.2.41                            " rwr: "+rwrConflictTime+
1619 pnkfelix 1.1.2.41                            " (num:"+rwrNumConflicts+
1620 pnkfelix 1.1.2.41                             " ave:"+(rwrConflictTime/rwrNumConflicts)+")");
1621 pnkfelix 1.1.2.41         rwrConflictTime = twrConflictTime = 1;
1622 pnkfelix 1.1.2.41         rwrNumConflicts = twrNumConflicts = 1; 
1623 pnkfelix 1.1.2.41         rnrwrNumChecks = rntwrNumChecks = 1; 
1624 pnkfelix 1.1.2.41     }
1625 pnkfelix 1.1.2.41     static long rwrConflictTime = 0; static int rwrNumConflicts = 0;
1626 pnkfelix 1.1.2.41     static long twrConflictTime = 0; static int twrNumConflicts = 0;
1627 pnkfelix 1.1.2.41     static int rntwrNumChecks = 1, rnrwrNumChecks = 1;
1628 pnkfelix 1.1.2.5      abstract class WebRecord {
1629 pnkfelix 1.1.2.6          int nints, disp;
1630 pnkfelix 1.1.2.6          double spcost;
1631 pnkfelix 1.1.2.6          List adjnds; // List<WebRecord>
1632 pnkfelix 1.1.2.6  
1633 pnkfelix 1.1.2.9          private int sreg; 
1634 pnkfelix 1.1.2.9          private boolean sregYet = false;
1635 pnkfelix 1.1.2.6  
1636 pnkfelix 1.1.2.15         WebRecord() {
1637 pnkfelix 1.1.2.6              nints = 0;
1638 pnkfelix 1.1.2.6              disp = Integer.MIN_VALUE;
1639 pnkfelix 1.1.2.6              spcost = 0.0;
1640 pnkfelix 1.1.2.6              adjnds = new LinkedList();
1641 pnkfelix 1.1.2.6          }
1642 pnkfelix 1.1.2.9          
1643 cananian 1.3.2.1          int sreg() { assert sregYet; return sreg; }
1644 pnkfelix 1.1.2.5          void sreg(int val) {
1645 cananian 1.3.2.1              assert !sregYet;
1646 pnkfelix 1.1.2.5              sreg = val;
1647 pnkfelix 1.1.2.9              sregYet = true;
1648 pnkfelix 1.1.2.28         }
1649 pnkfelix 1.1.2.28         
1650 pnkfelix 1.1.2.28         /** Returns true if this shares a use/def with wr. */
1651 pnkfelix 1.1.2.28         boolean overlaps(WebRecord wr) {
1652 pnkfelix 1.1.2.28             HashSet refs = 
1653 pnkfelix 1.1.2.28                 new HashSet( defs().size() + uses().size() );
1654 pnkfelix 1.1.2.28             refs.addAll(defs());
1655 pnkfelix 1.1.2.28             refs.addAll(uses());
1656 pnkfelix 1.1.2.28             HashSet rfs2 = new HashSet(refs);
1657 pnkfelix 1.1.2.28             if (refs.retainAll(wr.defs()) ||
1658 pnkfelix 1.1.2.28                 rfs2.retainAll(wr.uses())) {
1659 pnkfelix 1.1.2.34                 if (SCARY_OUTPUT) System.out.println(this + " overlaps " + wr);
1660 pnkfelix 1.1.2.28                 return true;
1661 pnkfelix 1.1.2.28             }
1662 pnkfelix 1.1.2.34             if (SCARY_OUTPUT) System.out.println(this + " does NOT overlap " + wr);
1663 pnkfelix 1.1.2.28             return false;
1664 pnkfelix 1.1.2.9          }
1665 pnkfelix 1.1.2.9  
1666 pnkfelix 1.1.2.8          // ( interference based on Muchnick, page 494.)
1667 pnkfelix 1.1.2.5          boolean conflictsWith(WebRecord wr) {
1668 pnkfelix 1.1.2.41             long immed_conflict_time, reg_conflict_time=0, start_time;
1669 pnkfelix 1.1.2.41 
1670 pnkfelix 1.1.2.41             start_time = System.currentTimeMillis();        
1671 pnkfelix 1.1.2.27             boolean r =
1672 pnkfelix 1.1.2.27                 this.conflictsWith1D(wr) ||
1673 pnkfelix 1.1.2.9                  wr.conflictsWith1D(this);
1674 pnkfelix 1.1.2.41             immed_conflict_time = System.currentTimeMillis() - start_time;
1675 pnkfelix 1.1.2.27             if (!r &&
1676 pnkfelix 1.1.2.27                 webPrecolor.containsKey(this)) {
1677 pnkfelix 1.1.2.27                 WebRecord rwr = (WebRecord) 
1678 pnkfelix 1.1.2.27                     regToWeb.get(webPrecolor.get(this));
1679 pnkfelix 1.1.2.41 
1680 pnkfelix 1.1.2.41                 start_time = System.currentTimeMillis();
1681 pnkfelix 1.1.2.27                 r = rwr.conflictsWith(wr);
1682 pnkfelix 1.1.2.41                 reg_conflict_time = System.currentTimeMillis() - start_time;
1683 pnkfelix 1.1.2.27             }
1684 pnkfelix 1.1.2.41             if (false && reg_conflict_time > 10)
1685 pnkfelix 1.1.2.41                 System.out.println("conflict compute time, imm: "+
1686 pnkfelix 1.1.2.41                                    immed_conflict_time+" reg: "+
1687 pnkfelix 1.1.2.41                                reg_conflict_time);
1688 pnkfelix 1.1.2.27             return r;
1689 pnkfelix 1.1.2.9          }
1690 pnkfelix 1.1.2.9  
1691 pnkfelix 1.1.2.9          // one directional conflict check (helper function) 
1692 pnkfelix 1.1.2.9          // if this is live at a def in wr, returns true.
1693 pnkfelix 1.1.2.12         boolean conflictsWith1D(WebRecord wr) {
1694 pnkfelix 1.1.2.41             long start_time = System.currentTimeMillis();
1695 pnkfelix 1.1.2.41             boolean r = false;
1696 cananian 1.6                  for(Object dO : this.defs()){
1697 cananian 1.6                      Instr d = (Instr) dO;
1698 pnkfelix 1.1.2.42                 
1699 pnkfelix 1.1.2.42                 // "a,b := f()" ==> a and b interfere, even though
1700 pnkfelix 1.1.2.42                 // there may not be any defs of either that "reach"
1701 pnkfelix 1.1.2.42                 // this statement (a statement need not reach itself)
1702 pnkfelix 1.1.2.42                 if (wr.defs().contains( d ))
1703 pnkfelix 1.1.2.42                     return true;
1704 pnkfelix 1.1.2.42 
1705 pnkfelix 1.1.2.11                 Set l= liveTemps.getLiveAfter(d);
1706 pnkfelix 1.1.2.33                 if(l.contains(wr.temp())) {
1707 pnkfelix 1.1.2.25                     if (wr instanceof RegWebRecord) {
1708 pnkfelix 1.1.2.41                         r = true;
1709 pnkfelix 1.1.2.41                         break;
1710 pnkfelix 1.1.2.25                     }
1711 pnkfelix 1.1.2.33                     
1712 pnkfelix 1.1.2.19                     HashSet wDefs = new HashSet
1713 pnkfelix 1.1.2.19                         (rdefs.reachingDefs(d, wr.temp()));
1714 pnkfelix 1.1.2.19                     wDefs.retainAll(wr.defs());
1715 pnkfelix 1.1.2.25                     if (!wDefs.isEmpty()) {
1716 pnkfelix 1.1.2.41                         r = true;
1717 pnkfelix 1.1.2.41                         break;
1718 pnkfelix 1.1.2.25                     }
1719 pnkfelix 1.1.2.19                 }
1720 pnkfelix 1.1.2.41             
1721 pnkfelix 1.1.2.5              }
1722 pnkfelix 1.1.2.41             twrConflictTime += System.currentTimeMillis() - start_time;
1723 pnkfelix 1.1.2.41             twrNumConflicts++;
1724 pnkfelix 1.1.2.41             return r;
1725 pnkfelix 1.1.2.5          }
1726 pnkfelix 1.1.2.9  
1727 pnkfelix 1.1.2.5          // returns the set of instrs that this web holds definitions
1728 pnkfelix 1.1.2.5          // for.  These instrs are used to detect conflicts between
1729 pnkfelix 1.1.2.5          // webs. 
1730 pnkfelix 1.1.2.5          abstract Set defs();
1731 pnkfelix 1.1.2.9  
1732 pnkfelix 1.1.2.9          // returns the set of instrs that this web holds uses
1733 pnkfelix 1.1.2.9          // for.  These instrs are used to detect conflicts between
1734 pnkfelix 1.1.2.9          // webs. 
1735 pnkfelix 1.1.2.9          abstract Set uses();
1736 pnkfelix 1.1.2.9  
1737 pnkfelix 1.1.2.13         // returns the Temp that this WebRecord represents.
1738 pnkfelix 1.1.2.13         abstract Temp temp();
1739 pnkfelix 1.1.2.5  
1740 pnkfelix 1.1.2.13         public String toString() { return "w:"+temp(); }
1741 pnkfelix 1.1.2.13     }
1742 pnkfelix 1.1.2.9  
1743 pnkfelix 1.1.2.13     class RegWebRecord extends WebRecord {
1744 pnkfelix 1.1.2.13         final Temp reg;
1745 pnkfelix 1.1.2.13         RegWebRecord(Temp reg) {
1746 pnkfelix 1.1.2.15             super();
1747 pnkfelix 1.1.2.13             this.reg = reg;
1748 pnkfelix 1.1.2.13         }
1749 pnkfelix 1.1.2.33         public int hashCode() { return reg.hashCode(); }
1750 pnkfelix 1.1.2.33         public boolean equals(Object o) { 
1751 pnkfelix 1.1.2.33             if (o == this) 
1752 pnkfelix 1.1.2.33                 return true;
1753 pnkfelix 1.1.2.33             if (o != null && o instanceof RegWebRecord) {
1754 pnkfelix 1.1.2.33                 return reg.equals(((RegWebRecord)o).reg);
1755 pnkfelix 1.1.2.33             } else {
1756 pnkfelix 1.1.2.33                 return false;
1757 pnkfelix 1.1.2.33             }
1758 pnkfelix 1.1.2.33         }
1759 pnkfelix 1.1.2.13         public Set defs() { return (Set) regToDefs.getValues(reg); }
1760 pnkfelix 1.1.2.13         public Set uses() { return (Set) regToUses.getValues(reg); }
1761 pnkfelix 1.1.2.13         public Temp temp() { return reg; }
1762 pnkfelix 1.1.2.9  
1763 pnkfelix 1.1.2.23         boolean conflictsWith1D(WebRecord wr) {
1764 pnkfelix 1.1.2.41             long start_time = System.currentTimeMillis();
1765 pnkfelix 1.1.2.41             boolean r;
1766 pnkfelix 1.1.2.13             if (wr instanceof RegWebRecord) {
1767 pnkfelix 1.1.2.41                 r = true;
1768 pnkfelix 1.1.2.5              } else {
1769 pnkfelix 1.1.2.41                 r = super.conflictsWith1D(wr);
1770 pnkfelix 1.1.2.27                 if (!r &&
1771 pnkfelix 1.1.2.27                     webPrecolor.invert().containsKey(reg)) {
1772 pnkfelix 1.1.2.41                     Collection preWebsForReg = webPrecolor.invert().getValues(reg);
1773 pnkfelix 1.1.2.41                     int nms=0;
1774 pnkfelix 1.1.2.41                     Iterator wbs = preWebsForReg.iterator();
1775 pnkfelix 1.1.2.41                     while(wbs.hasNext()) { nms++;
1776 pnkfelix 1.1.2.27                         WebRecord _wr = (WebRecord) wbs.next();
1777 pnkfelix 1.1.2.27                         if (_wr.conflictsWith1D(wr) ||
1778 pnkfelix 1.1.2.27                             wr.conflictsWith1D(_wr)) {
1779 pnkfelix 1.1.2.41                             r = true;
1780 pnkfelix 1.1.2.41                             break;
1781 pnkfelix 1.1.2.27                         }
1782 pnkfelix 1.1.2.27                     }
1783 pnkfelix 1.1.2.41                     rntwrNumChecks+=nms; rnrwrNumChecks++;
1784 pnkfelix 1.1.2.27                 }
1785 pnkfelix 1.1.2.5              }
1786 pnkfelix 1.1.2.41             rwrConflictTime += System.currentTimeMillis() - start_time;
1787 pnkfelix 1.1.2.41             rwrNumConflicts++;
1788 pnkfelix 1.1.2.41             return r;
1789 pnkfelix 1.1.2.5          }
1790 pnkfelix 1.1.2.5      }
1791 pnkfelix 1.1.2.5  
1792 pnkfelix 1.1.2.9      // converts a Set<Instr>:s1 into a Set<Integer>:s2 where the
1793 pnkfelix 1.1.2.9      // elements in s2 correspond to the IDs of the instructions in s1
1794 pnkfelix 1.1.2.9      private static Integer i2int(Instr i) { return new Integer(i.getID()); }
1795 pnkfelix 1.1.2.9      private static Set readable(final Set instrs) {
1796 pnkfelix 1.1.2.9          final FilterIterator.Filter fltr = new FilterIterator.Filter() {
1797 pnkfelix 1.1.2.9              public Object map(Object o) { return i2int((Instr)o); }
1798 pnkfelix 1.1.2.9          };
1799 pnkfelix 1.1.2.9          return new AbstractSet() {
1800 pnkfelix 1.1.2.9              public int size() { return instrs.size(); }
1801 pnkfelix 1.1.2.9              public Iterator iterator() {
1802 pnkfelix 1.1.2.9                  return new FilterIterator(instrs.iterator(), fltr);
1803 pnkfelix 1.1.2.9              }
1804 pnkfelix 1.1.2.9          };
1805 pnkfelix 1.1.2.9      }
1806 pnkfelix 1.1.2.9  
1807 pnkfelix 1.1.2.5      class TempWebRecord extends WebRecord {
1808 pnkfelix 1.1.2.5          Temp sym;
1809 pnkfelix 1.1.2.5          Set defs, uses; // Set<Instr>
1810 pnkfelix 1.1.2.5          boolean spill;
1811 pnkfelix 1.1.2.5          int disp;
1812 pnkfelix 1.1.2.33 
1813 pnkfelix 1.1.2.33         public int hashCode() { return sym.hashCode(); }
1814 pnkfelix 1.1.2.33         public boolean equals(Object o) {
1815 pnkfelix 1.1.2.33             if (o == this) 
1816 pnkfelix 1.1.2.33                 return true;
1817 pnkfelix 1.1.2.33             if (o != null && o instanceof TempWebRecord) {
1818 pnkfelix 1.1.2.33                 TempWebRecord t = (TempWebRecord) o;
1819 pnkfelix 1.1.2.33                 return sym.equals(t.sym) &&
1820 pnkfelix 1.1.2.33                     defs.equals(t.defs) &&
1821 pnkfelix 1.1.2.33                     uses.equals(t.uses);
1822 pnkfelix 1.1.2.33             } else {
1823 pnkfelix 1.1.2.33                 return false;
1824 pnkfelix 1.1.2.33             }
1825 pnkfelix 1.1.2.33         }
1826 pnkfelix 1.1.2.5          TempWebRecord(Temp symbol, Set defSet, Set useSet) {
1827 pnkfelix 1.1.2.15             super();
1828 pnkfelix 1.1.2.5              sym = symbol; defs = defSet; uses = useSet;
1829 pnkfelix 1.1.2.9              spill = false; disp = -1;
1830 cananian 1.3.2.1              assert !isRegister(sym);
1831 pnkfelix 1.1.2.5          }
1832 pnkfelix 1.1.2.5          
1833 pnkfelix 1.1.2.13         public Temp temp() { return sym; }
1834 pnkfelix 1.1.2.12         public Set defs() { return Collections.unmodifiableSet(defs);}
1835 pnkfelix 1.1.2.12         public Set uses() { return Collections.unmodifiableSet(uses);}
1836 pnkfelix 1.1.2.7  
1837 pnkfelix 1.1.2.5          public String toString() {
1838 pnkfelix 1.1.2.12             List a = (List) rfi.getRegAssignments(sym).iterator().next();
1839 pnkfelix 1.1.2.22             if (true) 
1840 pnkfelix 1.1.2.21                 return "<web sym:"+sym+
1841 pnkfelix 1.1.2.7                      ", defs:"+readable(defs)+
1842 pnkfelix 1.1.2.7                      ", uses:"+readable(uses)+
1843 pnkfelix 1.1.2.12                     ((a.size()==1)?", single-word":", multi-word")+
1844 pnkfelix 1.1.2.7                      " >";
1845 pnkfelix 1.1.2.7              else 
1846 pnkfelix 1.1.2.21                 return "w:"+sym+" degree:"+adjnds.size();
1847 pnkfelix 1.1.2.5          }
1848 pnkfelix 1.1.2.5      }
1849 pnkfelix 1.1.2.5  
1850 pnkfelix 1.1.2.5      class AdjMtx {
1851 pnkfelix 1.1.2.21         // a Lower Triangular Matrix backed by a HashSet of IntPairs
1852 pnkfelix 1.1.2.21         HashSet pairSet;
1853 pnkfelix 1.1.2.21         AdjMtx(List symReg) {
1854 pnkfelix 1.1.2.21             pairSet = new HashSet(symReg.size());
1855 pnkfelix 1.1.2.21         }
1856 pnkfelix 1.1.2.21         public boolean get(int x, int y) {
1857 pnkfelix 1.1.2.21             return pairSet.contains(new IntPair(x, y));
1858 pnkfelix 1.1.2.21         }
1859 pnkfelix 1.1.2.21         public void set(int x, int y, boolean b) {
1860 pnkfelix 1.1.2.21             IntPair p = new IntPair(x, y);
1861 pnkfelix 1.1.2.21             if (b) {
1862 pnkfelix 1.1.2.21                 pairSet.add(p);
1863 pnkfelix 1.1.2.21             } else {
1864 pnkfelix 1.1.2.21                 pairSet.remove(p);
1865 pnkfelix 1.1.2.21             }
1866 pnkfelix 1.1.2.21         }
1867 pnkfelix 1.1.2.21         class IntPair { 
1868 pnkfelix 1.1.2.21             final int m,n;
1869 pnkfelix 1.1.2.21             IntPair(int x, int y) { 
1870 pnkfelix 1.1.2.21                 if (x > y) {
1871 pnkfelix 1.1.2.21                     m=x; n=y;
1872 pnkfelix 1.1.2.21                 } else {
1873 pnkfelix 1.1.2.21                     m=y; n=x;
1874 pnkfelix 1.1.2.21                 }
1875 pnkfelix 1.1.2.21             }
1876 pnkfelix 1.1.2.33             public int hashCode() { return ((m<<16)|(m>>16)) ^ n; }
1877 pnkfelix 1.1.2.21             public boolean equals(Object o) { 
1878 pnkfelix 1.1.2.21                 IntPair p = (IntPair) o;
1879 pnkfelix 1.1.2.21                 return m == p.m && n == p.n;
1880 pnkfelix 1.1.2.21             }
1881 pnkfelix 1.1.2.21         }
1882 pnkfelix 1.1.2.21         
1883 pnkfelix 1.1.2.21     }
1884 pnkfelix 1.1.2.21     
1885 pnkfelix 1.1.2.21     class AdjMtxOld {
1886 pnkfelix 1.1.2.13         // a Lower Triangular Matrix backed by a BitString.  Note that
1887 pnkfelix 1.1.2.13         // for Lower Triangular Matrix, order of coordinate args is
1888 pnkfelix 1.1.2.13         // insignificant (from p.o.v. of user). 
1889 pnkfelix 1.1.2.13 
1890 cananian 1.5              final net.cscott.jutil.BitString bits;
1891 pnkfelix 1.1.2.11         final int side;
1892 pnkfelix 1.1.2.21         AdjMtxOld(List symReg) {
1893 pnkfelix 1.1.2.11             side = symReg.size();
1894 cananian 1.5                  bits = new net.cscott.jutil.BitString(side * side / 2);
1895 pnkfelix 1.1.2.11         }
1896 pnkfelix 1.1.2.11         boolean get(int x, int y) {
1897 cananian 1.3.2.1              assert x != y;
1898 cananian 1.3.2.1              assert x < side; 
1899 cananian 1.3.2.1              assert y < side;
1900 pnkfelix 1.1.2.11             return bits.get(convert(x,y));
1901 pnkfelix 1.1.2.11         }
1902 pnkfelix 1.1.2.11         void set(int x, int y, boolean b) {
1903 cananian 1.3.2.1              assert x != y;
1904 cananian 1.3.2.1              assert x < side; 
1905 cananian 1.3.2.1              assert y < side;
1906 pnkfelix 1.1.2.11             if (b) bits.set(convert(x,y)); 
1907 pnkfelix 1.1.2.11             else   bits.clear(convert(x,y));
1908 cananian 1.3.2.1              assert get(x,y) == b;
1909 pnkfelix 1.1.2.11         }
1910 pnkfelix 1.1.2.11         private int convert(int x, int y) {
1911 pnkfelix 1.1.2.18             if (x > y) return offset(x) + y;
1912 pnkfelix 1.1.2.11             else       return offset(y) + x;
1913 pnkfelix 1.1.2.11         }
1914 pnkfelix 1.1.2.18         private int offset(int x) { return (x * (x - 1)) / 2; }
1915 pnkfelix 1.1.2.32     }
1916 pnkfelix 1.1.2.32 
1917 pnkfelix 1.1.2.32     // only defined for unions of WebRecords
1918 cananian 1.5          class EqWebRecords extends net.cscott.jutil.DisjointSet {
1919 pnkfelix 1.1.2.32         private HashSet temps = new HashSet();
1920 pnkfelix 1.1.2.35         MultiMap wrToEqwrs = new GenericMultiMap();
1921 pnkfelix 1.1.2.35 
1922 pnkfelix 1.1.2.32         public boolean containsTemp(Temp t) {
1923 pnkfelix 1.1.2.32             return temps.contains(t);
1924 pnkfelix 1.1.2.32         }
1925 pnkfelix 1.1.2.32         public Instr rename(final Instr i) {
1926 pnkfelix 1.1.2.32             TempMap tmap = new TempMap() { 
1927 pnkfelix 1.1.2.32                 public Temp tempMap(Temp tmp) {
1928 pnkfelix 1.1.2.32                     WebRecord wr = getWR(i,tmp);
1929 pnkfelix 1.1.2.32                     if (wr == null) return tmp;
1930 pnkfelix 1.1.2.32                     wr = (WebRecord) find(wr);
1931 pnkfelix 1.1.2.32                     return wr.temp();
1932 pnkfelix 1.1.2.32                 }
1933 pnkfelix 1.1.2.32             };
1934 pnkfelix 1.1.2.32             return i.rename(tmap);
1935 pnkfelix 1.1.2.32         }
1936 pnkfelix 1.1.2.32         public void union(Object a, Object b) {
1937 pnkfelix 1.1.2.38             if ( super.find(a).equals(super.find(b))) 
1938 pnkfelix 1.1.2.38                 return;
1939 pnkfelix 1.1.2.35 
1940 pnkfelix 1.1.2.38             WebRecord wrA = (WebRecord) a;
1941 pnkfelix 1.1.2.38             WebRecord wrB = (WebRecord) b;
1942 pnkfelix 1.1.2.41             if (UNIFY_INFO) 
1943 pnkfelix 1.1.2.41                 System.out.println("unioning0 "
1944 pnkfelix 1.1.2.41                  +" ("+System.identityHashCode(super.find(wrA))+")"
1945 pnkfelix 1.1.2.41                  +" ("+System.identityHashCode(super.find(wrB))+")"
1946 pnkfelix 1.1.2.41                                    );
1947 pnkfelix 1.1.2.38             if (UNIFY_INFO)
1948 pnkfelix 1.1.2.41                 System.out.println(" unioning1  " + asTemps(unified(wrA)) 
1949 pnkfelix 1.1.2.41                                    + " and " + asTemps(unified(wrB))
1950 pnkfelix 1.1.2.41                                    );
1951 pnkfelix 1.1.2.35 
1952 pnkfelix 1.1.2.38             Collection as = unified(wrA);
1953 pnkfelix 1.1.2.38             Collection bs = unified(wrB);
1954 pnkfelix 1.1.2.38             
1955 pnkfelix 1.1.2.38             temps.add( wrA.temp() );
1956 pnkfelix 1.1.2.38             temps.add( wrB.temp() );
1957 pnkfelix 1.1.2.38             super.union(super.find(wrA), super.find(wrB));
1958 pnkfelix 1.1.2.35 
1959 pnkfelix 1.1.2.38             // clear old mappings
1960 pnkfelix 1.1.2.38             wrToEqwrs.remove(wrA);
1961 pnkfelix 1.1.2.38             wrToEqwrs.remove(wrB);
1962 pnkfelix 1.1.2.35 
1963 pnkfelix 1.1.2.38             if (UNIFY_INFO)
1964 pnkfelix 1.1.2.38                 System.out.println(" unioning2 " + asTemps(unified(wrA)) 
1965 pnkfelix 1.1.2.38                                    + " and " + asTemps(unified(wrB)));
1966 pnkfelix 1.1.2.38 
1967 pnkfelix 1.1.2.38             wrToEqwrs.addAll(super.find(wrA), as);
1968 pnkfelix 1.1.2.38             wrToEqwrs.addAll(super.find(wrB), bs);
1969 pnkfelix 1.1.2.38 
1970 pnkfelix 1.1.2.38             if (UNIFY_INFO)
1971 pnkfelix 1.1.2.38                 System.out.println(" unioning3 " + asTemps(unified(wrA)) 
1972 pnkfelix 1.1.2.38                                    + " and " + asTemps(unified(wrB)));
1973 pnkfelix 1.1.2.35         }
1974 pnkfelix 1.1.2.35         
1975 pnkfelix 1.1.2.35         boolean anyConflicting(WebRecord wr1, Collection wrs) {
1976 cananian 1.6                  for(Object wr2O : wrs) {
1977 cananian 1.6                      WebRecord wr2 = (WebRecord) wr2O;
1978 pnkfelix 1.1.2.38                 if (real_conflicting(wr1, wr2)) 
1979 pnkfelix 1.1.2.35                     return true;
1980 pnkfelix 1.1.2.35             }
1981 pnkfelix 1.1.2.35             return false;
1982 pnkfelix 1.1.2.35         }
1983 pnkfelix 1.1.2.35 
1984 pnkfelix 1.1.2.35         boolean conflicting(WebRecord wr1, WebRecord wr2) {
1985 pnkfelix 1.1.2.38             boolean rtn = real_conflicting(wr1, wr2);
1986 pnkfelix 1.1.2.38             return rtn;
1987 pnkfelix 1.1.2.38         }
1988 pnkfelix 1.1.2.38         
1989 pnkfelix 1.1.2.38         private Collection unified(WebRecord wr) {
1990 pnkfelix 1.1.2.38             Collection wrs = new ArrayList(wrToEqwrs.getValues(super.find(wr)));
1991 pnkfelix 1.1.2.38             wrs.add(wr);
1992 pnkfelix 1.1.2.38             return wrs;
1993 pnkfelix 1.1.2.38         }
1994 pnkfelix 1.1.2.38 
1995 pnkfelix 1.1.2.38         private Collection asTemps(final Collection wrs) {
1996 pnkfelix 1.1.2.38             return new java.util.AbstractCollection() {
1997 pnkfelix 1.1.2.38                     public int size() { return wrs.size(); }
1998 pnkfelix 1.1.2.38                     public Iterator iterator() { 
1999 pnkfelix 1.1.2.38                         return new FilterIterator
2000 pnkfelix 1.1.2.38                             (wrs.iterator(), 
2001 pnkfelix 1.1.2.38                              new FilterIterator.Filter() {
2002 pnkfelix 1.1.2.38                                      public Object map(Object o) {
2003 pnkfelix 1.1.2.38                                          return ((WebRecord)o).temp();
2004 pnkfelix 1.1.2.38                                      }
2005 pnkfelix 1.1.2.38                                  });
2006 pnkfelix 1.1.2.38                     }
2007 pnkfelix 1.1.2.38                 };
2008 pnkfelix 1.1.2.38         }
2009 pnkfelix 1.1.2.38         private boolean real_conflicting(WebRecord wr1, WebRecord wr2) {
2010 pnkfelix 1.1.2.38             Collection wrs1 = unified(wr1);
2011 pnkfelix 1.1.2.38             Collection wrs2 = unified(wr2);
2012 cananian 1.6                  for(Object wrAO : wrs1) {
2013 cananian 1.6                      WebRecord wrA = (WebRecord) wrAO;
2014 cananian 1.6                      for(Object wrBO : wrs2) {
2015 cananian 1.6                          WebRecord wrB = (WebRecord) wrBO;
2016 pnkfelix 1.1.2.35                     if (wrA.conflictsWith(wrB))
2017 pnkfelix 1.1.2.35                         return true;
2018 pnkfelix 1.1.2.35                 }
2019 pnkfelix 1.1.2.35             }
2020 pnkfelix 1.1.2.35             return false;
2021 pnkfelix 1.1.2.32         }
2022 pnkfelix 1.1.2.11     }
2023 pnkfelix 1.1.2.11 
2024 cananian 1.2      }