1 kkz 1.1.2.1 // BasicGCInfo.java, created Wed Jan 26 11:05:45 2000 by kkz 2 cananian 1.1.2.22 // Copyright (C) 2000 Karen K. Zee <kkz@alum.mit.edu> 3 kkz 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 kkz 1.1.2.1 package harpoon.Backend.Analysis; 5 kkz 1.1.2.1 6 kkz 1.1.2.1 import harpoon.Analysis.BasicBlock; 7 kkz 1.1.2.1 import harpoon.Analysis.DataFlow.LiveTemps; 8 kkz 1.1.2.16 import harpoon.Analysis.Instr.IgnoreSpillUseDefer; 9 pnkfelix 1.1.2.15 import harpoon.Analysis.Instr.RegAlloc.IntermediateCode; 10 kkz 1.1.2.1 import harpoon.Analysis.Instr.RegAlloc.IntermediateCodeFactory; 11 kkz 1.1.2.1 import harpoon.Analysis.Liveness; 12 kkz 1.1.2.6 import harpoon.Analysis.Maps.Derivation; 13 kkz 1.1.2.6 import harpoon.Analysis.Maps.Derivation.DList; 14 kkz 1.1.2.6 import harpoon.Analysis.ReachingDefs; 15 kkz 1.1.2.19 import harpoon.Analysis.ReachingDefsAltImpl; 16 kkz 1.1.2.1 import harpoon.Backend.Generic.Frame; 17 kkz 1.1.2.6 import harpoon.Backend.Generic.GCInfo.DLoc; 18 kkz 1.1.2.1 import harpoon.Backend.Generic.GCInfo.GCPoint; 19 kkz 1.1.2.14 import harpoon.Backend.Generic.GCInfo.WrappedMachineRegLoc; 20 kkz 1.1.2.14 import harpoon.Backend.Generic.GCInfo.WrappedStackOffsetLoc; 21 kkz 1.1.2.6 import harpoon.Backend.Generic.RegFileInfo.CommonLoc; 22 kkz 1.1.2.6 import harpoon.Backend.Generic.RegFileInfo.MachineRegLoc; 23 kkz 1.1.2.6 import harpoon.Backend.Generic.RegFileInfo.StackOffsetLoc; 24 kkz 1.1.2.6 import harpoon.Backend.Generic.RegFileInfo.TempLocator; 25 kkz 1.1.2.11 import harpoon.Backend.Maps.BackendDerivation; 26 kkz 1.1.2.6 import harpoon.ClassFile.HClass; 27 kkz 1.1.2.1 import harpoon.ClassFile.HCode; 28 kkz 1.1.2.1 import harpoon.ClassFile.HCodeEdge; 29 kkz 1.1.2.1 import harpoon.ClassFile.HCodeElement; 30 kkz 1.1.2.1 import harpoon.ClassFile.HCodeFactory; 31 kkz 1.1.2.1 import harpoon.ClassFile.HMethod; 32 kkz 1.1.2.1 import harpoon.IR.Assem.Instr; 33 kkz 1.1.2.1 import harpoon.IR.Assem.InstrCALL; 34 kkz 1.1.2.1 import harpoon.IR.Assem.InstrEdge; 35 kkz 1.1.2.14 import harpoon.IR.Assem.InstrJUMP; 36 kkz 1.1.2.1 import harpoon.IR.Assem.InstrLABEL; 37 kkz 1.1.2.1 import harpoon.IR.Assem.InstrVisitor; 38 kkz 1.1.2.1 import harpoon.IR.Properties.CFGrapher; 39 kkz 1.1.2.16 import harpoon.IR.Properties.UseDefer; 40 kkz 1.1.2.1 import harpoon.Temp.Label; 41 kkz 1.1.2.1 import harpoon.Temp.Temp; 42 kkz 1.1.2.1 import harpoon.Util.Util; 43 kkz 1.1.2.1 import harpoon.Util.Worklist; 44 cananian 1.1.2.24 import harpoon.Util.Collections.WorkSet; 45 kkz 1.1.2.1 46 kkz 1.1.2.1 import java.util.ArrayList; 47 kkz 1.1.2.14 import java.util.Collection; 48 kkz 1.1.2.14 import java.util.Collections; 49 kkz 1.1.2.1 import java.util.HashMap; 50 kkz 1.1.2.1 import java.util.HashSet; 51 kkz 1.1.2.1 import java.util.Iterator; 52 kkz 1.1.2.1 import java.util.List; 53 kkz 1.1.2.1 import java.util.Map; 54 kkz 1.1.2.1 import java.util.Set; 55 kkz 1.1.2.1 /** 56 kkz 1.1.2.1 * <code>BasicGCInfo</code> selects as GC points all 57 kkz 1.1.2.1 * call sites and backward branches. 58 kkz 1.1.2.1 * 59 cananian 1.1.2.22 * @author Karen K. Zee <kkz@alum.mit.edu> 60 cananian 1.6 * @version $Id: BasicGCInfo.java,v 1.6 2004/02/08 03:20:42 cananian Exp $ 61 kkz 1.1.2.1 */ 62 kkz 1.1.2.1 public class BasicGCInfo extends harpoon.Backend.Generic.GCInfo { 63 kkz 1.1.2.6 // Maps methods to gc points 64 kkz 1.1.2.6 final private Map m = new HashMap(); 65 kkz 1.1.2.6 // Maps classes to methods that have been processed 66 kkz 1.1.2.6 final private Map orderedMethods = new HashMap(); 67 kkz 1.1.2.14 /** Returns an ordered, unmodifiable <code>List</code> of the 68 kkz 1.1.2.6 <code>GCPoint</code>s in a given <code>HMethod</code>. 69 kkz 1.1.2.6 Returns <code>null</code> if the <code>HMethod</code> 70 kkz 1.1.2.6 has not been evaluated for garbage collection purposes. 71 kkz 1.1.2.6 Returns an empty <code>List</code> if the 72 kkz 1.1.2.6 <code>HMethod</code> has been evaluated and has been 73 kkz 1.1.2.6 found to not contain any GC points. 74 kkz 1.1.2.6 */ 75 kkz 1.1.2.6 public List gcPoints(HMethod hm) { 76 kkz 1.1.2.14 return Collections.unmodifiableList((List)m.get(hm)); 77 kkz 1.1.2.6 } 78 kkz 1.1.2.14 /** Returns an ordered, unmodifiable <code>List</code> of 79 kkz 1.1.2.14 <code>HMethod</code>s with the following properties: 80 kkz 1.1.2.6 - The declaring class of the <code>HMethod</code> is 81 kkz 1.1.2.6 <code>HClass</code>. 82 kkz 1.1.2.6 - The <code>convert</code> method of the 83 kkz 1.1.2.6 <code>IntermediateCodeFactory</code> has been invoked 84 kkz 1.1.2.6 on all the <code>HMethod</code>s in the <code>List</code>. 85 kkz 1.1.2.6 The <code>IntermediateCodeFactory</code> referred 86 kkz 1.1.2.6 to here is the one returned by the <code>codeFactory</code> 87 kkz 1.1.2.6 method of <code>this</code>. Returns null if the given 88 kkz 1.1.2.6 <code>HClass</code> does not declare any methods on which 89 kkz 1.1.2.6 <code>convert</code> has been invoked. 90 kkz 1.1.2.6 - The <code>HMethod</code>s are ordered according to the 91 kkz 1.1.2.6 order in which the <code>convert</code> method was invoked. 92 kkz 1.1.2.6 */ 93 kkz 1.1.2.6 public List getOrderedMethods(HClass hc) { 94 kkz 1.1.2.14 final List result = (List)orderedMethods.get(hc); 95 kkz 1.1.2.14 if (result == null) return null; 96 kkz 1.1.2.14 return Collections.unmodifiableList(result); 97 kkz 1.1.2.6 } 98 kkz 1.1.2.6 // adds a given method to the orderedMethod map 99 kkz 1.1.2.6 // used to maintain the orderedMethod map 100 kkz 1.1.2.6 private void addToOrderedMethods(HMethod hm) { 101 kkz 1.1.2.6 List l = (List)orderedMethods.get(hm.getDeclaringClass()); 102 kkz 1.1.2.6 if (l != null) { 103 kkz 1.1.2.6 // hm should not yet be in the List 104 cananian 1.3.2.1 assert !l.contains(hm); 105 kkz 1.1.2.6 } else { 106 kkz 1.1.2.14 // the HClass is not yet in the map; make a new List 107 kkz 1.1.2.6 l = new ArrayList(); 108 kkz 1.1.2.6 // add new entry to map 109 kkz 1.1.2.6 orderedMethods.put(hm.getDeclaringClass(), l); 110 kkz 1.1.2.6 } 111 kkz 1.1.2.14 l.add(hm); 112 kkz 1.1.2.6 } 113 kkz 1.1.2.1 /** Returns an IntermediateCodeFactory that inserts 114 kkz 1.1.2.1 <code>InstrLABEL</code>s at garbage collection points 115 kkz 1.1.2.1 and stores the information needed by the garbage 116 kkz 1.1.2.6 collector in <code>this</code>. 117 kkz 1.1.2.1 <BR> <B>requires:</B> The <code>parentFactory</code> 118 kkz 1.1.2.6 in <code>Instr</code> form. 119 kkz 1.1.2.1 */ 120 kkz 1.1.2.1 public IntermediateCodeFactory 121 kkz 1.1.2.1 codeFactory(final IntermediateCodeFactory parentFactory, 122 kkz 1.1.2.1 final Frame frame) 123 kkz 1.1.2.1 { 124 kkz 1.1.2.1 return new IntermediateCodeFactory() { 125 kkz 1.1.2.1 protected final HCodeFactory parent = parentFactory; 126 kkz 1.1.2.1 protected final Frame f = frame; 127 kkz 1.1.2.1 protected final CFGrapher cfger = CFGrapher.DEFAULT; 128 kkz 1.1.2.14 protected final Map hce2label = new HashMap(); 129 kkz 1.1.2.1 public HCode convert(HMethod hm) { 130 kkz 1.1.2.6 // preserve ordering information 131 kkz 1.1.2.6 addToOrderedMethods(hm); 132 kkz 1.1.2.6 harpoon.IR.Assem.Code hc = 133 kkz 1.1.2.6 (harpoon.IR.Assem.Code)parent.convert(hm); 134 kkz 1.1.2.6 if (hc == null) { 135 kkz 1.1.2.6 // need to map method to empty List 136 kkz 1.1.2.6 // of GC points to indicate that the 137 kkz 1.1.2.6 // method has been processed, but no 138 kkz 1.1.2.6 // GC points were found 139 kkz 1.1.2.6 m.put(hm, new ArrayList()); 140 kkz 1.1.2.6 return null; 141 kkz 1.1.2.6 } 142 kkz 1.1.2.14 List hceList = hc.getElementsL(); 143 kkz 1.1.2.16 UseDefer ud = new IgnoreSpillUseDefer(); 144 kkz 1.1.2.6 // pass 1: liveness and reaching definitions analyses 145 kkz 1.1.2.16 LiveTemps ltAnalysis = analyzeLiveness(hc, ud); 146 kkz 1.1.2.19 ReachingDefs rdAnalysis = 147 kkz 1.1.2.19 new ReachingDefsAltImpl(hc, cfger, ud); 148 kkz 1.1.2.1 // pass 2: identify backward branches 149 kkz 1.1.2.6 Set backEdgeGCPts = identifyBackwardBranches(hc); 150 kkz 1.1.2.1 // pass 3: identify GC points 151 kkz 1.1.2.1 List gcps = new ArrayList(); 152 kkz 1.1.2.14 // clear map before going into GCPointFinder 153 kkz 1.1.2.14 hce2label.clear(); 154 kkz 1.1.2.16 // GCPointFinder gcpf = new GCPointFinder 155 kkz 1.1.2.16 // (hm, hc, gcps, ltAnalysis, rdAnalysis, backEdgeGCPts, 156 kkz 1.1.2.16 // hc.getDerivation()); 157 kkz 1.1.2.16 // For now, ignoring back edges. 158 kkz 1.1.2.6 GCPointFinder gcpf = 159 kkz 1.1.2.14 new GCPointFinder(hm, hc, gcps, ltAnalysis, rdAnalysis, 160 kkz 1.1.2.17 new HashSet(), hc.getDerivation(), ud); 161 kkz 1.1.2.1 for(Iterator instrs = hc.getElementsL().iterator(); 162 kkz 1.1.2.1 instrs.hasNext(); ) 163 kkz 1.1.2.1 ((Instr)instrs.next()).accept(gcpf); 164 kkz 1.1.2.14 // put labels in 165 cananian 1.6 for(Object iO : hce2label.keySet()) { 166 cananian 1.6 Instr i = (Instr) iO; 167 kkz 1.1.2.14 InstrLABEL label = (InstrLABEL)hce2label.get(i); 168 kkz 1.1.2.14 // instr should only have one successor 169 cananian 1.5 assert cfger.succC(i).size() == 1; 170 kkz 1.1.2.16 // insert label 171 kkz 1.1.2.14 label.layout(i, i.getNext()); 172 kkz 1.1.2.14 } 173 kkz 1.1.2.1 m.put(hm, gcps); // add to map 174 kkz 1.1.2.14 return hc; 175 kkz 1.1.2.1 } 176 kkz 1.1.2.1 // do liveness analysis and return analysis 177 kkz 1.1.2.16 private LiveTemps analyzeLiveness(HCode intermediateCode, 178 kkz 1.1.2.16 UseDefer ud) { 179 kkz 1.1.2.1 // use CFGrapher.DEFAULT for now at Felix's bequest 180 kkz 1.1.2.1 // Instrs should graduate to having their own CFGrapher 181 pnkfelix 1.1.2.5 BasicBlock.Factory bbFact = 182 cananian 1.1.2.8 new BasicBlock.Factory(intermediateCode, cfger); 183 kkz 1.1.2.1 Set liveOnExit = f.getRegFileInfo().liveOnExit(); 184 kkz 1.1.2.16 LiveTemps ltAnalysis = new LiveTemps(bbFact, liveOnExit, ud); 185 pnkfelix 1.1.2.5 // get an iterator for the solver 186 pnkfelix 1.1.2.5 Iterator it = bbFact.blockSet().iterator(); 187 kkz 1.1.2.1 harpoon.Analysis.DataFlow.Solver.worklistSolve(it, ltAnalysis); 188 kkz 1.1.2.16 // ltAnalysis should now contain the liveness 189 kkz 1.1.2.16 // results we want 190 kkz 1.1.2.1 return ltAnalysis; 191 kkz 1.1.2.1 } 192 kkz 1.1.2.16 // identify and return Instrs that come before 193 kkz 1.1.2.16 // backward branches 194 kkz 1.1.2.1 private Set identifyBackwardBranches(HCode intermediateCode) { 195 kkz 1.1.2.1 // pass 1: number Instrs 196 kkz 1.1.2.1 Map ordering = new HashMap(); 197 kkz 1.1.2.1 int index = 0; 198 kkz 1.1.2.16 for(Iterator instrs = intermediateCode.getElementsL(). 199 kkz 1.1.2.16 iterator(); instrs.hasNext(); ) 200 kkz 1.1.2.1 ordering.put(instrs.next(), new Integer(index++)); 201 kkz 1.1.2.1 // pass 2: identify backward branches 202 kkz 1.1.2.1 Set results = new HashSet(); 203 kkz 1.1.2.1 // work list of edges that need to be examined 204 kkz 1.1.2.1 // start with the successors of the root Instr 205 kkz 1.1.2.1 HCodeElement root = intermediateCode.getRootElement(); 206 kkz 1.1.2.1 Worklist toProcess = new WorkSet(cfger.succC(root)); 207 kkz 1.1.2.1 while(!toProcess.isEmpty()) { 208 kkz 1.1.2.1 HCodeEdge edge = (HCodeEdge)toProcess.pull(); 209 kkz 1.1.2.1 Integer from = (Integer)ordering.get(edge.from()); 210 kkz 1.1.2.1 Integer to = (Integer)ordering.get(edge.to()); 211 cananian 1.3.2.1 assert from != null && to != null; 212 kkz 1.1.2.1 if (from.intValue() > to.intValue()) 213 kkz 1.1.2.1 results.add(edge.from()); 214 kkz 1.1.2.1 else { 215 cananian 1.3.2.1 assert from.intValue() != to.intValue(); 216 kkz 1.1.2.1 // add to work list the successor edges 217 kkz 1.1.2.16 for (Iterator edges = cfger.succC(edge.to()). 218 kkz 1.1.2.16 iterator(); edges.hasNext(); ) 219 kkz 1.1.2.1 toProcess.push(edges.next()); 220 kkz 1.1.2.1 } 221 kkz 1.1.2.1 } 222 kkz 1.1.2.1 return results; 223 kkz 1.1.2.1 } 224 kkz 1.1.2.1 public String getCodeName() { 225 kkz 1.1.2.1 return parent.getCodeName(); // should i have my own name? 226 kkz 1.1.2.1 } 227 kkz 1.1.2.1 public void clear(HMethod hm) { 228 kkz 1.1.2.1 parent.clear(hm); 229 kkz 1.1.2.1 m.remove(hm); // remove from map 230 kkz 1.1.2.1 } 231 kkz 1.1.2.1 class GCPointFinder extends InstrVisitor { 232 kkz 1.1.2.1 protected final List results; 233 kkz 1.1.2.1 protected final LiveTemps lt; 234 kkz 1.1.2.6 protected final ReachingDefs rd; 235 kkz 1.1.2.1 protected final Set s; 236 kkz 1.1.2.11 protected final TempLocator tl; 237 cananian 1.1.2.2 protected final harpoon.Analysis.Maps.Derivation d; 238 kkz 1.1.2.14 protected final HMethod hm; 239 kkz 1.1.2.14 protected final HCode hc; 240 kkz 1.1.2.17 protected final UseDefer ud; 241 kkz 1.1.2.1 protected int index = 0; 242 kkz 1.1.2.1 /** Creates a <code>GCPointFinder</code> object. 243 kkz 1.1.2.1 @param results 244 kkz 1.1.2.16 an empty <code>List</code> for storing 245 kkz 1.1.2.16 the resulting <code>GCPoint</code> objects 246 kkz 1.1.2.1 @param lt 247 kkz 1.1.2.16 the completed <code>LiveTemps</code> analysis 248 kkz 1.1.2.1 @param s 249 kkz 1.1.2.16 the <code>Set</code> of <code>Instr</code>s 250 kkz 1.1.2.16 that occur before a backward branch 251 kkz 1.1.2.1 */ 252 kkz 1.1.2.14 public GCPointFinder(HMethod hm, HCode hc, List results, 253 kkz 1.1.2.14 LiveTemps lt, 254 kkz 1.1.2.6 ReachingDefs rd, Set s, 255 kkz 1.1.2.17 harpoon.Analysis.Maps.Derivation d, 256 kkz 1.1.2.17 UseDefer ud) { 257 kkz 1.1.2.1 this.hm = hm; 258 kkz 1.1.2.14 this.hc = hc; 259 cananian 1.3.2.1 assert results != null && results.isEmpty(); 260 kkz 1.1.2.1 this.results = results; 261 kkz 1.1.2.1 this.lt = lt; 262 kkz 1.1.2.6 this.rd = rd; 263 kkz 1.1.2.1 this.s = s; 264 kkz 1.1.2.1 this.d = d; 265 pnkfelix 1.1.2.15 this.tl = ((IntermediateCode)hc).getTempLocator(); 266 kkz 1.1.2.17 this.ud = ud; 267 kkz 1.1.2.1 } 268 kkz 1.1.2.1 public void visit(InstrCALL c) { 269 kkz 1.1.2.6 // all InstrCALLs are GC points 270 kkz 1.1.2.14 if (c.getTargets().size() == 0) { 271 kkz 1.1.2.14 // native calls fall through 272 cananian 1.3.2.1 assert c.canFallThrough : "InstrCALL with no targets must fall through."; 273 kkz 1.1.2.14 updateGCInfo(c, null); 274 kkz 1.1.2.14 } else { 275 kkz 1.1.2.14 List targets = c.getTargets(); 276 kkz 1.1.2.14 // non-native calls have a return 277 kkz 1.1.2.14 // address and an exception address 278 cananian 1.3.2.1 assert targets.size() == 2 : "InstrCALL with targets must have regular"+ 279 cananian 1.3.2.1 " and exceptional return addresses."; 280 kkz 1.1.2.14 updateGCInfo(c, (Label)targets.get(0)); 281 kkz 1.1.2.14 } 282 kkz 1.1.2.14 } 283 kkz 1.1.2.14 public void visit(InstrJUMP j) { 284 kkz 1.1.2.14 // InstrJUMPs are GC points only if 285 kkz 1.1.2.14 // they come before a backward edge 286 kkz 1.1.2.14 if (!s.contains(j)) return; 287 kkz 1.1.2.14 List targets = j.getTargets(); 288 cananian 1.3.2.1 assert targets.size() == 1 : "Multiple targets for InstrJUMP."; 289 kkz 1.1.2.14 updateGCInfo(j, (Label)targets.get(0)); 290 kkz 1.1.2.1 } 291 kkz 1.1.2.1 public void visit(Instr i) { 292 kkz 1.1.2.1 if (!s.contains(i)) return; 293 kkz 1.1.2.14 // Instrs are GC points only if 294 kkz 1.1.2.14 // they come before a backward edge, 295 kkz 1.1.2.14 // in which case they must have a 296 kkz 1.1.2.14 // conditional target 297 cananian 1.3.2.1 assert i.canFallThrough : "Cannot fall through non-jump,"+ 298 cananian 1.3.2.1 " non-call Instr before a backward edge."; 299 kkz 1.1.2.14 List targets = i.getTargets(); 300 cananian 1.3.2.1 assert targets.size() == 1 : "No target for Instr before a backward edge."; 301 kkz 1.1.2.14 updateGCInfo(i, (Label)targets.get(0)); 302 kkz 1.1.2.14 // alternatively: 303 kkz 1.1.2.14 // updateGCInfo(i, null); 304 kkz 1.1.2.1 } 305 kkz 1.1.2.14 private void updateGCInfo(Instr i, Label l) { 306 kkz 1.1.2.14 // add label if one is not already provided 307 kkz 1.1.2.14 if (l == null) { 308 kkz 1.1.2.14 String str = 309 cananian 1.1.2.23 f.getRuntime().getNameMap().mangle(hm, "gcp_"+index++); 310 kkz 1.1.2.14 l = new Label(str); 311 kkz 1.1.2.14 InstrLABEL label = f.getInstrBuilder().makeLabel(l, i); 312 kkz 1.1.2.14 hce2label.put(i, label); 313 kkz 1.1.2.14 } 314 kkz 1.1.2.14 // we want the live temps going into the instr 315 kkz 1.1.2.6 WorkSet live = new WorkSet(); 316 kkz 1.1.2.1 live.addAll(lt.getLiveBefore(i)); 317 kkz 1.1.2.6 // filter out non-pointers and derived pointers 318 kkz 1.1.2.6 Set liveLocs = new HashSet(); 319 kkz 1.1.2.10 Map derivedPtrs = new HashMap(); 320 kkz 1.1.2.13 Map calleeSaved = new HashMap(); 321 kkz 1.1.2.6 while(!live.isEmpty()) { 322 kkz 1.1.2.6 Temp t = (Temp)live.pull(); 323 kkz 1.1.2.19 //System.out.println(t.toString()+" is live."); 324 cananian 1.3.2.1 assert i != null : "Cannot pass null instruction"+ 325 cananian 1.3.2.1 " to reaching definitions analysis"; 326 cananian 1.3.2.1 assert t != null : "Cannot pass null temporary"+ 327 cananian 1.3.2.1 " to reaching definitions analysis"; 328 kkz 1.1.2.16 Iterator defPtsit = 329 kkz 1.1.2.16 rd.reachingDefs(i, t).iterator(); 330 kkz 1.1.2.16 // there must be at least one defintion 331 kkz 1.1.2.16 // that reaches i 332 cananian 1.3.2.1 assert defPtsit.hasNext() : "Cannot find"+ 333 kkz 1.1.2.14 " definition of "+t.toString()+" at "+ 334 cananian 1.3.2.1 i.toString(); 335 kkz 1.1.2.14 Instr defPt = (Instr)defPtsit.next(); 336 kkz 1.1.2.6 // all of the above defPts should work 337 kkz 1.1.2.19 DList ddl = d.derivation(defPt, t); 338 kkz 1.1.2.11 if (ddl == null) { 339 kkz 1.1.2.11 // try and find its type 340 kkz 1.1.2.19 HClass hclass = d.typeMap(defPt, t); 341 kkz 1.1.2.11 if (hclass == null) { 342 kkz 1.1.2.11 // no derivation, no type means 343 kkz 1.1.2.11 // this is a callee-saved register 344 kkz 1.1.2.11 BackendDerivation bd = (BackendDerivation)d; 345 kkz 1.1.2.11 // find out which register's contents we have 346 kkz 1.1.2.11 BackendDerivation.Register reg = 347 kkz 1.1.2.14 bd.calleeSaveRegister(defPt, t); 348 kkz 1.1.2.14 Set locationSet = tl.locate(t, defPt); 349 kkz 1.1.2.13 // the following may be a bad assumption 350 cananian 1.3.2.1 assert locationSet.size() == 1; 351 kkz 1.1.2.11 for (Iterator it=locationSet.iterator(); 352 kkz 1.1.2.12 it.hasNext(); ) { 353 kkz 1.1.2.13 calleeSaved.put(reg, (CommonLoc)it.next()); 354 kkz 1.1.2.12 } 355 kkz 1.1.2.11 } else if (!hclass.isPrimitive()) 356 kkz 1.1.2.11 // a non-derived pointer: add all 357 kkz 1.1.2.11 // locations where it can be found 358 kkz 1.1.2.14 liveLocs.addAll(tl.locate(t, defPt)); 359 kkz 1.1.2.11 } else 360 kkz 1.1.2.10 // a derived pointer: add to set of derived ptrs 361 kkz 1.1.2.14 derivedPtrs.put(tl.locate(t, defPt), 362 kkz 1.1.2.6 unroll(ddl, i)); 363 kkz 1.1.2.1 } 364 kkz 1.1.2.11 GCPoint gcp = 365 kkz 1.1.2.14 new GCPoint(i, l, derivedPtrs, liveLocs, calleeSaved); 366 kkz 1.1.2.1 results.add(gcp); 367 kkz 1.1.2.1 } 368 kkz 1.1.2.6 private DLoc unroll(DList ddl, Instr instr) { 369 kkz 1.1.2.6 List regLocs = new ArrayList(); 370 kkz 1.1.2.6 List regSigns = new ArrayList(); 371 kkz 1.1.2.6 List stackLocs = new ArrayList(); 372 kkz 1.1.2.6 List stackSigns = new ArrayList(); 373 kkz 1.1.2.6 while(ddl != null) { 374 kkz 1.1.2.6 Temp base = ddl.base; 375 pnkfelix 1.1.2.20 // System.out.println("doing reachingDefs"+ 376 kkz 1.1.2.19 // " instr:"+instr+ 377 kkz 1.1.2.19 // " base:"+base); 378 pnkfelix 1.1.2.18 Collection c1 = rd.reachingDefs(instr, base); 379 cananian 1.3.2.1 assert c1 != null; 380 cananian 1.3.2.1 assert c1.size() >0; 381 pnkfelix 1.1.2.18 Instr[] defPts = (Instr[]) 382 pnkfelix 1.1.2.18 c1.toArray(new Instr[c1.size()]); 383 kkz 1.1.2.6 // any of the definition points should work 384 pnkfelix 1.1.2.18 Collection c2 = tl.locate(base, defPts[0]); 385 cananian 1.3.2.1 assert c2 != null && c2.size() > 0; 386 pnkfelix 1.1.2.18 CommonLoc[] locs = (CommonLoc[]) 387 pnkfelix 1.1.2.18 c2.toArray(new CommonLoc[c2.size()]); 388 kkz 1.1.2.6 // any of the CommonLocs should work 389 kkz 1.1.2.6 switch(locs[0].kind()) { 390 kkz 1.1.2.6 case StackOffsetLoc.KIND: 391 kkz 1.1.2.14 WrappedStackOffsetLoc wsol = new 392 kkz 1.1.2.14 WrappedStackOffsetLoc((StackOffsetLoc)locs[0]); 393 kkz 1.1.2.14 stackLocs.add(wsol); 394 kkz 1.1.2.6 stackSigns.add(new Boolean(ddl.sign)); 395 kkz 1.1.2.6 break; 396 kkz 1.1.2.6 case MachineRegLoc.KIND: 397 kkz 1.1.2.14 WrappedMachineRegLoc wmrl = new 398 kkz 1.1.2.14 WrappedMachineRegLoc((MachineRegLoc)locs[0]); 399 kkz 1.1.2.14 regLocs.add(wmrl); 400 kkz 1.1.2.6 regSigns.add(new Boolean(ddl.sign)); 401 kkz 1.1.2.6 break; 402 cananian 1.3.2.1 default: assert false; 403 kkz 1.1.2.6 } 404 pnkfelix 1.1.2.18 ddl = ddl.next; // FSK moved this outside switch 405 kkz 1.1.2.6 } 406 cananian 1.3.2.1 assert regLocs.size() == regSigns.size(); 407 kkz 1.1.2.14 WrappedMachineRegLoc[] regArray = 408 kkz 1.1.2.14 (WrappedMachineRegLoc[])regLocs.toArray 409 kkz 1.1.2.14 (new WrappedMachineRegLoc[0]); 410 kkz 1.1.2.6 boolean[] regSignArray = new boolean[regSigns.size()]; 411 kkz 1.1.2.6 int i=0; 412 kkz 1.1.2.6 for(Iterator it=regSigns.iterator(); it.hasNext(); ) 413 kkz 1.1.2.6 regSignArray[i++] = 414 kkz 1.1.2.6 ((Boolean)it.next()).booleanValue(); 415 cananian 1.3.2.1 assert stackLocs.size() == stackSigns.size(); 416 kkz 1.1.2.14 WrappedStackOffsetLoc[] stackArray = 417 kkz 1.1.2.14 (WrappedStackOffsetLoc[])stackLocs.toArray 418 kkz 1.1.2.14 (new WrappedStackOffsetLoc[0]); 419 kkz 1.1.2.6 boolean[] stackSignArray = new boolean[stackSigns.size()]; 420 kkz 1.1.2.6 int j=0; 421 kkz 1.1.2.6 for(Iterator it=stackSigns.iterator(); it.hasNext(); ) 422 kkz 1.1.2.6 stackSignArray[j++] = 423 kkz 1.1.2.6 ((Boolean)it.next()).booleanValue(); 424 kkz 1.1.2.6 425 kkz 1.1.2.6 return new DLoc(regArray, stackArray, 426 kkz 1.1.2.6 regSignArray, stackSignArray); 427 kkz 1.1.2.6 } 428 kkz 1.1.2.1 } 429 kkz 1.1.2.1 }; 430 kkz 1.1.2.1 } // codeFactory 431 kkz 1.1.2.1 } // class 432 kkz 1.1.2.16 433 kkz 1.1.2.16 434 kkz 1.1.2.6 435 kkz 1.1.2.1 436 cananian 1.2