1 pnkfelix 1.1.2.1 // RegAlloc.java, created Mon Mar 29 16:47:25 1999 by pnkfelix 2 cananian 1.1.2.126 // Copyright (C) 1999 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 cananian 1.7 import harpoon.Temp.Label; 7 pnkfelix 1.1.2.1 import harpoon.Temp.Temp; 8 pnkfelix 1.1.2.101 import harpoon.Temp.TempMap; 9 pnkfelix 1.1.2.1 import harpoon.IR.Assem.Instr; 10 pnkfelix 1.1.2.31 import harpoon.IR.Assem.InstrEdge; 11 pnkfelix 1.1.2.14 import harpoon.IR.Assem.InstrFactory; 12 pnkfelix 1.1.2.125 import harpoon.IR.Assem.InstrGroup; 13 pnkfelix 1.1.2.6 import harpoon.IR.Assem.InstrMEM; 14 pnkfelix 1.1.2.6 import harpoon.IR.Assem.InstrVisitor; 15 pnkfelix 1.1.2.125 import harpoon.IR.Properties.UseDefer; 16 cananian 1.1.2.124 import harpoon.IR.Properties.UseDefable; 17 pnkfelix 1.1.2.60 import harpoon.IR.Properties.CFGrapher; 18 pnkfelix 1.1.2.1 import harpoon.Backend.Generic.Frame; 19 pnkfelix 1.1.2.1 import harpoon.Backend.Generic.Code; 20 pnkfelix 1.1.2.36 import harpoon.Backend.Generic.RegFileInfo; 21 pnkfelix 1.1.2.36 import harpoon.Backend.Generic.RegFileInfo.SpillException; 22 pnkfelix 1.1.2.83 import harpoon.Backend.Generic.RegFileInfo.TempLocator; 23 pnkfelix 1.1.2.83 import harpoon.Backend.Generic.RegFileInfo.MachineRegLoc; 24 pnkfelix 1.1.2.83 import harpoon.Backend.Generic.RegFileInfo.StackOffsetLoc; 25 pnkfelix 1.1.2.36 import harpoon.Backend.Generic.InstrBuilder; 26 pnkfelix 1.1.2.39 import harpoon.Analysis.BasicBlock; 27 salcianu 1.4 import harpoon.Analysis.BasicBlockInterf; 28 cananian 1.1.2.73 import harpoon.Analysis.Maps.Derivation; 29 pnkfelix 1.1.2.99 import harpoon.Backend.Maps.BackendDerivation; 30 pnkfelix 1.1.2.3 import harpoon.ClassFile.HCodeFactory; 31 pnkfelix 1.1.2.3 import harpoon.ClassFile.HCode; 32 pnkfelix 1.1.2.99 import harpoon.ClassFile.HClass; 33 pnkfelix 1.1.2.3 import harpoon.ClassFile.HCodeElement; 34 pnkfelix 1.1.2.3 import harpoon.ClassFile.HMethod; 35 pnkfelix 1.1.2.7 import harpoon.Util.Util; 36 cananian 1.8 import net.cscott.jutil.Default; 37 cananian 1.8 import net.cscott.jutil.MultiMap; 38 cananian 1.8 import net.cscott.jutil.MultiMapFactory; 39 cananian 1.8 import net.cscott.jutil.GenericMultiMap; 40 cananian 1.8 import net.cscott.jutil.UnmodifiableIterator; 41 cananian 1.8 import net.cscott.jutil.CombineIterator; 42 pnkfelix 1.1.2.44 43 pnkfelix 1.1.2.42 import harpoon.Analysis.DataFlow.ReachingDefs; 44 pnkfelix 1.1.2.42 import harpoon.Analysis.DataFlow.ForwardDataFlowBasicBlockVisitor; 45 pnkfelix 1.1.2.42 import harpoon.Analysis.DataFlow.InstrSolver; 46 pnkfelix 1.1.2.19 47 pnkfelix 1.1.2.1 import java.util.Hashtable; 48 pnkfelix 1.1.2.19 import java.util.Arrays; 49 pnkfelix 1.1.2.49 import java.util.Collection; 50 pnkfelix 1.1.2.56 import java.util.Collections; 51 pnkfelix 1.1.2.1 import java.util.Set; 52 pnkfelix 1.1.2.1 import java.util.Vector; 53 pnkfelix 1.1.2.7 import java.util.List; 54 pnkfelix 1.1.2.90 import java.util.ArrayList; 55 pnkfelix 1.1.2.1 import java.util.ListIterator; 56 pnkfelix 1.1.2.6 import java.util.Iterator; 57 pnkfelix 1.1.2.1 import java.util.HashSet; 58 pnkfelix 1.1.2.1 import java.util.Map; 59 pnkfelix 1.1.2.1 import java.util.HashMap; 60 pnkfelix 1.1.2.1 61 pnkfelix 1.1.2.3 62 pnkfelix 1.1.2.1 /** 63 pnkfelix 1.1.2.3 * <code>RegAlloc</code> performs Register Allocation for a set of 64 pnkfelix 1.1.2.12 * <code>Instr</code>s in a <code>Backend.Generic.Code</code>. After 65 pnkfelix 1.1.2.12 * register allocation is completed for a set of <code>Instr</code>s, 66 pnkfelix 1.1.2.65 * references to non-register <code>Temp</code>s in the 67 pnkfelix 1.1.2.65 * <code>Instr</code>s will have been replaced by references to 68 pnkfelix 1.1.2.65 * machine registers. Since the number of simultaneously live 69 pnkfelix 1.1.2.65 * temporaries will exceed the space in the register file, spill code 70 pnkfelix 1.1.2.65 * will also be inserted to maintain the state of the register file at 71 pnkfelix 1.1.2.65 * each instruction, storing values to the stack and reloading them as 72 pnkfelix 1.1.2.65 * needed. 73 pnkfelix 1.1.2.1 * 74 pnkfelix 1.1.2.94 * <BR> <B>DESIGN NOTE:</B> The <code>abstractSpillFactory</code> 75 pnkfelix 1.1.2.68 * method relies on the subclasses of <code>RegAlloc</code> to perform 76 pnkfelix 1.1.2.68 * actual allocation. This causes a cycle in our module dependency 77 pnkfelix 1.1.2.68 * graph, which, while not strictly illegal, tends to be a sign of a 78 pnkfelix 1.1.2.68 * design flaw. Consider moving the code factory generator out of the 79 pnkfelix 1.1.2.68 * <code>RegAlloc</code> class into a seperate class to get rid of the 80 pnkfelix 1.1.2.68 * cycle. In the meantime, any new <code>RegAlloc</code> subclasses 81 pnkfelix 1.1.2.68 * can be incorporated into this method to be used in the compiler. 82 pnkfelix 1.1.2.68 * Perhaps should also design a way to parameterize which 83 pnkfelix 1.1.2.68 * <code>RegAlloc</code> subclasses will be used. 84 pnkfelix 1.1.2.64 * 85 cananian 1.1.2.126 * @author Felix S. Klock II <pnkfelix@mit.edu> 86 cananian 1.9 * @version $Id: RegAlloc.java,v 1.9 2004/02/08 03:19:37 cananian Exp $ 87 pnkfelix 1.1.2.65 */ 88 pnkfelix 1.1.2.3 public abstract class RegAlloc { 89 pnkfelix 1.1.2.109 90 pnkfelix 1.1.2.109 public static abstract class Factory { 91 pnkfelix 1.1.2.109 public abstract RegAlloc makeRegAlloc(Code c); 92 pnkfelix 1.1.2.109 } 93 pnkfelix 1.1.2.1 94 pnkfelix 1.1.2.106 /** Flags whether debugging information should be printed to 95 pnkfelix 1.1.2.106 System.out. */ 96 pnkfelix 1.1.2.66 public static final boolean DEBUG = false; 97 pnkfelix 1.1.2.68 98 pnkfelix 1.1.2.106 /** Flags whether timing information should be printed to 99 pnkfelix 1.1.2.106 System.out. */ 100 pnkfelix 1.1.2.107 public static final boolean TIME = false; 101 pnkfelix 1.1.2.106 102 pnkfelix 1.1.2.106 /** <code>Generic.Frame</code> for <code>this</code>. */ 103 pnkfelix 1.1.2.3 protected Frame frame; 104 pnkfelix 1.1.2.106 105 pnkfelix 1.1.2.106 /** <code>Generic.Code</code> for <code>this</code>. */ 106 pnkfelix 1.1.2.3 protected Code code; 107 pnkfelix 1.1.2.106 108 pnkfelix 1.1.2.106 /** <code>BasicBlock.Factory</code> for BasicBlocks of 109 pnkfelix 1.1.2.106 <code>this.code</code>. */ 110 pnkfelix 1.1.2.75 protected BasicBlock.Factory bbFact; 111 pnkfelix 1.1.2.1 112 pnkfelix 1.1.2.106 /** Tracks <code>Instr</code>s that have been verified for 113 pnkfelix 1.1.2.106 debugging purposes. */ 114 pnkfelix 1.1.2.90 protected HashSet checked = new HashSet(); 115 pnkfelix 1.1.2.82 116 pnkfelix 1.1.2.125 /** (Helper method) Returns a <code>CFGrapher</code> that treats 117 pnkfelix 1.1.2.125 <code>InstrGroup</code>s of <code>Type</code> <code>t</code> 118 pnkfelix 1.1.2.125 as single atomic elements. */ 119 pnkfelix 1.1.2.125 protected CFGrapher getGrapherFor(InstrGroup.Type t) { 120 pnkfelix 1.1.2.125 return code.getInstrFactory().getGrapherFor(t); 121 pnkfelix 1.1.2.125 } 122 pnkfelix 1.1.2.125 123 pnkfelix 1.1.2.125 /** (Helper method) Returns a <code>UseDefer</code> that treats 124 pnkfelix 1.1.2.125 <code>InstrGroup</code>s of <code>Type</code> <code>t</code> 125 pnkfelix 1.1.2.125 as single atomic elements. */ 126 pnkfelix 1.1.2.125 protected UseDefer getUseDeferFor(InstrGroup.Type t) { 127 pnkfelix 1.1.2.125 return code.getInstrFactory().getUseDeferFor(t); 128 pnkfelix 1.1.2.125 } 129 pnkfelix 1.1.2.125 130 pnkfelix 1.1.2.125 /** (Helper method) Returns the RegFileInfo for the frame of the code being analyzed. 131 pnkfelix 1.1.2.125 */ 132 pnkfelix 1.1.2.125 protected final RegFileInfo rfi() { 133 pnkfelix 1.1.2.125 return frame.getRegFileInfo(); 134 pnkfelix 1.1.2.125 } 135 pnkfelix 1.1.2.114 136 pnkfelix 1.1.2.102 /** Map[ Instr:i -> Instr:b ], where `i' was added to `code' 137 pnkfelix 1.1.2.102 because of `b'. The `b' is used when queries are performed on 138 pnkfelix 1.1.2.102 `i', so it is important that all of the <code>Temp</code>s 139 pnkfelix 1.1.2.102 referenced by `i' are also referenced by `b' (so that 140 pnkfelix 1.1.2.102 Derivation lookups will succeed). 141 pnkfelix 1.1.2.99 */ 142 pnkfelix 1.1.2.114 private Map backedInstrs = new HashMap(); 143 pnkfelix 1.1.2.114 144 pnkfelix 1.1.2.114 /** adds a mapping <code>instr</code> to <code>back</code> in 145 pnkfelix 1.1.2.114 to the BackedInstrs. 146 pnkfelix 1.1.2.114 */ 147 pnkfelix 1.1.2.114 protected void back(Instr instr, Instr back) { 148 pnkfelix 1.1.2.114 if (backedInstrs.keySet().contains(back)) { 149 pnkfelix 1.1.2.114 backedInstrs.put(instr, backedInstrs.get(back)); 150 pnkfelix 1.1.2.114 } else { 151 pnkfelix 1.1.2.114 backedInstrs.put(instr, back); 152 pnkfelix 1.1.2.114 } 153 pnkfelix 1.1.2.114 } 154 pnkfelix 1.1.2.114 155 pnkfelix 1.1.2.125 /** replaces 'orig' with 'repl', and modifies internal data 156 pnkfelix 1.1.2.125 structures to reflect that replacement as necessary. 157 pnkfelix 1.1.2.125 */ 158 pnkfelix 1.1.2.125 protected void replace(Instr orig, Instr repl) { 159 pnkfelix 1.1.2.125 Instr.replace(orig, repl); 160 pnkfelix 1.1.2.125 back(repl, orig); 161 pnkfelix 1.1.2.125 } 162 pnkfelix 1.1.2.125 163 pnkfelix 1.1.2.114 /** returns the root backing <code>i</code>. Instrs not 164 pnkfelix 1.1.2.114 present in BackedInstrs are their own root. 165 pnkfelix 1.1.2.114 */ 166 pnkfelix 1.1.2.114 protected Instr getBack(Instr i) { 167 pnkfelix 1.1.2.114 if (!backedInstrs.keySet().contains(i)) 168 pnkfelix 1.1.2.114 return i; 169 pnkfelix 1.1.2.114 170 pnkfelix 1.1.2.114 Instr b = (Instr) backedInstrs.get(i); 171 pnkfelix 1.1.2.114 while(backedInstrs.keySet().contains(b)) { 172 pnkfelix 1.1.2.114 b = (Instr) backedInstrs.get(b); 173 pnkfelix 1.1.2.114 } 174 pnkfelix 1.1.2.114 return b; 175 pnkfelix 1.1.2.114 } 176 pnkfelix 1.1.2.99 177 pnkfelix 1.1.2.23 /** Class for <code>RegAlloc</code> usage in loading registers. 178 pnkfelix 1.1.2.23 179 pnkfelix 1.1.2.23 Note that the constructors automagically put in the 180 pnkfelix 1.1.2.23 "appropriate" `d# and `s# operands. 181 pnkfelix 1.1.2.62 182 pnkfelix 1.1.2.23 183 pnkfelix 1.1.2.64 REP INVARIANT: SpillLoads have only one src Temp. 184 pnkfelix 1.1.2.66 */ 185 pnkfelix 1.1.2.87 public static class SpillLoad extends InstrMEM { 186 pnkfelix 1.1.2.87 static SpillLoad makeLD(Instr i, String prefix, 187 pnkfelix 1.1.2.87 Temp dst, Temp src) { 188 pnkfelix 1.1.2.91 return new SpillLoad(i,prefix+" "+dst+" "+src,dst,src); 189 pnkfelix 1.1.2.87 } 190 pnkfelix 1.1.2.87 191 pnkfelix 1.1.2.87 static SpillLoad makeLD(Instr i, String prefix, 192 pnkfelix 1.1.2.87 Collection dsts, Temp src) { 193 pnkfelix 1.1.2.91 return new SpillLoad(i,prefix+" "+dsts+" "+src, dsts, src); 194 pnkfelix 1.1.2.87 } 195 pnkfelix 1.1.2.87 196 pnkfelix 1.1.2.94 private StackOffsetTemp stackOffset; 197 pnkfelix 1.1.2.94 198 pnkfelix 1.1.2.87 SpillLoad(InstrFactory inf, Instr i, String assem, 199 pnkfelix 1.1.2.87 Temp dst, Temp src) { 200 pnkfelix 1.1.2.87 super(inf, i, assem, 201 pnkfelix 1.1.2.16 new Temp[]{dst}, new Temp[]{src}); 202 pnkfelix 1.1.2.16 } 203 pnkfelix 1.1.2.64 SpillLoad(Instr i, String assem, Temp dst, Temp src) { 204 pnkfelix 1.1.2.49 this(i.getFactory(), i, assem, dst, src); 205 pnkfelix 1.1.2.23 } 206 pnkfelix 1.1.2.40 207 pnkfelix 1.1.2.49 // Note that the order that 'dsts' will appear in is the order 208 pnkfelix 1.1.2.49 // that its iterator returns the Temps in. 209 pnkfelix 1.1.2.64 SpillLoad(InstrFactory inf, Instr i, String assem, Collection dsts, Temp src) { 210 pnkfelix 1.1.2.87 super(inf, i, assem, 211 pnkfelix 1.1.2.87 (Temp[])dsts.toArray(new Temp[dsts.size()]), 212 pnkfelix 1.1.2.23 new Temp[]{src}); 213 pnkfelix 1.1.2.14 } 214 pnkfelix 1.1.2.64 SpillLoad(Instr i, String assem, Collection dsts, Temp src) { 215 pnkfelix 1.1.2.49 this(i.getFactory(), i, assem, dsts, src); 216 pnkfelix 1.1.2.49 } 217 pnkfelix 1.1.2.23 218 pnkfelix 1.1.2.14 } 219 pnkfelix 1.1.2.14 220 pnkfelix 1.1.2.23 /** Class for <code>RegAlloc</code> usage in spilling registers. 221 pnkfelix 1.1.2.23 222 pnkfelix 1.1.2.23 Note that the constructors automagically put in the 223 pnkfelix 1.1.2.23 "appropriate" `d# and `s# operands. 224 pnkfelix 1.1.2.23 225 pnkfelix 1.1.2.64 REP INVARIANT: SpillStores have only one dst Temp. 226 pnkfelix 1.1.2.62 227 pnkfelix 1.1.2.23 */ 228 pnkfelix 1.1.2.87 public static class SpillStore extends InstrMEM { 229 pnkfelix 1.1.2.87 static SpillStore makeST(Instr i, String prefix, 230 pnkfelix 1.1.2.87 Temp dst, Temp src) { 231 pnkfelix 1.1.2.94 SpillStore ss = new SpillStore(i,prefix+" "+dst+" "+src,dst,src); 232 pnkfelix 1.1.2.94 return ss; 233 pnkfelix 1.1.2.87 } 234 pnkfelix 1.1.2.87 235 pnkfelix 1.1.2.87 static SpillStore makeST(Instr i, String prefix, 236 pnkfelix 1.1.2.87 Temp dst, Collection srcs) { 237 pnkfelix 1.1.2.94 SpillStore ss = new SpillStore(i,prefix+" "+dst+" "+srcs,dst,srcs); 238 pnkfelix 1.1.2.94 return ss; 239 pnkfelix 1.1.2.87 } 240 pnkfelix 1.1.2.87 241 pnkfelix 1.1.2.94 private StackOffsetTemp stackOffset; 242 pnkfelix 1.1.2.94 243 pnkfelix 1.1.2.94 private SpillStore(Instr i, String assem, Temp dst, Temp src) { 244 pnkfelix 1.1.2.49 this(i.getFactory(), i, assem, dst, src); 245 pnkfelix 1.1.2.49 } 246 pnkfelix 1.1.2.49 247 pnkfelix 1.1.2.94 private SpillStore(InstrFactory inf, HCodeElement hce, 248 pnkfelix 1.1.2.14 String assem, Temp dst, Temp src) { 249 pnkfelix 1.1.2.94 this(inf, hce, assem, dst, Collections.singleton(src)); 250 pnkfelix 1.1.2.16 } 251 pnkfelix 1.1.2.40 252 pnkfelix 1.1.2.49 // Note that the order that 'dsts' will appear in is the order 253 pnkfelix 1.1.2.49 // that its iterator returns the Temps in. 254 pnkfelix 1.1.2.94 private SpillStore(InstrFactory inf, HCodeElement hce, 255 pnkfelix 1.1.2.49 String assem, Temp dst, Collection srcs) { 256 pnkfelix 1.1.2.87 super(inf, hce, assem,new Temp[]{dst}, 257 pnkfelix 1.1.2.23 (Temp[])srcs.toArray(new Temp[srcs.size()])); 258 pnkfelix 1.1.2.14 } 259 pnkfelix 1.1.2.49 260 pnkfelix 1.1.2.94 private SpillStore(Instr i, String assem, Temp dst, Collection srcs) { 261 pnkfelix 1.1.2.49 this(i.getFactory(), i, assem, dst, srcs); 262 pnkfelix 1.1.2.49 } 263 pnkfelix 1.1.2.92 264 pnkfelix 1.1.2.94 265 cananian 1.3.2.3 public Collection<Temp> defC() { 266 cananian 1.3.2.3 Collection<Temp> defs = super.defC(); 267 pnkfelix 1.1.2.94 return defs; 268 pnkfelix 1.1.2.94 } 269 pnkfelix 1.1.2.94 270 pnkfelix 1.1.2.14 } 271 pnkfelix 1.1.2.125 272 pnkfelix 1.1.2.125 protected class SpillProxy extends Instr { 273 pnkfelix 1.1.2.125 Instr instr; 274 pnkfelix 1.1.2.125 Temp tmp; 275 pnkfelix 1.1.2.125 SpillProxy(Instr def, Temp t) { 276 pnkfelix 1.1.2.125 super(def.getFactory(), def, "SPILL "+t, 277 pnkfelix 1.1.2.125 new Temp[]{ }, new Temp[]{ t }, 278 cananian 1.7 true, (List<Label>) Collections.EMPTY_LIST); 279 pnkfelix 1.1.2.125 instr = def; 280 pnkfelix 1.1.2.125 tmp = t; 281 pnkfelix 1.1.2.125 } 282 pnkfelix 1.1.2.125 public Instr rename(InstrFactory inf, 283 pnkfelix 1.1.2.125 TempMap defMap, TempMap useMap) { 284 pnkfelix 1.1.2.125 Instr i = new SpillProxy(instr, 285 pnkfelix 1.1.2.125 // instr.rename(inf, defMap, useMap), 286 pnkfelix 1.1.2.125 useMap.tempMap(tmp)); 287 pnkfelix 1.1.2.125 return i; 288 pnkfelix 1.1.2.125 } 289 pnkfelix 1.1.2.125 290 pnkfelix 1.1.2.125 } 291 pnkfelix 1.1.2.125 292 pnkfelix 1.1.2.125 protected class RestoreProxy extends Instr { 293 pnkfelix 1.1.2.125 Instr instr; 294 pnkfelix 1.1.2.125 Temp tmp; 295 pnkfelix 1.1.2.125 RestoreProxy(Instr use, Temp t) { 296 pnkfelix 1.1.2.125 super(use.getFactory(), use, "RESTORE "+t, 297 pnkfelix 1.1.2.125 new Temp[]{ t }, new Temp[]{}, 298 cananian 1.7 true, (List<Label>) Collections.EMPTY_LIST); 299 pnkfelix 1.1.2.125 instr = use; 300 pnkfelix 1.1.2.125 tmp = t; 301 pnkfelix 1.1.2.125 } 302 pnkfelix 1.1.2.125 public Instr rename(InstrFactory inf, 303 pnkfelix 1.1.2.125 TempMap defMap, TempMap useMap){ 304 pnkfelix 1.1.2.125 Instr i = new RestoreProxy(instr, 305 pnkfelix 1.1.2.125 //instr.rename(inf,defMap,useMap), 306 pnkfelix 1.1.2.125 defMap.tempMap(tmp)); 307 pnkfelix 1.1.2.125 return i; 308 pnkfelix 1.1.2.125 } 309 pnkfelix 1.1.2.125 } 310 pnkfelix 1.1.2.125 311 pnkfelix 1.1.2.125 312 pnkfelix 1.1.2.125 /** Replaces the proxy instructions with symbolic loads and 313 pnkfelix 1.1.2.125 stores. (The proxys don't have register assignment info 314 pnkfelix 1.1.2.125 internally, the new instructions do.) 315 pnkfelix 1.1.2.125 */ 316 pnkfelix 1.1.2.125 protected void fixupSpillCode() { 317 pnkfelix 1.1.2.125 for(Iterator is=code.getElementsI(); is.hasNext(); ) { 318 pnkfelix 1.1.2.125 Instr i = (Instr) is.next(); 319 pnkfelix 1.1.2.125 if (i instanceof SpillProxy) { 320 pnkfelix 1.1.2.125 SpillProxy sp = (SpillProxy) i; 321 pnkfelix 1.1.2.125 Instr spillInstr = 322 pnkfelix 1.1.2.125 SpillStore.makeST(sp.instr, "FSK-ST", sp.tmp, 323 pnkfelix 1.1.2.125 code.getRegisters(sp,sp.tmp)); 324 pnkfelix 1.1.2.125 replace(sp, spillInstr); 325 pnkfelix 1.1.2.125 back(spillInstr, sp.instr); 326 pnkfelix 1.1.2.125 } else if (i instanceof RestoreProxy) { 327 pnkfelix 1.1.2.125 RestoreProxy rp = (RestoreProxy) i; 328 pnkfelix 1.1.2.125 Instr loadInstr = 329 pnkfelix 1.1.2.125 SpillLoad.makeLD(rp.instr, "FSK-LD", 330 pnkfelix 1.1.2.125 code.getRegisters(rp,rp.tmp), 331 pnkfelix 1.1.2.125 rp.tmp); 332 pnkfelix 1.1.2.125 replace(rp, loadInstr); 333 pnkfelix 1.1.2.125 } 334 pnkfelix 1.1.2.125 } 335 pnkfelix 1.1.2.125 } 336 pnkfelix 1.1.2.125 337 pnkfelix 1.1.2.125 338 pnkfelix 1.1.2.125 339 pnkfelix 1.1.2.14 340 pnkfelix 1.1.2.75 /** Creates a <code>RegAlloc</code>. <code>RegAlloc</code>s are 341 pnkfelix 1.1.2.75 each associated with a unique <code>Code</code> which they are 342 pnkfelix 1.1.2.75 responsible for performing register allocation and assignment 343 pnkfelix 1.1.2.75 for. 344 pnkfelix 1.1.2.125 <BR> <B>modifies:</B> `this.{frame, code, bbFact}' 345 pnkfelix 1.1.2.125 <BR> <B>effects:</B> 346 pnkfelix 1.1.2.125 sets the frame, code in accordance with the code argument, 347 pnkfelix 1.1.2.125 and computesBasicBlocks. 348 pnkfelix 1.1.2.1 */ 349 pnkfelix 1.1.2.12 protected RegAlloc(Code code) { 350 pnkfelix 1.1.2.12 this.frame = code.getFrame(); 351 pnkfelix 1.1.2.1 this.code = code; 352 pnkfelix 1.1.2.125 this.bbFact = computeBasicBlocks(); 353 pnkfelix 1.1.2.1 } 354 pnkfelix 1.1.2.49 355 pnkfelix 1.1.2.102 /** returns a <code>Derivation</code> for analyses to use on the 356 pnkfelix 1.1.2.102 register-allocated code. This allows for register allocation 357 pnkfelix 1.1.2.102 routines to make transformations on the code and still allow 358 pnkfelix 1.1.2.102 Derivation information to propagate to later analyses. 359 pnkfelix 1.1.2.101 <BR> <B>requires:</B> 360 pnkfelix 1.1.2.101 <code>this.generateRegAssignment()</code> has been 361 pnkfelix 1.1.2.101 called. 362 pnkfelix 1.1.2.101 */ 363 pnkfelix 1.1.2.102 protected abstract Derivation getDerivation(); 364 pnkfelix 1.1.2.101 365 pnkfelix 1.1.2.106 /** Computes <code>BasicBlock</code>s for the <code>Code</code> 366 pnkfelix 1.1.2.106 associated with <code>this</code>. 367 pnkfelix 1.1.2.125 <BR> <B>requires:</B> `this.code' has been set 368 pnkfelix 1.1.2.125 @return a basic-block factory for `this.code', 369 pnkfelix 1.1.2.125 using the default control-flow view of the code. 370 pnkfelix 1.1.2.106 */ 371 pnkfelix 1.1.2.125 protected BasicBlock.Factory computeBasicBlocks() { 372 pnkfelix 1.1.2.125 return new BasicBlock.Factory 373 pnkfelix 1.1.2.125 (code, code.getInstrFactory().getGrapherFor(InstrGroup.AGGREGATE)); 374 pnkfelix 1.1.2.85 } 375 pnkfelix 1.1.2.127 376 pnkfelix 1.1.2.127 /** Iterates over a view of the code which skips over instrs that 377 pnkfelix 1.1.2.127 are not in our basic block set. This is a useful notion 378 pnkfelix 1.1.2.127 because many of the datastructures used for register 379 pnkfelix 1.1.2.127 allocation barf if given an instruction that wasn't in a basic 380 pnkfelix 1.1.2.127 block (such as a element in a data-table). Note that this 381 pnkfelix 1.1.2.127 method uses the basic-block structure as the basis for its 382 pnkfelix 1.1.2.127 data, so if computeBasicBlocks() is overriden, the behavior of 383 pnkfelix 1.1.2.127 the iteration may change. 384 pnkfelix 1.1.2.127 385 pnkfelix 1.1.2.127 <p> Note also that if the compiler emits dead code, the instrs 386 pnkfelix 1.1.2.127 in such code will not ever be yielded from this, but MAY 387 pnkfelix 1.1.2.127 indeed be yielded from code.getElementsI(). Since FLEX seems 388 pnkfelix 1.1.2.127 to be emitting unreachable code in certain cases, an allocator 389 pnkfelix 1.1.2.127 may want still provide some bogus assignment so that we don't 390 pnkfelix 1.1.2.127 die in an assertion failure in this module. Or perhaps one 391 pnkfelix 1.1.2.127 would prefer to fix the earlier part that is generating 392 pnkfelix 1.1.2.127 unreachable code. C:P 393 pnkfelix 1.1.2.127 394 pnkfelix 1.1.2.127 */ 395 pnkfelix 1.1.2.127 protected Iterator reachableInstrs() { 396 pnkfelix 1.1.2.127 final Iterator blocks = bbFact.blockSet().iterator(); 397 pnkfelix 1.1.2.127 return new CombineIterator(new UnmodifiableIterator() { 398 pnkfelix 1.1.2.127 public Object next() { 399 pnkfelix 1.1.2.127 return ((BasicBlock)blocks.next()).statements().iterator();} 400 pnkfelix 1.1.2.127 public boolean hasNext() { 401 pnkfelix 1.1.2.127 return blocks.hasNext();} 402 pnkfelix 1.1.2.127 }); 403 pnkfelix 1.1.2.127 } 404 pnkfelix 1.1.2.127 405 pnkfelix 1.1.2.1 406 pnkfelix 1.1.2.3 /** Assigns registers in the code for <code>this</code>. 407 pnkfelix 1.1.2.1 408 pnkfelix 1.1.2.3 <BR> <B>effects:</B> Partially or completely allocates 409 pnkfelix 1.1.2.3 registers for the values defined and used in the code for 410 pnkfelix 1.1.2.3 <code>this</code>. Values will be preserved in the code; 411 pnkfelix 1.1.2.3 any live value will be stored before its assigned 412 pnkfelix 1.1.2.18 register is overwritten. 413 pnkfelix 1.1.2.18 <BR> Loads and Stores in general 414 pnkfelix 1.1.2.64 are added in the form of <code>SpillLoad</code>s and 415 pnkfelix 1.1.2.64 <code>SpillStore</code>s; the main <code>RegAlloc</code> 416 pnkfelix 1.1.2.85 class will use <code>resolveOutstandingTemps()</code> 417 pnkfelix 1.1.2.17 to replace these "fake" loads and stores with frame 418 pnkfelix 1.1.2.17 specified Memory instructions. 419 pnkfelix 1.1.2.17 420 pnkfelix 1.1.2.85 @see RegAlloc#resolveOutstandingTemps() 421 pnkfelix 1.1.2.3 */ 422 pnkfelix 1.1.2.65 protected abstract void generateRegAssignment(); 423 pnkfelix 1.1.2.1 424 pnkfelix 1.1.2.109 public static HCodeFactory codeFactory(final HCodeFactory pFact, 425 pnkfelix 1.1.2.109 final Frame frame, 426 pnkfelix 1.1.2.109 final RegAlloc.Factory raFact) { 427 pnkfelix 1.1.2.109 return (frame.getGCInfo() == null) ? 428 pnkfelix 1.1.2.109 concreteSpillFactory 429 pnkfelix 1.1.2.109 (abstractSpillFactory(pFact, frame, raFact), frame) : 430 pnkfelix 1.1.2.109 concreteSpillFactory 431 pnkfelix 1.1.2.109 (frame.getGCInfo().codeFactory 432 pnkfelix 1.1.2.109 (abstractSpillFactory(pFact, frame, raFact), frame), frame); 433 pnkfelix 1.1.2.109 } 434 pnkfelix 1.1.2.109 435 pnkfelix 1.1.2.3 /** Creates a register-allocating <code>HCodeFactory</code> for 436 pnkfelix 1.1.2.3 "instr" form. 437 pnkfelix 1.1.2.3 <BR> <B>requires:</B> <code>parentFactory</code> produces code 438 pnkfelix 1.1.2.3 in a derivative of "instr" form. 439 pnkfelix 1.1.2.3 <BR> <B>effects:</B> Produces an <code>HCodeFactory</code> 440 pnkfelix 1.1.2.3 which allocates registers in the code produced by 441 pnkfelix 1.1.2.3 <code>parentFactory</code> using the machine properties 442 pnkfelix 1.1.2.3 specified in <code>frame</code>. 443 pnkfelix 1.1.2.3 */ 444 pnkfelix 1.1.2.3 public static HCodeFactory codeFactory(final HCodeFactory parentFactory, 445 pnkfelix 1.1.2.3 final Frame frame) { 446 kkz 1.1.2.89 return (frame.getGCInfo() == null) ? 447 kkz 1.1.2.89 concreteSpillFactory 448 kkz 1.1.2.89 (abstractSpillFactory(parentFactory, frame), frame) : 449 kkz 1.1.2.89 concreteSpillFactory 450 kkz 1.1.2.89 (frame.getGCInfo().codeFactory 451 kkz 1.1.2.89 (abstractSpillFactory(parentFactory, frame), frame), frame); 452 pnkfelix 1.1.2.1 } 453 pnkfelix 1.1.2.62 454 pnkfelix 1.1.2.96 /** <code>IntermediateCode</code> is a code which has been 455 pnkfelix 1.1.2.66 register allocated but the architecture-specific spill 456 pnkfelix 1.1.2.96 instructions and method prologue/epilogue have not been 457 pnkfelix 1.1.2.96 inserted yet. Stack Offsets have been determined and are 458 pnkfelix 1.1.2.96 stored in the spill code instructions, but the output needs to 459 pnkfelix 1.1.2.96 be passed through <code>RegAlloc.concreteSpillFactory()</code> 460 pnkfelix 1.1.2.96 before it will be executable. 461 pnkfelix 1.1.2.66 @see RegAlloc#abstractSpillFactory 462 pnkfelix 1.1.2.66 @see RegAlloc#concreteSpillFactory 463 pnkfelix 1.1.2.66 */ 464 pnkfelix 1.1.2.96 public static interface IntermediateCode { 465 pnkfelix 1.1.2.96 Set usedRegisterTemps(); 466 pnkfelix 1.1.2.96 int numberOfLocals(); 467 pnkfelix 1.1.2.96 TempLocator getTempLocator(); 468 pnkfelix 1.1.2.96 } 469 pnkfelix 1.1.2.96 470 pnkfelix 1.1.2.96 /** IntermediateCodeFactory is an HCodeFactory that is guaranteed 471 pnkfelix 1.1.2.96 to produce <code>IntermediateCode</code>s. If the Java 472 pnkfelix 1.1.2.96 langaguage supported covariant return types, we would be able 473 pnkfelix 1.1.2.96 to enforce this constraint in the lanuage, but for now we are 474 pnkfelix 1.1.2.96 forced to rely on enforcing the constraint through 475 pnkfelix 1.1.2.96 specification alone. FSK is just keeping the interface around 476 pnkfelix 1.1.2.96 because its make things confusing to go and remove all of the 477 pnkfelix 1.1.2.96 references to IntermediateCodeFactory from Karen's code. 478 pnkfelix 1.1.2.96 */ 479 pnkfelix 1.1.2.96 public static interface IntermediateCodeFactory 480 pnkfelix 1.1.2.96 extends HCodeFactory { 481 pnkfelix 1.1.2.96 /** The <code>HCode</code>s returned by this method are 482 pnkfelix 1.1.2.96 guaranteed to implement the <code>IntermediateCode</code> 483 pnkfelix 1.1.2.96 interface. 484 pnkfelix 1.1.2.96 */ 485 pnkfelix 1.1.2.96 HCode convert(HMethod m); 486 pnkfelix 1.1.2.62 } 487 pnkfelix 1.1.2.62 488 pnkfelix 1.1.2.98 /** Produces an <code>IntermediateCodeFactory</code> which can be 489 pnkfelix 1.1.2.97 used to extract Derivation information about code it 490 pnkfelix 1.1.2.97 generates. 491 pnkfelix 1.1.2.64 <BR> <B>requires:</B> <code>parentFactory</code> produces code 492 pnkfelix 1.1.2.64 in a derivative of "instr" form. 493 pnkfelix 1.1.2.64 <BR> <B>effects:</B> Produces an 494 pnkfelix 1.1.2.97 <code>IntermediateCodeFactory</code> which allocates 495 pnkfelix 1.1.2.64 registers in the code produced by 496 pnkfelix 1.1.2.96 <code>parentFactory</code> using the machine properties 497 pnkfelix 1.1.2.97 specified in <code>frame</code>. 498 pnkfelix 1.1.2.96 Spilled temporarys are assigned a stack offset but the 499 pnkfelix 1.1.2.96 actual code does not have the concrete load and store 500 pnkfelix 1.1.2.96 instructions necessary for the spilling. In addition, 501 pnkfelix 1.1.2.96 the architecture specific method prologue and epilogue 502 pnkfelix 1.1.2.96 instructions have not been inserted either. The 503 pnkfelix 1.1.2.97 <code>IntermediateCodeFactory</code> returned can be 504 pnkfelix 1.1.2.97 passed to <code>concreteSpillFactory()</code> to produce 505 pnkfelix 1.1.2.97 a code factory suitable for generating runnable assembly 506 pnkfelix 1.1.2.97 code. 507 pnkfelix 1.1.2.64 */ 508 pnkfelix 1.1.2.96 public static IntermediateCodeFactory 509 pnkfelix 1.1.2.88 abstractSpillFactory(final HCodeFactory parent, 510 pnkfelix 1.1.2.88 final Frame frame) { 511 pnkfelix 1.1.2.111 return abstractSpillFactory(parent, frame, 512 pnkfelix 1.1.2.120 false?LOCAL:GLOBAL); 513 pnkfelix 1.1.2.109 } 514 pnkfelix 1.1.2.115 public static final Factory GLOBAL = GraphColoringRegAlloc.FACTORY; 515 pnkfelix 1.1.2.129 // public static final Factory GLOBAL = AppelRegAlloc.FACTORY; 516 pnkfelix 1.1.2.115 public static final Factory LOCAL = LocalCffRegAlloc.FACTORY; 517 pnkfelix 1.1.2.115 518 pnkfelix 1.1.2.119 static class MyCode extends Code 519 pnkfelix 1.1.2.119 implements IntermediateCode { 520 pnkfelix 1.1.2.119 Code mycode; 521 pnkfelix 1.1.2.119 int numLocals; TempLocator tl; Set usedRegs; 522 pnkfelix 1.1.2.119 MyCode(Code code, Instr i, 523 pnkfelix 1.1.2.119 Derivation d, String codeName, 524 pnkfelix 1.1.2.119 int numLocals, TempLocator tl, Set usedRegs) { 525 pnkfelix 1.1.2.119 super(code, i, d, codeName); 526 pnkfelix 1.1.2.119 mycode = code; 527 pnkfelix 1.1.2.119 this.numLocals = numLocals; 528 pnkfelix 1.1.2.119 this.tl = tl; 529 pnkfelix 1.1.2.119 this.usedRegs = usedRegs; 530 pnkfelix 1.1.2.119 } 531 pnkfelix 1.1.2.119 public String getName() { return mycode.getName(); } 532 pnkfelix 1.1.2.119 public List getRegisters(Instr i, Temp t) { 533 pnkfelix 1.1.2.119 return mycode.getRegisters(i,t); 534 pnkfelix 1.1.2.119 } 535 pnkfelix 1.1.2.119 public String getRegisterName(Instr i, Temp t, String s) { 536 pnkfelix 1.1.2.119 return mycode.getRegisterName(i,t,s); 537 pnkfelix 1.1.2.119 } 538 pnkfelix 1.1.2.119 public void assignRegister(Instr i, Temp pReg, List regs) { 539 pnkfelix 1.1.2.119 mycode.assignRegister(i, pReg, regs); 540 pnkfelix 1.1.2.119 } 541 pnkfelix 1.1.2.119 public boolean registerAssigned(Instr i, Temp t) { 542 pnkfelix 1.1.2.119 return mycode.registerAssigned(i, t); 543 pnkfelix 1.1.2.119 } 544 pnkfelix 1.1.2.119 public void removeAssignment(Instr i, Temp t) { 545 pnkfelix 1.1.2.119 mycode.removeAssignment(i, t); 546 pnkfelix 1.1.2.119 } 547 pnkfelix 1.1.2.119 public int numberOfLocals() { return numLocals; } 548 pnkfelix 1.1.2.119 public TempLocator getTempLocator() { return tl; } 549 pnkfelix 1.1.2.119 public Set usedRegisterTemps() { return usedRegs; } 550 pnkfelix 1.1.2.119 } 551 pnkfelix 1.1.2.119 552 pnkfelix 1.1.2.109 public static IntermediateCodeFactory 553 pnkfelix 1.1.2.109 abstractSpillFactory(final HCodeFactory parent, 554 pnkfelix 1.1.2.109 final Frame frame, 555 pnkfelix 1.1.2.109 final RegAlloc.Factory raFact) { 556 pnkfelix 1.1.2.64 return new IntermediateCodeFactory() { 557 pnkfelix 1.1.2.96 HCodeFactory p = parent; 558 pnkfelix 1.1.2.96 559 pnkfelix 1.1.2.96 public HCode convert(HMethod m) { 560 pnkfelix 1.1.2.96 Code preAllocCode = (Code) p.convert(m); 561 pnkfelix 1.1.2.96 if (preAllocCode == null) { 562 pnkfelix 1.1.2.96 return null; 563 pnkfelix 1.1.2.65 } 564 pnkfelix 1.1.2.65 565 pnkfelix 1.1.2.109 RegAlloc globalCode; 566 pnkfelix 1.1.2.65 567 pnkfelix 1.1.2.104 if (TIME) System.out.print("C"); 568 pnkfelix 1.1.2.109 globalCode = raFact.makeRegAlloc(preAllocCode); 569 pnkfelix 1.1.2.104 if (TIME) System.out.print("G"); 570 pnkfelix 1.1.2.65 globalCode.generateRegAssignment(); 571 pnkfelix 1.1.2.104 if (TIME) System.out.print("R"); 572 pnkfelix 1.1.2.96 List triple = globalCode.resolveOutstandingTemps(); 573 pnkfelix 1.1.2.104 if (TIME) System.out.print("#"); 574 pnkfelix 1.1.2.104 575 pnkfelix 1.1.2.96 final Instr instr = (Instr) triple.get(0); 576 pnkfelix 1.1.2.88 final RegFileInfo.TempLocator tl = 577 pnkfelix 1.1.2.96 (RegFileInfo.TempLocator) triple.get(1); 578 pnkfelix 1.1.2.68 final Code mycode = globalCode.code; 579 pnkfelix 1.1.2.96 final int numLocals = ((Integer)triple.get(2)).intValue(); 580 pnkfelix 1.1.2.96 final Set usedRegs = globalCode.computeUsedRegs(instr); 581 cananian 1.3.2.1 assert mycode != null; 582 pnkfelix 1.1.2.96 583 pnkfelix 1.1.2.68 584 pnkfelix 1.1.2.96 return new MyCode(mycode, instr, 585 pnkfelix 1.1.2.119 globalCode.getDerivation(), 586 pnkfelix 1.1.2.119 mycode.getName(), numLocals, tl, usedRegs); 587 pnkfelix 1.1.2.65 } 588 pnkfelix 1.1.2.65 589 pnkfelix 1.1.2.64 public String getCodeName() { return p.getCodeName(); } 590 pnkfelix 1.1.2.64 public void clear(HMethod m) { p.clear(m); } 591 pnkfelix 1.1.2.64 }; 592 pnkfelix 1.1.2.62 } 593 pnkfelix 1.1.2.93 594 pnkfelix 1.1.2.93 protected boolean allRegs(Collection c) { 595 cananian 1.9 for (Object tO : c) { 596 cananian 1.9 Temp t = (Temp) tO; 597 pnkfelix 1.1.2.93 if (!isRegister(t)) { 598 pnkfelix 1.1.2.93 return false; 599 pnkfelix 1.1.2.93 } 600 pnkfelix 1.1.2.93 } 601 pnkfelix 1.1.2.93 return true; 602 pnkfelix 1.1.2.93 } 603 pnkfelix 1.1.2.93 604 pnkfelix 1.1.2.62 605 pnkfelix 1.1.2.64 /** Produces an <code>HCodeFactory</code> which will transform the 606 pnkfelix 1.1.2.64 abstract spills into concrete spills. 607 pnkfelix 1.1.2.64 <BR> <B>effects:</B> Produces an <code>HCodeFactory</code> 608 pnkfelix 1.1.2.64 which takes the codes produced by <code>parent</code>, 609 pnkfelix 1.1.2.66 finds the code spilling abstract stack-offset Temps 610 pnkfelix 1.1.2.66 (generated by <code>parent</code>) and replaces it with 611 pnkfelix 1.1.2.66 concrete, architecture-dependant spill code. 612 pnkfelix 1.1.2.64 */ 613 pnkfelix 1.1.2.66 public static HCodeFactory concreteSpillFactory(final IntermediateCodeFactory parent, 614 pnkfelix 1.1.2.66 final Frame frame) { 615 pnkfelix 1.1.2.66 // Not sure how to handle multiple Temp references in one 616 pnkfelix 1.1.2.66 // InstrMEM...for now will assume that there is only one 617 pnkfelix 1.1.2.66 // memory references per InstrMEM... 618 pnkfelix 1.1.2.66 class InstrReplacer extends InstrVisitor { 619 pnkfelix 1.1.2.93 private boolean allRegs(Collection c) { 620 cananian 1.9 for (Object tO : c) { 621 cananian 1.9 Temp t = (Temp) tO; 622 pnkfelix 1.1.2.93 if (!frame.getRegFileInfo().isRegister(t)) { 623 pnkfelix 1.1.2.93 return false; 624 pnkfelix 1.1.2.93 } 625 pnkfelix 1.1.2.93 } 626 pnkfelix 1.1.2.93 return true; 627 pnkfelix 1.1.2.93 } 628 pnkfelix 1.1.2.93 629 pnkfelix 1.1.2.66 // Make these SMARTER: get rid of requirement that Loads 630 pnkfelix 1.1.2.66 // and Stores have only one references to memory (to 631 pnkfelix 1.1.2.66 // allow for StrongARMs ldm* instructions : starting doing 632 pnkfelix 1.1.2.66 // this, but I think TempFinder above relies on some parts 633 pnkfelix 1.1.2.66 // of it, at least when assigning offsets. Check over 634 pnkfelix 1.1.2.66 // this. 635 pnkfelix 1.1.2.66 private void visitStore(SpillStore m) { 636 pnkfelix 1.1.2.95 StackOffsetTemp def = m.stackOffset; 637 pnkfelix 1.1.2.94 List regs = Arrays.asList(m.use()); 638 cananian 1.3.2.1 assert allRegs(regs); 639 pnkfelix 1.1.2.66 List instrs = frame.getInstrBuilder(). 640 pnkfelix 1.1.2.93 makeStore(regs, def.offset, m); 641 pnkfelix 1.1.2.66 Instr.replaceInstrList(m, instrs); 642 pnkfelix 1.1.2.66 } 643 pnkfelix 1.1.2.66 644 pnkfelix 1.1.2.66 private void visitLoad(SpillLoad m) { 645 pnkfelix 1.1.2.95 StackOffsetTemp use = m.stackOffset; 646 pnkfelix 1.1.2.94 List regs = Arrays.asList(m.def()); 647 cananian 1.3.2.1 assert allRegs(regs); 648 pnkfelix 1.1.2.66 List instrs = frame.getInstrBuilder(). 649 pnkfelix 1.1.2.93 makeLoad(regs, use.offset, m); 650 pnkfelix 1.1.2.66 Instr.replaceInstrList(m, instrs); 651 pnkfelix 1.1.2.66 } 652 pnkfelix 1.1.2.66 653 pnkfelix 1.1.2.66 public void visit(Instr i) { 654 pnkfelix 1.1.2.66 // do nothing 655 pnkfelix 1.1.2.66 } 656 pnkfelix 1.1.2.66 657 pnkfelix 1.1.2.66 public void visit(InstrMEM i) { 658 pnkfelix 1.1.2.66 if (i instanceof SpillStore) { 659 pnkfelix 1.1.2.66 visitStore((SpillStore) i); 660 pnkfelix 1.1.2.66 } else if (i instanceof SpillLoad) { 661 pnkfelix 1.1.2.66 visitLoad((SpillLoad) i); 662 pnkfelix 1.1.2.66 } 663 pnkfelix 1.1.2.66 } 664 pnkfelix 1.1.2.66 } 665 pnkfelix 1.1.2.66 666 pnkfelix 1.1.2.66 return new HCodeFactory() { 667 pnkfelix 1.1.2.66 HCodeFactory p = parent; 668 pnkfelix 1.1.2.66 public HCode convert(HMethod m) { 669 pnkfelix 1.1.2.66 Code absCode = (Code) p.convert(m); 670 pnkfelix 1.1.2.66 if (absCode == null) { 671 pnkfelix 1.1.2.66 return null; 672 pnkfelix 1.1.2.66 } 673 pnkfelix 1.1.2.96 674 pnkfelix 1.1.2.96 int locals = ((IntermediateCode)absCode).numberOfLocals(); 675 pnkfelix 1.1.2.96 Set usedRegs = ((IntermediateCode)absCode).usedRegisterTemps(); 676 pnkfelix 1.1.2.96 Instr root = (Instr) absCode.getRootElement(); 677 pnkfelix 1.1.2.96 678 pnkfelix 1.1.2.96 root = frame.getCodeGen(). 679 pnkfelix 1.1.2.96 procFixup(absCode.getMethod(),root,locals,usedRegs); 680 pnkfelix 1.1.2.66 681 pnkfelix 1.1.2.66 InstrReplacer replace = new InstrReplacer(); 682 pnkfelix 1.1.2.66 683 pnkfelix 1.1.2.66 Iterator instrs = absCode.getElementsI(); 684 pnkfelix 1.1.2.66 while(instrs.hasNext()) { 685 pnkfelix 1.1.2.66 Instr i = (Instr) instrs.next(); 686 pnkfelix 1.1.2.66 i.accept(replace); 687 pnkfelix 1.1.2.66 } 688 pnkfelix 1.1.2.66 689 pnkfelix 1.1.2.82 if (DEBUG) { 690 pnkfelix 1.1.2.82 instrs = absCode.getElementsI(); // debug check 691 pnkfelix 1.1.2.82 while(instrs.hasNext()) { 692 pnkfelix 1.1.2.82 Instr i = (Instr) instrs.next(); 693 cananian 1.3.2.1 assert !(i instanceof SpillLoad) : "SpillLoad in i-list!"; 694 cananian 1.3.2.1 assert !(i instanceof SpillStore) : "SpillStore in i-list! " 695 pnkfelix 1.1.2.107 /* + i.getPrev() + " " + 696 cananian 1.3.2.1 i + " " + i.getNext() */; 697 pnkfelix 1.1.2.82 } 698 pnkfelix 1.1.2.105 } 699 pnkfelix 1.1.2.82 700 pnkfelix 1.1.2.82 701 pnkfelix 1.1.2.66 return absCode; 702 pnkfelix 1.1.2.66 } 703 pnkfelix 1.1.2.66 704 pnkfelix 1.1.2.66 public String getCodeName() { return p.getCodeName(); } 705 pnkfelix 1.1.2.66 public void clear(HMethod m) { p.clear(m); } 706 pnkfelix 1.1.2.66 }; 707 pnkfelix 1.1.2.62 } 708 pnkfelix 1.1.2.62 709 pnkfelix 1.1.2.6 710 pnkfelix 1.1.2.66 /** Temp Wrapper that incorporates a stack offset. */ 711 pnkfelix 1.1.2.66 private static class StackOffsetTemp extends Temp 712 pnkfelix 1.1.2.66 implements RegFileInfo.StackOffsetLoc { 713 pnkfelix 1.1.2.66 714 pnkfelix 1.1.2.66 Temp wrappedTemp; // FSK: is this field needed? 715 pnkfelix 1.1.2.66 int offset; 716 pnkfelix 1.1.2.66 StackOffsetTemp(Temp t, int stackOffset) { 717 pnkfelix 1.1.2.66 super(t); 718 pnkfelix 1.1.2.66 wrappedTemp = t; 719 pnkfelix 1.1.2.66 offset = stackOffset; 720 pnkfelix 1.1.2.66 } 721 pnkfelix 1.1.2.66 722 pnkfelix 1.1.2.77 public int kind() { 723 pnkfelix 1.1.2.77 return RegFileInfo.StackOffsetLoc.KIND; 724 pnkfelix 1.1.2.76 } 725 pnkfelix 1.1.2.66 public int stackOffset() { return offset; } 726 pnkfelix 1.1.2.87 727 pnkfelix 1.1.2.87 public String name() { 728 pnkfelix 1.1.2.87 return "StkTmp"+offset+ 729 pnkfelix 1.1.2.87 "("+wrappedTemp.toString()+")"; 730 pnkfelix 1.1.2.87 } 731 pnkfelix 1.1.2.66 } 732 pnkfelix 1.1.2.66 733 pnkfelix 1.1.2.65 /** Transforms Temp references for <code>this</code> into appropriate offsets 734 pnkfelix 1.1.2.13 from the Stack Pointer in the Memory. 735 pnkfelix 1.1.2.65 <BR> <B>modifies:</B> this 736 pnkfelix 1.1.2.64 <BR> <B>effects:</B> Replaces the <code>SpillLoad</code> and 737 pnkfelix 1.1.2.64 <code>SpillStore</code>s with memory instructions for the 738 pnkfelix 1.1.2.96 appropriate <code>Frame</code>. Returns a three-elem list 739 pnkfelix 1.1.2.96 (instr, tempLocator, numLocals) :: Instr x TempLocator x Integer 740 pnkfelix 1.1.2.52 */ 741 pnkfelix 1.1.2.82 protected final List resolveOutstandingTemps() { 742 pnkfelix 1.1.2.7 // This implementation is REALLY braindead. Fix to do a 743 pnkfelix 1.1.2.7 // smarter Graph-Coloring stack offset allocator 744 pnkfelix 1.1.2.65 Code in = code; 745 pnkfelix 1.1.2.83 final MultiMap tempXinstrToCommonLoc = new GenericMultiMap(); 746 cananian 1.3.2.1 assert in != null : "Don't try to resolve Temps for null HCodes"; 747 pnkfelix 1.1.2.7 748 pnkfelix 1.1.2.19 class TempFinder extends InstrVisitor { 749 pnkfelix 1.1.2.6 HashMap tempsToOffsets = new HashMap(); 750 pnkfelix 1.1.2.87 int nextOffset = 0; 751 pnkfelix 1.1.2.6 752 pnkfelix 1.1.2.66 private void visitLoad(SpillLoad m) { 753 pnkfelix 1.1.2.14 // look for non-Register Temps in use, adding 754 pnkfelix 1.1.2.6 // them to internal map 755 pnkfelix 1.1.2.85 Temp use = m.use()[0]; 756 pnkfelix 1.1.2.88 if(!isRegister(use)) { 757 pnkfelix 1.1.2.85 if (tempsToOffsets.get(use)==null){ 758 pnkfelix 1.1.2.85 tempsToOffsets.put(use, new Integer(nextOffset)); 759 pnkfelix 1.1.2.85 nextOffset += frame.getInstrBuilder().getSize(use); 760 pnkfelix 1.1.2.85 } 761 pnkfelix 1.1.2.85 762 pnkfelix 1.1.2.85 int off = ((Integer)tempsToOffsets.get(use)).intValue(); 763 pnkfelix 1.1.2.85 // replace 'use' with StackOffsetTemp 764 pnkfelix 1.1.2.94 StackOffsetTemp stkOff = 765 pnkfelix 1.1.2.94 new StackOffsetTemp(use, off); 766 pnkfelix 1.1.2.85 767 pnkfelix 1.1.2.94 m.stackOffset = stkOff; 768 pnkfelix 1.1.2.94 769 pnkfelix 1.1.2.94 List dxi = Default.pair(use, m); 770 pnkfelix 1.1.2.85 tempXinstrToCommonLoc.add(dxi, stkOff); 771 pnkfelix 1.1.2.85 772 pnkfelix 1.1.2.6 } 773 pnkfelix 1.1.2.85 } 774 pnkfelix 1.1.2.85 775 pnkfelix 1.1.2.66 private void visitStore(SpillStore m) { 776 pnkfelix 1.1.2.14 // look for non-Register Temps in def, adding 777 pnkfelix 1.1.2.14 // them to internal map 778 pnkfelix 1.1.2.85 Temp def = m.def()[0]; 779 pnkfelix 1.1.2.88 if(!isRegister(def)) { 780 pnkfelix 1.1.2.85 if (tempsToOffsets.get(def)==null){ 781 pnkfelix 1.1.2.85 tempsToOffsets.put(def, new Integer(nextOffset)); 782 pnkfelix 1.1.2.85 nextOffset += frame.getInstrBuilder().getSize(def); 783 pnkfelix 1.1.2.85 } 784 pnkfelix 1.1.2.85 785 pnkfelix 1.1.2.85 int off = 786 pnkfelix 1.1.2.85 ((Integer)tempsToOffsets.get(def)).intValue(); 787 pnkfelix 1.1.2.85 788 pnkfelix 1.1.2.85 // replace 'def' with StackOffsetTemp 789 pnkfelix 1.1.2.85 StackOffsetTemp stkOff = 790 pnkfelix 1.1.2.85 new StackOffsetTemp(def, off); 791 pnkfelix 1.1.2.94 792 pnkfelix 1.1.2.94 m.stackOffset = stkOff; 793 pnkfelix 1.1.2.85 794 pnkfelix 1.1.2.94 List dxi = Default.pair(def, m); 795 pnkfelix 1.1.2.85 tempXinstrToCommonLoc.add(dxi, stkOff); 796 pnkfelix 1.1.2.85 } else { 797 pnkfelix 1.1.2.85 System.out.println("what kind of spill is this??? : "+m); 798 pnkfelix 1.1.2.14 } 799 pnkfelix 1.1.2.14 } 800 pnkfelix 1.1.2.9 801 pnkfelix 1.1.2.66 public void visit(Instr i) { 802 pnkfelix 1.1.2.83 // lookup CommonLocs for defs in 'i' 803 cananian 1.9 for (Object defO : i.defC()) { 804 cananian 1.9 Temp def = (Temp) defO; 805 pnkfelix 1.1.2.83 List dxi = Default.pair(def, i); 806 pnkfelix 1.1.2.88 if (isRegister(def)) { 807 pnkfelix 1.1.2.84 tempXinstrToCommonLoc.add(dxi, def); 808 pnkfelix 1.1.2.84 } else { 809 cananian 1.3.2.1 // assert checked.contains(i) : i+" not checked"; 810 cananian 1.3.2.1 assert code.registerAssigned(i,def) : ("def:"+def+" not assigned in "+ 811 pnkfelix 1.1.2.112 i.getID()+" : "+i); 812 pnkfelix 1.1.2.84 Collection regs = code.getRegisters(i, def); 813 pnkfelix 1.1.2.84 tempXinstrToCommonLoc.addAll(dxi, regs); 814 pnkfelix 1.1.2.84 } 815 pnkfelix 1.1.2.83 } 816 pnkfelix 1.1.2.66 } 817 pnkfelix 1.1.2.19 818 pnkfelix 1.1.2.66 public void visit(InstrMEM m) { 819 pnkfelix 1.1.2.64 if (m instanceof SpillStore) 820 pnkfelix 1.1.2.64 visitStore((SpillStore) m); 821 pnkfelix 1.1.2.64 else if (m instanceof SpillLoad) { 822 pnkfelix 1.1.2.64 visitLoad((SpillLoad) m); 823 pnkfelix 1.1.2.63 } 824 pnkfelix 1.1.2.6 } 825 pnkfelix 1.1.2.6 } 826 pnkfelix 1.1.2.6 827 pnkfelix 1.1.2.6 TempFinder tf = new TempFinder(); 828 pnkfelix 1.1.2.6 Iterator instrs = in.getElementsI(); 829 pnkfelix 1.1.2.6 while(instrs.hasNext()) { 830 pnkfelix 1.1.2.6 Instr i = (Instr) instrs.next(); 831 pnkfelix 1.1.2.35 i.accept(tf); 832 pnkfelix 1.1.2.6 } 833 pnkfelix 1.1.2.96 834 pnkfelix 1.1.2.66 // now 'instrs' has spill instructions which reference Temps 835 pnkfelix 1.1.2.66 // that are associated with stack offsets 836 pnkfelix 1.1.2.58 837 pnkfelix 1.1.2.56 Instr instr = (Instr) in.getRootElement(); 838 pnkfelix 1.1.2.56 839 pnkfelix 1.1.2.83 TempLocator tl = new TempLocator() { 840 pnkfelix 1.1.2.83 public Set locate(Temp t, Instr i) { 841 pnkfelix 1.1.2.83 return (Set) 842 pnkfelix 1.1.2.83 tempXinstrToCommonLoc.getValues(Default.pair(t,i)); 843 pnkfelix 1.1.2.83 } 844 pnkfelix 1.1.2.83 }; 845 pnkfelix 1.1.2.83 846 pnkfelix 1.1.2.96 return Arrays.asList 847 pnkfelix 1.1.2.96 (new Object[] { instr, tl, new Integer(tf.nextOffset) }); 848 pnkfelix 1.1.2.6 } 849 pnkfelix 1.1.2.52 850 pnkfelix 1.1.2.56 private Set computeUsedRegs(Instr instrs) { 851 pnkfelix 1.1.2.56 Set s = new HashSet(); 852 pnkfelix 1.1.2.56 for (Instr il = instrs; il!=null; il=il.getNext()) { 853 pnkfelix 1.1.2.64 if (il instanceof SpillStore) continue; 854 pnkfelix 1.1.2.56 Temp[] d = il.def(); 855 pnkfelix 1.1.2.56 for (int i=0; i<d.length; i++) { 856 pnkfelix 1.1.2.88 if (isRegister(d[i])) { 857 pnkfelix 1.1.2.56 s.add(d[i]); 858 pnkfelix 1.1.2.56 } else { 859 pnkfelix 1.1.2.56 Collection c = code.getRegisters(il, d[i]); 860 pnkfelix 1.1.2.56 s.addAll(c); 861 pnkfelix 1.1.2.56 } 862 pnkfelix 1.1.2.56 } 863 pnkfelix 1.1.2.56 } 864 pnkfelix 1.1.2.56 return Collections.unmodifiableSet(s); 865 pnkfelix 1.1.2.56 } 866 pnkfelix 1.1.2.56 867 pnkfelix 1.1.2.90 /** Returns a List of the Component Temps that compose 868 pnkfelix 1.1.2.90 <code>t</code (Helper method). 869 pnkfelix 1.1.2.90 */ 870 pnkfelix 1.1.2.90 public List expand(Temp t) { 871 pnkfelix 1.1.2.90 return frame.getRegFileInfo().expand(t); 872 pnkfelix 1.1.2.90 } 873 pnkfelix 1.1.2.90 874 pnkfelix 1.1.2.90 /** Checks if any element of <code>c</code> is a register (Helper 875 pnkfelix 1.1.2.90 method). 876 pnkfelix 1.1.2.90 <BR> <B>requires:</B> <code>c</code> is a 877 pnkfelix 1.1.2.90 <code>Collection</code> of <code>Temp</code>s. 878 pnkfelix 1.1.2.90 <BR> <B>effects:</B> If <code>c</code> contains any Register 879 pnkfelix 1.1.2.90 <code>Temp</code>s, returns true. Else returns false. 880 pnkfelix 1.1.2.90 */ 881 pnkfelix 1.1.2.90 protected boolean hasRegister(Collection c) { 882 cananian 1.9 for (Object tO : c) { 883 cananian 1.9 Temp t = (Temp) tO; 884 pnkfelix 1.1.2.90 if (isRegister(t)) { 885 pnkfelix 1.1.2.90 return true; 886 pnkfelix 1.1.2.90 } 887 pnkfelix 1.1.2.90 } 888 pnkfelix 1.1.2.90 return false; 889 pnkfelix 1.1.2.90 } 890 pnkfelix 1.1.2.1 891 pnkfelix 1.1.2.3 /** Checks if <code>t</code> is a register (Helper method). 892 pnkfelix 1.1.2.3 <BR> <B>effects:</B> If <code>t</code> is a register for the 893 pnkfelix 1.1.2.3 <code>frame</code> associated with <code>this</code>, 894 pnkfelix 1.1.2.3 then returns true. Else returns false. 895 pnkfelix 1.1.2.3 */ 896 pnkfelix 1.1.2.88 protected boolean isRegister(Temp t) { 897 cananian 1.1.2.37 return frame.getRegFileInfo().isRegister(t); 898 pnkfelix 1.1.2.1 } 899 pnkfelix 1.1.2.1 900 pnkfelix 1.1.2.1 /** Checks if <code>i</code> is last use of <code>reg</code> in 901 pnkfelix 1.1.2.48 the block of instructions listed in <code>iter</code>. 902 pnkfelix 1.1.2.1 903 pnkfelix 1.1.2.1 <BR> <B>requires:</B> 904 pnkfelix 1.1.2.9 <BR> 1. <code>i</code> is an element in <code>iter</code> 905 pnkfelix 1.1.2.9 <BR> 2. <code>iter</code> is an <code>Iterator</code> of 906 pnkfelix 1.1.2.9 a linear series of <code>Instr</code>s in the 907 pnkfelix 1.1.2.9 order that they will be executed. 908 pnkfelix 1.1.2.9 <BR> 3. <code>iter</code> is currently indexed at 909 pnkfelix 1.1.2.9 <code>i</code> 910 pnkfelix 1.1.2.9 <BR> <B>modifies:</B> <code>iter</code> 911 pnkfelix 1.1.2.9 <BR> <B>effects:</B> 912 pnkfelix 1.1.2.9 <BR> 1. Returns true if no instruction after 913 pnkfelix 1.1.2.9 <code>i</code> in <code>iter</code> uses 914 pnkfelix 1.1.2.9 <code>reg</code> before <code>reg</code> is 915 pnkfelix 1.1.2.9 redefined (<code>i</code> redefining 916 pnkfelix 1.1.2.9 <code>reg</code> is sufficient). Else returns 917 pnkfelix 1.1.2.9 false. 918 pnkfelix 1.1.2.9 <BR> 2. <code>iter</code> is left at an undetermined 919 pnkfelix 1.1.2.9 index. 920 pnkfelix 1.1.2.1 */ 921 cananian 1.1.2.124 protected static boolean lastUse(Temp reg, UseDefable i, Iterator iter) { 922 cananian 1.1.2.124 UseDefable curr = i; 923 pnkfelix 1.1.2.1 boolean r = true; 924 pnkfelix 1.1.2.102 while (iter.hasNext() && ! curr.defC().contains(reg ) ) { 925 cananian 1.1.2.124 curr = (UseDefable) iter.next(); 926 pnkfelix 1.1.2.102 927 pnkfelix 1.1.2.102 if (curr.useC().contains(reg)) { 928 pnkfelix 1.1.2.1 r = false; 929 pnkfelix 1.1.2.1 break; 930 pnkfelix 1.1.2.1 } 931 pnkfelix 1.1.2.1 } 932 pnkfelix 1.1.2.1 return r; 933 pnkfelix 1.1.2.3 } 934 pnkfelix 1.1.2.43 935 pnkfelix 1.1.2.43 } 936 pnkfelix 1.1.2.42 937 pnkfelix 1.1.2.43 /** Visits <code>BasicBlock</code>s of <code>Instr</code>s and 938 pnkfelix 1.1.2.64 uses the <code>SpillLoad</code> and <code>SpillStore</code> 939 pnkfelix 1.1.2.43 instructions to construct <code>Web</code>s for this method, 940 pnkfelix 1.1.2.43 These webs will need to be run through a merging dataflow 941 pnkfelix 1.1.2.43 analysis pass. This is effectively ReachingDefs, but I 942 pnkfelix 1.1.2.43 couldn't figure out how to easily adapt Whaley's version of 943 pnkfelix 1.1.2.43 ReachingDefs to my needs (note to FSK, either figure out 944 pnkfelix 1.1.2.43 Whaley's version or rewrite it in a form thats at least as 945 pnkfelix 1.1.2.43 useful as the LiveVars class) (also note to FSK: the current 946 pnkfelix 1.1.2.43 implementation is soft and flabby (space and time 947 pnkfelix 1.1.2.43 inefficient); look into really fixing up ReachingDefs and 948 pnkfelix 1.1.2.43 LiveVars to be fast AND easy-to-use) 949 pnkfelix 1.1.2.43 */ 950 pnkfelix 1.1.2.43 class MakeWebsDumb extends ForwardDataFlowBasicBlockVisitor { 951 pnkfelix 1.1.2.43 /** struct class: 952 pnkfelix 1.1.2.43 'in' maps a Temp to a Web that is defined somewhere above 953 pnkfelix 1.1.2.43 this block. 954 pnkfelix 1.1.2.43 'out' maps a Temp to a Web that is defined somewhere above 955 pnkfelix 1.1.2.43 or within this block (note that the Web defined IN 956 pnkfelix 1.1.2.43 this block is a distinct object from the one defined 957 pnkfelix 1.1.2.43 ABOVE this block) 958 pnkfelix 1.1.2.43 'use' maps a Temp to the Set of Instrs that refer to it up 959 pnkfelix 1.1.2.43 until (and not including) that Temp's LAST definition 960 pnkfelix 1.1.2.43 in the block 961 pnkfelix 1.1.2.43 'def' maps a Temp to the Set of Instrs from that Temp's 962 pnkfelix 1.1.2.43 LAST definition in the basic block through all of its 963 pnkfelix 1.1.2.43 subsequent uses in the block 964 pnkfelix 1.1.2.42 */ 965 pnkfelix 1.1.2.43 class WebInfo { 966 cananian 1.3.2.2 MultiMapFactory mmf = new MultiMapFactory(); 967 pnkfelix 1.1.2.48 968 cananian 1.1.2.72 MultiMap in = new GenericMultiMap(); // Map[Temp, [Web] ] 969 cananian 1.1.2.72 MultiMap out = new GenericMultiMap(); // Map[Temp, [Web] ] 970 cananian 1.1.2.122 MultiMap use = new GenericMultiMap(new MySetFactory()); // Map[Temp, [Instr] ] 971 cananian 1.1.2.122 MultiMap def = new GenericMultiMap(new MySetFactory()); // Map[Temp, [Instr] ] 972 pnkfelix 1.1.2.48 973 cananian 1.8 class MySetFactory extends net.cscott.jutil.SetFactory { 974 pnkfelix 1.1.2.44 public Set makeSet(java.util.Collection c) { 975 pnkfelix 1.1.2.44 return new java.util.HashSet(c) { 976 pnkfelix 1.1.2.44 /** temporarily overriding this.toString() to 977 pnkfelix 1.1.2.44 give dense description of Set's contents. */ 978 pnkfelix 1.1.2.44 public String toString() { 979 pnkfelix 1.1.2.44 StringBuffer str = new StringBuffer("{ "); 980 pnkfelix 1.1.2.44 Iterator iter = iterator(); 981 pnkfelix 1.1.2.44 while(iter.hasNext()) { 982 pnkfelix 1.1.2.44 Instr i = (Instr) iter.next(); 983 pnkfelix 1.1.2.44 str.append( i.getID() ); 984 pnkfelix 1.1.2.44 if (iter.hasNext()) str.append(", "); 985 pnkfelix 1.1.2.44 } 986 pnkfelix 1.1.2.44 str.append(" }"); 987 pnkfelix 1.1.2.44 return str.toString(); 988 pnkfelix 1.1.2.44 } 989 pnkfelix 1.1.2.44 }; 990 pnkfelix 1.1.2.44 } 991 pnkfelix 1.1.2.44 } 992 pnkfelix 1.1.2.44 993 pnkfelix 1.1.2.43 994 pnkfelix 1.1.2.64 void foundLoad(RegAlloc.SpillLoad instr) { 995 cananian 1.9 for (Object tO : instr.useC()) { 996 cananian 1.9 Temp t = (Temp) tO; 997 pnkfelix 1.1.2.49 998 cananian 1.3.2.1 assert t != null : "No nulls for Temps"; 999 pnkfelix 1.1.2.43 1000 pnkfelix 1.1.2.45 if ((def.getValues(t)).isEmpty()) { 1001 pnkfelix 1.1.2.43 // if it uses a variable defined in 1002 pnkfelix 1.1.2.43 // another block, then add to USE 1003 pnkfelix 1.1.2.45 use.add(t, instr); 1004 pnkfelix 1.1.2.43 } else { 1005 pnkfelix 1.1.2.43 // put it in the DEF set; we'll move the DEF 1006 pnkfelix 1.1.2.43 // set into the USE set later if we have to. 1007 pnkfelix 1.1.2.45 def.add(t, instr); 1008 pnkfelix 1.1.2.42 } 1009 pnkfelix 1.1.2.42 } 1010 pnkfelix 1.1.2.43 } 1011 pnkfelix 1.1.2.42 1012 pnkfelix 1.1.2.64 void foundStore(RegAlloc.SpillStore instr) { 1013 cananian 1.9 for (Object tO : instr.defC()) { 1014 cananian 1.9 Temp t = (Temp) tO; 1015 pnkfelix 1.1.2.49 1016 cananian 1.3.2.1 assert t != null : "No nulls for Temps"; 1017 pnkfelix 1.1.2.43 1018 pnkfelix 1.1.2.45 if (!(def.getValues(t)).isEmpty()) { 1019 pnkfelix 1.1.2.43 // We have seen a DEF for t in this block 1020 pnkfelix 1.1.2.43 // before; need to move all those instrs over 1021 pnkfelix 1.1.2.43 // before putting this in the DEF set 1022 pnkfelix 1.1.2.43 Iterator instrs = 1023 pnkfelix 1.1.2.45 (def.getValues(t)).iterator(); 1024 pnkfelix 1.1.2.43 while(instrs.hasNext()) { 1025 pnkfelix 1.1.2.45 use.add(t, instrs.next()); 1026 pnkfelix 1.1.2.42 } 1027 pnkfelix 1.1.2.42 } 1028 pnkfelix 1.1.2.45 def.add(t, instr); 1029 pnkfelix 1.1.2.42 } 1030 pnkfelix 1.1.2.42 } 1031 pnkfelix 1.1.2.43 } 1032 pnkfelix 1.1.2.43 1033 pnkfelix 1.1.2.43 HashMap bbInfoMap; 1034 pnkfelix 1.1.2.43 1035 pnkfelix 1.1.2.43 MakeWebsDumb(Iterator basicBlocks) { 1036 pnkfelix 1.1.2.43 bbInfoMap = new HashMap(); 1037 pnkfelix 1.1.2.43 1038 pnkfelix 1.1.2.43 // initialize USE/DEF info 1039 pnkfelix 1.1.2.43 while(basicBlocks.hasNext()) { 1040 pnkfelix 1.1.2.43 BasicBlock bb = (BasicBlock) basicBlocks.next(); 1041 pnkfelix 1.1.2.43 WebInfo info = new WebInfo(); 1042 pnkfelix 1.1.2.43 bbInfoMap.put(bb, info); 1043 pnkfelix 1.1.2.42 1044 pnkfelix 1.1.2.71 ListIterator instrs = bb.statements().listIterator(); 1045 pnkfelix 1.1.2.43 while(instrs.hasNext()) { 1046 pnkfelix 1.1.2.43 Instr instr = (Instr) instrs.next(); 1047 pnkfelix 1.1.2.64 if (instr instanceof RegAlloc.SpillLoad) { 1048 pnkfelix 1.1.2.43 // LOAD FROM MEM 1049 pnkfelix 1.1.2.64 info.foundLoad((RegAlloc.SpillLoad) instr); 1050 pnkfelix 1.1.2.64 } else if (instr instanceof RegAlloc.SpillStore) { 1051 pnkfelix 1.1.2.43 // STORE TO MEM 1052 pnkfelix 1.1.2.64 info.foundStore((RegAlloc.SpillStore) instr); 1053 pnkfelix 1.1.2.43 } 1054 pnkfelix 1.1.2.43 } 1055 pnkfelix 1.1.2.43 } 1056 pnkfelix 1.1.2.43 } 1057 pnkfelix 1.1.2.43 1058 salcianu 1.4 public boolean merge(BasicBlockInterf from, BasicBlockInterf to) { 1059 pnkfelix 1.1.2.46 1060 pnkfelix 1.1.2.43 WebInfo fromInfo = (WebInfo) bbInfoMap.get(from); 1061 pnkfelix 1.1.2.43 WebInfo toInfo = (WebInfo) bbInfoMap.get(to); 1062 pnkfelix 1.1.2.43 1063 pnkfelix 1.1.2.43 // FSK: can't just use putAll(); need to track if a change 1064 pnkfelix 1.1.2.43 // FSK: occurred. 1065 pnkfelix 1.1.2.43 // toInfo.in.putAll(fromInfo.out); 1066 pnkfelix 1.1.2.43 boolean changed = false; 1067 pnkfelix 1.1.2.43 Iterator keys = fromInfo.out.keySet().iterator(); 1068 pnkfelix 1.1.2.43 while(keys.hasNext()) { 1069 pnkfelix 1.1.2.43 Object key = keys.next(); 1070 pnkfelix 1.1.2.46 java.util.Collection newVals = fromInfo.out.getValues(key); 1071 pnkfelix 1.1.2.46 changed = changed || toInfo.in.addAll(key, newVals); 1072 pnkfelix 1.1.2.42 } 1073 pnkfelix 1.1.2.46 1074 pnkfelix 1.1.2.49 // System.out.println("\t\t\tMerging from " + from + 1075 pnkfelix 1.1.2.49 // " to " + to + ":" + 1076 pnkfelix 1.1.2.49 // (changed?"changed":"nochange")); 1077 pnkfelix 1.1.2.43 1078 pnkfelix 1.1.2.43 return changed; 1079 pnkfelix 1.1.2.43 } 1080 pnkfelix 1.1.2.43 1081 pnkfelix 1.1.2.43 public void visit(BasicBlock b) { 1082 pnkfelix 1.1.2.49 // System.out.println("\t\t\tVisiting " + b); 1083 pnkfelix 1.1.2.42 1084 pnkfelix 1.1.2.43 WebInfo webInfo = (WebInfo) bbInfoMap.get(b); 1085 pnkfelix 1.1.2.43 1086 cananian 1.9 for (Object entryO : webInfo.in.entrySet()) { 1087 cananian 1.9 Map.Entry entry = (Map.Entry) entryO; 1088 pnkfelix 1.1.2.43 Temp t = (Temp) entry.getKey(); 1089 pnkfelix 1.1.2.43 Web web = (Web) entry.getValue(); 1090 pnkfelix 1.1.2.45 Iterator instrs = webInfo.use.getValues(t).iterator(); 1091 pnkfelix 1.1.2.46 1092 pnkfelix 1.1.2.49 // System.out.println("\t\t\t\t IN -> OUT : [" + 1093 pnkfelix 1.1.2.49 // web + ", "+b+"]" ); 1094 pnkfelix 1.1.2.46 1095 pnkfelix 1.1.2.43 while(instrs.hasNext()) { 1096 pnkfelix 1.1.2.47 web.refs.add(instrs.next()); 1097 pnkfelix 1.1.2.43 } 1098 pnkfelix 1.1.2.42 1099 pnkfelix 1.1.2.43 webInfo.out.put(t, web); 1100 pnkfelix 1.1.2.42 } 1101 pnkfelix 1.1.2.43 1102 cananian 1.9 for (Object tO : webInfo.def.keySet()) { 1103 cananian 1.9 Temp t = (Temp) tO; 1104 pnkfelix 1.1.2.45 Set instrs = (Set) webInfo.def.getValues(t); 1105 pnkfelix 1.1.2.42 1106 pnkfelix 1.1.2.43 Web web = new Web(t, instrs); 1107 pnkfelix 1.1.2.42 1108 pnkfelix 1.1.2.43 // Note that this will replace any web in OUT that was 1109 pnkfelix 1.1.2.43 // in IN with the last defined web (with the same temp) in 1110 pnkfelix 1.1.2.43 // this Basic Block (if one exists). This is the correct 1111 pnkfelix 1.1.2.43 // behavior. 1112 pnkfelix 1.1.2.43 webInfo.out.put(t, web); 1113 pnkfelix 1.1.2.43 1114 pnkfelix 1.1.2.42 } 1115 pnkfelix 1.1.2.3 } 1116 pnkfelix 1.1.2.1 } 1117 cananian 1.2