1 pnkfelix 1.1.2.1  // ReachingDefsAltImpl.java, created Fri Jul 14 14:12:18 2000 by pnkfelix
  2 pnkfelix 1.1.2.1  // 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;
  5 pnkfelix 1.1.2.1  
  6 pnkfelix 1.1.2.1  import harpoon.ClassFile.HCode;
  7 pnkfelix 1.1.2.1  import harpoon.ClassFile.HCodeElement;
  8 pnkfelix 1.1.2.1  import harpoon.IR.Properties.CFGrapher;
  9 pnkfelix 1.1.2.1  import harpoon.Temp.Temp;
 10 cananian 1.5      import net.cscott.jutil.SetFactory;
 11 cananian 1.5      import net.cscott.jutil.BitSetFactory;
 12 cananian 1.5      import net.cscott.jutil.Factories;
 13 pnkfelix 1.1.2.1  import harpoon.Util.Util;
 14 cananian 1.5      import net.cscott.jutil.Default;
 15 pnkfelix 1.1.2.1  import harpoon.Util.Worklist;
 16 cananian 1.1.2.17 import harpoon.Util.Collections.WorkSet;
 17 cananian 1.5      import net.cscott.jutil.Indexer;
 18 pnkfelix 1.1.2.1  import harpoon.IR.Properties.UseDefer;
 19 pnkfelix 1.1.2.1  import harpoon.IR.Quads.TYPECAST;
 20 pnkfelix 1.1.2.1  
 21 pnkfelix 1.1.2.1  import java.util.Collections;
 22 pnkfelix 1.1.2.1  import java.util.Collection;
 23 pnkfelix 1.1.2.1  import java.util.HashMap;
 24 pnkfelix 1.1.2.1  import java.util.HashSet;
 25 pnkfelix 1.1.2.1  import java.util.Iterator;
 26 pnkfelix 1.1.2.1  import java.util.Map;
 27 pnkfelix 1.1.2.1  import java.util.List;
 28 pnkfelix 1.1.2.12 import java.util.ArrayList;
 29 pnkfelix 1.1.2.4  import java.util.ListIterator;
 30 pnkfelix 1.1.2.1  import java.util.Set;
 31 pnkfelix 1.1.2.1  
 32 pnkfelix 1.1.2.1  /**
 33 pnkfelix 1.1.2.1   * <code>ReachingDefsAltImpl</code>
 34 pnkfelix 1.1.2.1   * 
 35 pnkfelix 1.1.2.1   * @author  Felix S. Klock II <pnkfelix@mit.edu>
 36 cananian 1.6       * @version $Id: ReachingDefsAltImpl.java,v 1.6 2004/02/08 03:19:12 cananian Exp $
 37 pnkfelix 1.1.2.1   */
 38 cananian 1.3.2.2  public class ReachingDefsAltImpl<HCE extends HCodeElement>
 39 cananian 1.3.2.2      extends ReachingDefs<HCE> {
 40 pnkfelix 1.1.2.15 
 41 cananian 1.3.2.2      final private CFGrapher<HCE> cfger;
 42 cananian 1.3.2.2      final protected BasicBlock.Factory<HCE> bbf;
 43 pnkfelix 1.1.2.1  
 44 pnkfelix 1.1.2.1      // produces Set<Pair<Temp:t, HCodeElement:h>> where `h' is 
 45 pnkfelix 1.1.2.1      // a definition point for `t' 
 46 pnkfelix 1.1.2.13     final protected AugSetFactory bsf;
 47 pnkfelix 1.1.2.1      
 48 pnkfelix 1.1.2.1      // maps Temp:t -> Set:d where `bsf'-produced `d' contains all (t,x) 
 49 cananian 1.3.2.3      final protected Map<Temp,Set<Map.Entry<Temp,HCE>>> tempToAllDefs;
 50 pnkfelix 1.1.2.1  
 51 cananian 1.3.2.2      final protected Map<BasicBlock<HCE>,Record> cache =
 52 cananian 1.3.2.2          new HashMap<BasicBlock<HCE>,Record>(); // maps BasicBlocks to in Sets 
 53 pnkfelix 1.1.2.1      final protected boolean check_typecast; // demand the special treatment of TYPECAST
 54 cananian 1.3.2.2      final protected UseDefer<HCE> ud;
 55 pnkfelix 1.1.2.1  
 56 pnkfelix 1.1.2.4  
 57 pnkfelix 1.1.2.1      /** Creates a <code>ReachingDefsImpl</code> object for the
 58 pnkfelix 1.1.2.1          provided <code>HCode</code> using <code>CFGrapher.DEFAULT</code> and 
 59 pnkfelix 1.1.2.1          <code>UseDefer.DEFAULT</code>.  
 60 pnkfelix 1.1.2.1          This may take a while since the analysis is done at this time.
 61 pnkfelix 1.1.2.1      */
 62 cananian 1.3.2.2      public ReachingDefsAltImpl(HCode<HCE> hc) {
 63 cananian 1.5              this(hc, (CFGrapher<HCE>) CFGrapher.DEFAULT);
 64 pnkfelix 1.1.2.1      }
 65 pnkfelix 1.1.2.1  
 66 pnkfelix 1.1.2.1      /** Creates a <code>ReachingDefsImpl</code> object for the
 67 pnkfelix 1.1.2.1          provided <code>HCode</code> for an IR implementing
 68 cananian 1.1.2.14         <code>UseDefable</code> using the provided <code>CFGrapher</code>.
 69 pnkfelix 1.1.2.1          This may take a while since the analysis is done at this time. 
 70 pnkfelix 1.1.2.1      */
 71 cananian 1.3.2.2      public ReachingDefsAltImpl(HCode<HCE> hc, CFGrapher<HCE> cfger) {
 72 cananian 1.5              this(hc, cfger, (UseDefer<HCE>) UseDefer.DEFAULT);
 73 pnkfelix 1.1.2.1      }
 74 pnkfelix 1.1.2.1      /** Creates a <code>ReachingDefsImpl</code> object for the
 75 pnkfelix 1.1.2.1          provided <code>HCode</code> using the provided 
 76 pnkfelix 1.1.2.1          <code>CFGrapher</code> and <code>UseDefer</code>. This may
 77 pnkfelix 1.1.2.1          take a while since the analysis is done at this time.
 78 pnkfelix 1.1.2.1      */
 79 cananian 1.3.2.2      public ReachingDefsAltImpl(final HCode<HCE> hc, CFGrapher<HCE> cfger, final UseDefer<HCE> ud) {
 80 pnkfelix 1.1.2.1          super(hc);
 81 pnkfelix 1.1.2.1          this.cfger = cfger;
 82 cananian 1.3.2.2          this.bbf = new BasicBlock.Factory<HCE>(hc, cfger);
 83 pnkfelix 1.1.2.1          this.ud = ud;
 84 pnkfelix 1.1.2.1          // sometimes, TYPECAST need to be treated specially
 85 pnkfelix 1.1.2.1          check_typecast = 
 86 pnkfelix 1.1.2.1              hc.getName().equals(harpoon.IR.Quads.QuadNoSSA.codename);
 87 pnkfelix 1.1.2.12         report("Entering analyze() ");
 88 pnkfelix 1.1.2.12 
 89 pnkfelix 1.1.2.12         final DefPtRecord dpr = getDefPts();
 90 pnkfelix 1.1.2.12         tempToAllDefs = dpr.tempToPairs;
 91 pnkfelix 1.1.2.1          
 92 pnkfelix 1.1.2.12         // System.out.print("constucting universe");
 93 cananian 1.3.2.3          Iterator<Set<Map.Entry<Temp,HCE>>> pairsets = tempToAllDefs.values().iterator();
 94 cananian 1.3.2.3          Set<Map.Entry<Temp,HCE>> universe = new HashSet<Map.Entry<Temp,HCE>>(tempToAllDefs.values().size());
 95 pnkfelix 1.1.2.12         int totalsz = 0, numsets = 0, totsqsz = 0;
 96 pnkfelix 1.1.2.13         int maxsz=0, minsz=Integer.MAX_VALUE;
 97 pnkfelix 1.1.2.2          while(pairsets.hasNext()) {
 98 cananian 1.3.2.3              Set<Map.Entry<Temp,HCE>> pairset = pairsets.next();
 99 pnkfelix 1.1.2.12             universe.addAll(pairset);
100 pnkfelix 1.1.2.12 
101 pnkfelix 1.1.2.13             if (pairset.size() > maxsz) maxsz = pairset.size();
102 pnkfelix 1.1.2.13             if (pairset.size() < minsz) minsz = pairset.size();
103 pnkfelix 1.1.2.12             totalsz += pairset.size(); 
104 pnkfelix 1.1.2.12             totsqsz += (pairset.size()*pairset.size());
105 pnkfelix 1.1.2.12             numsets++;
106 pnkfelix 1.1.2.2          }
107 pnkfelix 1.1.2.12         
108 pnkfelix 1.1.2.2  
109 pnkfelix 1.1.2.12         report(" totalsz:"+totalsz +" totsqsz:"+totsqsz +
110 pnkfelix 1.1.2.13                " maxsz:"+maxsz+" minsz:"+minsz+
111 pnkfelix 1.1.2.12                " numsets:"+numsets +" mean sz:"+(totalsz/numsets));
112 pnkfelix 1.1.2.12         report(" numblks:"+bbf.blockSet().size()+
113 pnkfelix 1.1.2.12                " numtmps:"+tempToAllDefs.keySet().size());
114 pnkfelix 1.1.2.12         final int meanSize = totalsz / numsets;
115 pnkfelix 1.1.2.12 
116 pnkfelix 1.1.2.13         report("constucting AugmentedSetFactory (uni:"+universe.size()+")");
117 pnkfelix 1.1.2.12 
118 pnkfelix 1.1.2.13         bsf = new AugSetFactory(universe);
119 pnkfelix 1.1.2.12 
120 pnkfelix 1.1.2.12         if (true) {
121 pnkfelix 1.1.2.12             report("s/HashSet/AugSet/");
122 pnkfelix 1.1.2.12             // replace HashSets with AugSets in tempToAllDefs.values()
123 cananian 1.3.2.3              Iterator<Map.Entry<Temp,Set<Map.Entry<Temp,HCE>>>> es = tempToAllDefs.entrySet().iterator();
124 pnkfelix 1.1.2.13             while(es.hasNext()) {
125 cananian 1.3.2.3                  Map.Entry<Temp,Set<Map.Entry<Temp,HCE>>> e = es.next();
126 cananian 1.3.2.3                  Set<Map.Entry<Temp,HCE>> pairs = e.getValue();
127 pnkfelix 1.1.2.13                 e.setValue(bsf.makeSet(pairs));
128 pnkfelix 1.1.2.12             }
129 pnkfelix 1.1.2.13             bsf.stats();
130 pnkfelix 1.1.2.13         
131 pnkfelix 1.1.2.12         }
132 pnkfelix 1.1.2.12 
133 pnkfelix 1.1.2.12         report("performing analysis");
134 pnkfelix 1.1.2.2          analyze(tempToAllDefs);
135 pnkfelix 1.1.2.1          report("Leaving analyze()");
136 pnkfelix 1.1.2.2  
137 pnkfelix 1.1.2.2  
138 pnkfelix 1.1.2.1      }
139 pnkfelix 1.1.2.1  
140 pnkfelix 1.1.2.1      /** Returns the Set of <code>HCodeElement</code>s providing definitions
141 pnkfelix 1.1.2.1       *  of <code>Temp</code> <code>t</code> which reach 
142 pnkfelix 1.1.2.8       *  <code>HCodeElement</code> <code>hce</code>. 
143 pnkfelix 1.1.2.8       * Any use that is not explicitly defined is assumed to be
144 pnkfelix 1.1.2.8       * implicitly defined by the root element of the
145 pnkfelix 1.1.2.8       * <code>HCode</code> for <code>this</code>. 
146 pnkfelix 1.1.2.8       */
147 cananian 1.3.2.2      public Set<HCE> reachingDefs(HCE hce, Temp t) {
148 pnkfelix 1.1.2.3          // report("Processing HCodeElement: "+hce+" Temp: "+t);
149 pnkfelix 1.1.2.1          // find out which BasicBlock this HCodeElement is from
150 cananian 1.3.2.2          BasicBlock<HCE> b = bbf.getBlock(hce);
151 cananian 1.3.2.1          //assert b != null : "no block" /* +" for "+hce */;
152 witchel  1.1.2.10         if(b == null) {
153 cananian 1.3.2.3              if (true) return java.util.Collections.EMPTY_SET;
154 witchel  1.1.2.10        System.out.println("\nSuccC " + cfger.succC(hce));
155 witchel  1.1.2.10        System.out.println("PredC " + cfger.predC(hce));
156 cananian 1.3.2.1         assert false : "no block"+" for "+hce;
157 witchel  1.1.2.10     }
158 pnkfelix 1.1.2.3          // report("In BasicBlock: "+b.toString());
159 pnkfelix 1.1.2.4  
160 pnkfelix 1.1.2.4          boolean sawIt = false;
161 cananian 1.3.2.2          List<HCE> stms = b.statements();
162 cananian 1.3.2.2          ListIterator<HCE> iter = stms.listIterator(stms.size());
163 pnkfelix 1.1.2.4          while(iter.hasPrevious()) {
164 cananian 1.3.2.2              HCE curr = iter.previous();
165 pnkfelix 1.1.2.4              if (curr == hce) {
166 pnkfelix 1.1.2.4                  sawIt = true;
167 pnkfelix 1.1.2.4                  break;
168 pnkfelix 1.1.2.4              }
169 pnkfelix 1.1.2.4          }
170 cananian 1.3.2.1          assert sawIt;
171 pnkfelix 1.1.2.4          
172 pnkfelix 1.1.2.4          // broke out of loop, so now we need to see if exists a
173 pnkfelix 1.1.2.4          // definition in remaining hces
174 pnkfelix 1.1.2.4          while(iter.hasPrevious()) {
175 cananian 1.3.2.2              HCE curr = iter.previous();
176 pnkfelix 1.1.2.4              
177 cananian 1.3.2.2              Collection<Temp> defC = null;
178 pnkfelix 1.1.2.4              
179 pnkfelix 1.1.2.4              // special treatment of TYPECAST
180 pnkfelix 1.1.2.4              if(check_typecast && (curr instanceof TYPECAST))
181 pnkfelix 1.1.2.4                  defC = Collections.singleton(((TYPECAST)curr).objectref());
182 pnkfelix 1.1.2.4              else
183 pnkfelix 1.1.2.4                  defC = ud.defC(curr);
184 pnkfelix 1.1.2.4              
185 pnkfelix 1.1.2.4              if (defC.contains(t)) {
186 pnkfelix 1.1.2.5                  // System.out.print(" I");
187 pnkfelix 1.1.2.4                  return Collections.singleton(curr);
188 pnkfelix 1.1.2.4              }
189 pnkfelix 1.1.2.4          }
190 pnkfelix 1.1.2.4          
191 pnkfelix 1.1.2.4          // if we got here, then there isn't a def in the remainder
192 pnkfelix 1.1.2.4          // of the basic block... do a lookup
193 pnkfelix 1.1.2.4  
194 pnkfelix 1.1.2.1          // get the map for the BasicBlock
195 cananian 1.3.2.3          Record r = cache.get(b);
196 pnkfelix 1.1.2.1  
197 pnkfelix 1.1.2.1          // find HCodeElements associated with `t' in the IN Set
198 cananian 1.3.2.3          Set<Map.Entry<Temp,HCE>> results = bsf.makeSet(r.IN);
199 cananian 1.3.2.3          Set<Map.Entry<Temp,HCE>> defs = tempToAllDefs.get(t);
200 pnkfelix 1.1.2.8          if (defs == null) {
201 pnkfelix 1.1.2.9              // no def for t
202 pnkfelix 1.1.2.9              defs = Collections.EMPTY_SET;
203 pnkfelix 1.1.2.8          }
204 pnkfelix 1.1.2.7          results.retainAll(defs);
205 pnkfelix 1.1.2.2  
206 cananian 1.3.2.3          Iterator<Map.Entry<Temp,HCE>> pairs = results.iterator();
207 cananian 1.3.2.3          Set<HCE> results2 = new HashSet<HCE>();
208 pnkfelix 1.1.2.1          while(pairs.hasNext()) {
209 cananian 1.3.2.3              results2.add( pairs.next().getValue() );
210 pnkfelix 1.1.2.1          }
211 pnkfelix 1.1.2.2  
212 cananian 1.3.2.3          return results2;
213 pnkfelix 1.1.2.1      }
214 pnkfelix 1.1.2.1  
215 pnkfelix 1.1.2.1      // do analysis
216 cananian 1.3.2.3      private void analyze(Map<Temp,Set<Map.Entry<Temp,HCE>>> Temp_To_Pairs) {
217 pnkfelix 1.1.2.15         if (TIME) System.out.print("(");
218 pnkfelix 1.1.2.1          // build Gen and Kill sets
219 pnkfelix 1.1.2.12         report("Entering buildGenKillSets()");
220 pnkfelix 1.1.2.2          buildGenKillSets(Temp_To_Pairs);
221 pnkfelix 1.1.2.13 
222 pnkfelix 1.1.2.13         bsf.stats();
223 pnkfelix 1.1.2.3          // report("Leaving buildGenKillSets()");
224 pnkfelix 1.1.2.15         
225 pnkfelix 1.1.2.1          // solve for fixed point
226 pnkfelix 1.1.2.15         report("Entering solve()"); if (TIME) System.out.print("S");
227 pnkfelix 1.1.2.1          solve();
228 pnkfelix 1.1.2.3          // report("Leaving solve()");
229 pnkfelix 1.1.2.1          // store only essential information
230 cananian 1.3.2.3          Iterator<Record> records = cache.values().iterator();
231 pnkfelix 1.1.2.1          while(records.hasNext()) {
232 cananian 1.3.2.3              Record r = records.next();
233 pnkfelix 1.1.2.1              r.OUT = null; r.KILL = null; r.GEN = null;
234 pnkfelix 1.1.2.1          }
235 pnkfelix 1.1.2.15 
236 pnkfelix 1.1.2.15         if (TIME) System.out.print(")");
237 pnkfelix 1.1.2.1      }
238 pnkfelix 1.1.2.1  
239 pnkfelix 1.1.2.12     class DefPtRecord {
240 pnkfelix 1.1.2.12         // Temp -> Set of Pair< Temp, Defpt > >
241 cananian 1.3.2.3          private Map<Temp,Set<Map.Entry<Temp,HCE>>> tempToPairs;
242 pnkfelix 1.1.2.12         // List of Pair< Temp, Defpt > 
243 pnkfelix 1.1.2.12         private ArrayList defpts;
244 pnkfelix 1.1.2.12         DefPtRecord(int mapsz) {
245 cananian 1.3.2.3              tempToPairs = new HashMap<Temp,Set<Map.Entry<Temp,HCE>>>(mapsz);
246 pnkfelix 1.1.2.12             defpts = new ArrayList();
247 pnkfelix 1.1.2.12         }
248 pnkfelix 1.1.2.12     }
249 pnkfelix 1.1.2.12 
250 pnkfelix 1.1.2.12     // create a mapping of Temps to a Set of (t, defPt) Pairs, 
251 pnkfelix 1.1.2.12     // as well as a list of defPts defining more than one Temp. 
252 pnkfelix 1.1.2.12     // (the latter is to allow a more efficient indexer definition. 
253 pnkfelix 1.1.2.12     private DefPtRecord getDefPts() {
254 cananian 1.3.2.2          Collection<HCE> hceL = cfger.getElements(hc);
255 pnkfelix 1.1.2.12         DefPtRecord dpr = new DefPtRecord(hceL.size());
256 cananian 1.3.2.3          Map<Temp,Set<Map.Entry<Temp,HCE>>> m = dpr.tempToPairs;
257 pnkfelix 1.1.2.12         List multDefns = dpr.defpts;
258 cananian 1.6              for(HCE hce : hceL) {
259 pnkfelix 1.1.2.1              StringBuffer strbuf = new StringBuffer();
260 pnkfelix 1.1.2.1              Temp[] tArray = null;
261 pnkfelix 1.1.2.3              //report("Getting defs in: "+hce+" (defC:"+new java.util.ArrayList(ud.defC(hce))+")");
262 pnkfelix 1.1.2.1              // special treatment of TYPECAST
263 pnkfelix 1.1.2.1              if(check_typecast && (hce instanceof TYPECAST)) {
264 pnkfelix 1.1.2.1                  strbuf.append("TYPECAST: ");
265 pnkfelix 1.1.2.1                  tArray = new Temp[]{((TYPECAST)hce).objectref()};
266 pnkfelix 1.1.2.1              } else {
267 pnkfelix 1.1.2.1                  tArray = ud.def(hce);
268 pnkfelix 1.1.2.1                  if (tArray.length > 0)
269 pnkfelix 1.1.2.1                      strbuf.append("DEFINES: ");
270 pnkfelix 1.1.2.1              }
271 pnkfelix 1.1.2.1              for(int i=0; i < tArray.length; i++) {
272 pnkfelix 1.1.2.1                  Temp t = tArray[i];
273 pnkfelix 1.1.2.1                  strbuf.append(t+" ");
274 cananian 1.3.2.3                  Set<Map.Entry<Temp,HCE>> defPts = m.get(t);
275 pnkfelix 1.1.2.1                  if (defPts == null) {
276 pnkfelix 1.1.2.1                      // have not yet encountered this Temp
277 cananian 1.3.2.3                      defPts = new HashSet<Map.Entry<Temp,HCE>>();
278 pnkfelix 1.1.2.1                      // add to map
279 pnkfelix 1.1.2.1                      m.put(t, defPts);
280 pnkfelix 1.1.2.1                  }
281 pnkfelix 1.1.2.1                  // add this definition point
282 cananian 1.3.2.3                  Map.Entry<Temp,HCE> pair = Default.entry(t,hce);
283 pnkfelix 1.1.2.12                 defPts.add(pair);
284 pnkfelix 1.1.2.12                 if (tArray.length > 1) {
285 pnkfelix 1.1.2.12                     multDefns.add(pair);
286 pnkfelix 1.1.2.12                 }
287 pnkfelix 1.1.2.1              }
288 pnkfelix 1.1.2.12             if (false && DEBUG) {
289 pnkfelix 1.1.2.1                  Collection col = ud.useC(hce);
290 pnkfelix 1.1.2.1                  if (!col.isEmpty()) strbuf.append("\nUSES: ");
291 pnkfelix 1.1.2.1                  for(Iterator it2 = col.iterator(); it2.hasNext(); )
292 pnkfelix 1.1.2.1                      strbuf.append(it2.next().toString() + " ");
293 pnkfelix 1.1.2.1                  if (strbuf.length() > 0)
294 pnkfelix 1.1.2.1                      report(strbuf.toString());
295 pnkfelix 1.1.2.1              }
296 pnkfelix 1.1.2.1          }
297 pnkfelix 1.1.2.12         if (false && DEBUG) {
298 pnkfelix 1.1.2.1              StringBuffer strbuf2 = 
299 pnkfelix 1.1.2.1                  new StringBuffer("Have entry for Temp(s): ");
300 pnkfelix 1.1.2.1              for(Iterator keys = m.keySet().iterator(); keys.hasNext(); )
301 pnkfelix 1.1.2.1                  strbuf2.append(keys.next()+" ");
302 pnkfelix 1.1.2.1              report(strbuf2.toString());
303 pnkfelix 1.1.2.1          }
304 pnkfelix 1.1.2.12         return dpr;
305 pnkfelix 1.1.2.1      }
306 pnkfelix 1.1.2.2  
307 pnkfelix 1.1.2.1      final class Record {
308 cananian 1.3.2.3          Set<Map.Entry<Temp,HCE>> IN, OUT, GEN, KILL;
309 pnkfelix 1.1.2.12         boolean haveSeen = false;
310 pnkfelix 1.1.2.1          Record() {
311 pnkfelix 1.1.2.1              IN = bsf.makeSet();
312 pnkfelix 1.1.2.1              OUT = bsf.makeSet();
313 pnkfelix 1.1.2.1              GEN = bsf.makeSet();
314 pnkfelix 1.1.2.1              KILL = bsf.makeSet();
315 pnkfelix 1.1.2.1          }
316 pnkfelix 1.1.2.1      }
317 pnkfelix 1.1.2.1      // builds a BasicBlock -> Record mapping in `cache'
318 cananian 1.3.2.3      private void buildGenKillSets(Map<Temp,Set<Map.Entry<Temp,HCE>>> Temp_To_Pairs) {
319 pnkfelix 1.1.2.1          // calculate Gen and Kill sets for each basic block 
320 cananian 1.6              for(BasicBlock<HCE> b : bbf.blockSet()) {
321 pnkfelix 1.1.2.1              Record bitSets = new Record();
322 pnkfelix 1.1.2.1              cache.put(b, bitSets);
323 pnkfelix 1.1.2.1  
324 pnkfelix 1.1.2.1              // iterate through the instructions in the basic block
325 cananian 1.6                  for(HCE hce : b.statements()) {
326 pnkfelix 1.1.2.1                  Temp[] tArray = null;
327 pnkfelix 1.1.2.1                  // special treatment of TYPECAST
328 pnkfelix 1.1.2.1                  if(check_typecast && (hce instanceof TYPECAST))
329 pnkfelix 1.1.2.1                      tArray = new Temp[]{((TYPECAST)hce).objectref()};
330 pnkfelix 1.1.2.1                  else
331 pnkfelix 1.1.2.1                      tArray = ud.def(hce);
332 pnkfelix 1.1.2.1                  for(int i=0; i < tArray.length; i++) {
333 pnkfelix 1.1.2.1                      Temp t = tArray[i];
334 cananian 1.3.2.3                      Map.Entry<Temp,HCE> def = Default.entry(t, hce);
335 pnkfelix 1.1.2.12                     bitSets.GEN.add(def);
336 cananian 1.3.2.3                      Set<Map.Entry<Temp,HCE>> kill = bsf.makeSet(Temp_To_Pairs.get(t));
337 pnkfelix 1.1.2.12                     kill.remove(def);
338 pnkfelix 1.1.2.12                     bitSets.KILL.addAll(kill);
339 pnkfelix 1.1.2.1                  }
340 pnkfelix 1.1.2.1              }
341 pnkfelix 1.1.2.1          }
342 pnkfelix 1.1.2.1      }
343 pnkfelix 1.1.2.1      // uses Worklist algorithm to solve for reaching definitions
344 pnkfelix 1.1.2.1      // given a BasicBlock -> Record map
345 pnkfelix 1.1.2.1      private void solve() {
346 pnkfelix 1.1.2.1          int revisits = 0;
347 pnkfelix 1.1.2.1          WorkSet worklist;
348 pnkfelix 1.1.2.12 
349 pnkfelix 1.1.2.12         worklist = new WorkSet(bbf.blockSet().size());
350 pnkfelix 1.1.2.12         Iterator iter = bbf.postorderBlocksIter();
351 pnkfelix 1.1.2.12         while(iter.hasNext()) {
352 pnkfelix 1.1.2.12             worklist.addFirst(iter.next());
353 pnkfelix 1.1.2.1          }
354 pnkfelix 1.1.2.1  
355 pnkfelix 1.1.2.1          while(!worklist.isEmpty()) {
356 pnkfelix 1.1.2.12             // System.out.print(worklist.size() + " ");
357 pnkfelix 1.1.2.12             
358 pnkfelix 1.1.2.12             // FSK is unsure of these changes (11/13/2000)
359 pnkfelix 1.1.2.12             // BasicBlock b = (BasicBlock)worklist.pull();
360 pnkfelix 1.1.2.12             BasicBlock b = (BasicBlock)worklist.removeFirst();
361 pnkfelix 1.1.2.12             
362 pnkfelix 1.1.2.1              revisits++;
363 pnkfelix 1.1.2.1              // get all the bitSets for this BasicBlock
364 cananian 1.3.2.3              Record bitSet = cache.get(b);
365 pnkfelix 1.1.2.1              Set oldIN, oldOUT;
366 pnkfelix 1.1.2.1              oldIN = bsf.makeSet(bitSet.IN); // clone old in Set
367 pnkfelix 1.1.2.1              bitSet.IN.clear();
368 cananian 1.6                  for(Object predO : b.prevSet()) {
369 cananian 1.6                      BasicBlock pred = (BasicBlock) predO;
370 cananian 1.3.2.3                  Record pBitSet = cache.get(pred);
371 pnkfelix 1.1.2.1                  bitSet.IN.addAll(pBitSet.OUT); // union
372 pnkfelix 1.1.2.1              }
373 pnkfelix 1.1.2.12 
374 pnkfelix 1.1.2.12             // FSK is unsure of these changes (11/13/2000)
375 pnkfelix 1.1.2.12             if (bitSet.haveSeen && oldIN.equals(bitSet.IN)) {
376 pnkfelix 1.1.2.12                 // OUT is a function of IN, so if, by some miracle, IN
377 pnkfelix 1.1.2.12                 // has not changed, we continue
378 pnkfelix 1.1.2.12                 // System.out.print(" MIRACLE! ");
379 pnkfelix 1.1.2.12                 continue;
380 pnkfelix 1.1.2.12             }
381 pnkfelix 1.1.2.12 
382 pnkfelix 1.1.2.1              oldOUT = bitSet.OUT; // keep old out Set
383 pnkfelix 1.1.2.1              bitSet.OUT = bsf.makeSet(bitSet.IN);
384 pnkfelix 1.1.2.1              bitSet.OUT.removeAll(bitSet.KILL);
385 pnkfelix 1.1.2.1              bitSet.OUT.addAll(bitSet.GEN);
386 pnkfelix 1.1.2.12             bitSet.haveSeen = true;
387 pnkfelix 1.1.2.12 
388 pnkfelix 1.1.2.12             // FSK is unsure of these changes (11/13/2000)
389 pnkfelix 1.1.2.12             // if (oldIN.equals(bitSet.IN) && oldOUT.equals(bitSet.OUT))
390 pnkfelix 1.1.2.12             if (oldOUT.equals(bitSet.OUT)) {
391 pnkfelix 1.1.2.12                 // System.out.print(" GIFT! ");
392 pnkfelix 1.1.2.1                  continue;
393 pnkfelix 1.1.2.12             }
394 pnkfelix 1.1.2.1              for(Iterator succs=b.nextSet().iterator();succs.hasNext();){
395 pnkfelix 1.1.2.1                  Object block = (BasicBlock)succs.next();
396 pnkfelix 1.1.2.12                 worklist.addLast(block);
397 pnkfelix 1.1.2.1              }
398 pnkfelix 1.1.2.1          }
399 pnkfelix 1.1.2.15         if (TIME) System.out.print("#iter:"+revisits+
400 pnkfelix 1.1.2.15                                    " #bbs:"+bbf.blockSet().size());
401 pnkfelix 1.1.2.1  
402 pnkfelix 1.1.2.1      }
403 pnkfelix 1.1.2.1      // debugging utility
404 pnkfelix 1.1.2.3      private static final boolean DEBUG = false;
405 pnkfelix 1.1.2.13     private static void report(String str) {
406 pnkfelix 1.1.2.12         if (DEBUG) System.out.println(str+" "+new java.util.Date());
407 pnkfelix 1.1.2.13     }
408 pnkfelix 1.1.2.13 
409 pnkfelix 1.1.2.13     class AugSetFactory extends SetFactory {
410 pnkfelix 1.1.2.13         AugSetFactory(Set universe) { 
411 pnkfelix 1.1.2.15 
412 cananian 1.5                  // universe = new net.cscott.jutil.LinearSet(universe);
413 pnkfelix 1.1.2.15             // FSK: oog; don't do the above (BSF methods need fast
414 pnkfelix 1.1.2.15             // universe.contains(..) method implementation
415 pnkfelix 1.1.2.15 
416 pnkfelix 1.1.2.13             bitSetFact = new BitSetFactory(universe);
417 pnkfelix 1.1.2.13             final int unisize = universe.size();
418 pnkfelix 1.1.2.13             linToBitThreshold = unisize / 1000;
419 pnkfelix 1.1.2.13             bitToLinThreshold = unisize / 10000;
420 pnkfelix 1.1.2.13         }
421 pnkfelix 1.1.2.13 
422 pnkfelix 1.1.2.13         final BitSetFactory bitSetFact;
423 pnkfelix 1.1.2.13         //final SetFactory    linSetFact = Factories.linearSetFactory;
424 pnkfelix 1.1.2.13         final SetFactory    linSetFact = 
425 cananian 1.5                  new net.cscott.jutil.AggregateSetFactory();
426 pnkfelix 1.1.2.13         final int linToBitThreshold, bitToLinThreshold;
427 pnkfelix 1.1.2.13 
428 pnkfelix 1.1.2.13         int linToBitSwitches = 0;
429 pnkfelix 1.1.2.13         int bitToLinSwitches = 0;
430 pnkfelix 1.1.2.13         int startedAsBit = 0;
431 pnkfelix 1.1.2.13         int startedAsLin = 0;
432 pnkfelix 1.1.2.13 
433 pnkfelix 1.1.2.13         public void stats() { 
434 pnkfelix 1.1.2.13             report("stats: "+
435 pnkfelix 1.1.2.13                    "l2b: "+linToBitSwitches+" "+
436 pnkfelix 1.1.2.13                    "b2l: "+bitToLinSwitches+" "+
437 pnkfelix 1.1.2.13                    "sal: "+startedAsLin+" "+
438 pnkfelix 1.1.2.13                    "sab: "+startedAsBit);
439 pnkfelix 1.1.2.13         }
440 pnkfelix 1.1.2.13         
441 pnkfelix 1.1.2.13         class AugSet extends java.util.AbstractSet { 
442 pnkfelix 1.1.2.13             boolean bitSetRep;
443 pnkfelix 1.1.2.13             Set bSet;
444 pnkfelix 1.1.2.13             
445 pnkfelix 1.1.2.13             // FSK:  maybe change to add HashSets for medium size
446 pnkfelix 1.1.2.13             // (O(size-of-set) vs O(size-of-universe)
447 pnkfelix 1.1.2.13 
448 pnkfelix 1.1.2.13             public AugSet(Collection c){ this(c, (c.size() > linToBitThreshold));}
449 pnkfelix 1.1.2.13             public AugSet(Collection c, boolean useBitSetRep) {
450 pnkfelix 1.1.2.13                 if (useBitSetRep) {
451 pnkfelix 1.1.2.13                     startedAsBit++;
452 pnkfelix 1.1.2.13                     bitSetRep = true;
453 pnkfelix 1.1.2.13                     if (c instanceof AugSet) {
454 pnkfelix 1.1.2.13                         bSet = bitSetFact.makeSet( ((AugSet)c).bSet ); 
455 pnkfelix 1.1.2.13                     } else {
456 pnkfelix 1.1.2.13                         bSet = bitSetFact.makeSet(c);
457 pnkfelix 1.1.2.13                     }
458 pnkfelix 1.1.2.13                 } else {
459 pnkfelix 1.1.2.13                     startedAsLin++;
460 pnkfelix 1.1.2.13                     bitSetRep = false;
461 pnkfelix 1.1.2.13                     bSet = linSetFact.makeSet(c); 
462 pnkfelix 1.1.2.13                 }
463 pnkfelix 1.1.2.13             }
464 pnkfelix 1.1.2.13             public boolean equals(Object o) {
465 pnkfelix 1.1.2.13                 if (o instanceof AugSet) {
466 pnkfelix 1.1.2.13                     return bSet.equals( ((AugSet)o).bSet );
467 pnkfelix 1.1.2.13                 } else {
468 pnkfelix 1.1.2.13                     return super.equals(o);
469 pnkfelix 1.1.2.13                 }
470 pnkfelix 1.1.2.13             }
471 pnkfelix 1.1.2.13             public int size() { return bSet.size(); }
472 pnkfelix 1.1.2.13             public Iterator iterator() { return bSet.iterator(); }
473 pnkfelix 1.1.2.13             public void clear() { bSet.clear(); }
474 pnkfelix 1.1.2.13             public boolean add(Object o) { return mayConvert(bSet.add(o)); }
475 pnkfelix 1.1.2.13             public boolean remove(Object o){return mayConvert(bSet.remove(o));}
476 pnkfelix 1.1.2.13             public boolean addAll(Collection c) { 
477 pnkfelix 1.1.2.13                 boolean b;
478 pnkfelix 1.1.2.13                 mayConvert(c.size() + bSet.size());
479 pnkfelix 1.1.2.13                 if (c instanceof AugSet) {
480 pnkfelix 1.1.2.13                     // System.out.print("AU_");
481 pnkfelix 1.1.2.13                     b = bSet.addAll( ((AugSet)c).bSet );
482 pnkfelix 1.1.2.13                     // System.out.print(size());
483 pnkfelix 1.1.2.13                 } else {
484 pnkfelix 1.1.2.13                     // System.out.print("SU_");
485 pnkfelix 1.1.2.13                     b = bSet.addAll(c); 
486 pnkfelix 1.1.2.13                     // System.out.print(size());
487 pnkfelix 1.1.2.13                 } 
488 pnkfelix 1.1.2.13                 mayConvert();
489 pnkfelix 1.1.2.13                 return b; 
490 pnkfelix 1.1.2.13             }
491 pnkfelix 1.1.2.13             public boolean removeAll(Collection c) {
492 pnkfelix 1.1.2.13                 return ((c instanceof AugSet) ?
493 pnkfelix 1.1.2.13                         bSet.removeAll(((AugSet)c).bSet):
494 pnkfelix 1.1.2.13                         bSet.removeAll(c));
495 pnkfelix 1.1.2.13             }
496 pnkfelix 1.1.2.13             public boolean retainAll(Collection c) {
497 pnkfelix 1.1.2.13                 return ((c instanceof AugSet) ?
498 pnkfelix 1.1.2.13                         bSet.retainAll(((AugSet)c).bSet):
499 pnkfelix 1.1.2.13                         bSet.retainAll(c));
500 pnkfelix 1.1.2.13             }
501 pnkfelix 1.1.2.13             
502 pnkfelix 1.1.2.13             // macro to prettify other code
503 pnkfelix 1.1.2.13             private boolean mayConvert(boolean b) {mayConvert(); return b;}
504 pnkfelix 1.1.2.13             private void mayConvert() { mayConvert(this.size()); }
505 pnkfelix 1.1.2.13             private void mayConvert(int sz) {
506 pnkfelix 1.1.2.13                 if (bitSetRep) {
507 pnkfelix 1.1.2.13                     if (sz < bitToLinThreshold) {
508 pnkfelix 1.1.2.13                         // switch to tight rep
509 pnkfelix 1.1.2.13                         bitSetRep = false;
510 pnkfelix 1.1.2.13                         bitToLinSwitches++;
511 pnkfelix 1.1.2.13                         bSet = linSetFact.makeSet(this);
512 pnkfelix 1.1.2.13                     } 
513 pnkfelix 1.1.2.13                 } else {
514 pnkfelix 1.1.2.13                     if (sz > linToBitThreshold ) {
515 pnkfelix 1.1.2.13                         // switch to bitset rep
516 pnkfelix 1.1.2.13                         bitSetRep = true;
517 pnkfelix 1.1.2.13                         linToBitSwitches++;
518 pnkfelix 1.1.2.13                         bSet = bitSetFact.makeSet(this);
519 pnkfelix 1.1.2.13                     }
520 pnkfelix 1.1.2.13                 }
521 pnkfelix 1.1.2.13             }
522 pnkfelix 1.1.2.13             
523 pnkfelix 1.1.2.13         }
524 pnkfelix 1.1.2.13         public Set makeSet(Collection c) {
525 pnkfelix 1.1.2.13             return new AugSet(c);
526 pnkfelix 1.1.2.13         }
527 pnkfelix 1.1.2.13         
528 pnkfelix 1.1.2.1      }
529 cananian 1.2      }