1 pnkfelix 1.1.2.1 // ReachingDefsCachingImpl.java, created Thu Jul 13 13:37:11 2000 by pnkfelix 2 cananian 1.1.2.3 // 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.IR.Properties.UseDefer; 10 pnkfelix 1.1.2.1 import harpoon.IR.Quads.TYPECAST; 11 pnkfelix 1.1.2.1 import harpoon.Temp.Temp; 12 pnkfelix 1.1.2.1 13 pnkfelix 1.1.2.2 import harpoon.Util.Util; 14 cananian 1.4 import net.cscott.jutil.BitSetFactory; 15 pnkfelix 1.1.2.1 16 pnkfelix 1.1.2.1 import java.util.Collection; 17 pnkfelix 1.1.2.1 import java.util.Collections; 18 pnkfelix 1.1.2.1 import java.util.Map; 19 pnkfelix 1.1.2.2 import java.util.HashMap; 20 pnkfelix 1.1.2.2 import java.util.List; 21 pnkfelix 1.1.2.1 import java.util.Set; 22 pnkfelix 1.1.2.2 import java.util.HashSet; 23 pnkfelix 1.1.2.1 import java.util.Iterator; 24 pnkfelix 1.1.2.1 import java.util.HashMap; 25 pnkfelix 1.1.2.1 26 pnkfelix 1.1.2.1 /** 27 pnkfelix 1.1.2.1 * <code>ReachingDefsCachingImpl</code> is an extension of 28 pnkfelix 1.1.2.1 * <code>ReachingDefsImpl</code> that keeps a BasicBlock local cache 29 pnkfelix 1.1.2.1 * mapping Temp:t -> HCodeElement:h -> Set:s where s is the result of 30 pnkfelix 1.1.2.1 * calling reachingDefs(h, t). This way repeated queries in the same 31 pnkfelix 1.1.2.1 * <code>BasicBlock</code> as the last query don't have to iterate 32 pnkfelix 1.1.2.1 * over all the statements in the BasicBlock again. 33 pnkfelix 1.1.2.1 * 34 cananian 1.1.2.3 * @author Felix S. Klock II <pnkfelix@mit.edu> 35 cananian 1.5 * @version $Id: ReachingDefsCachingImpl.java,v 1.5 2004/02/08 03:19:12 cananian Exp $ 36 pnkfelix 1.1.2.1 */ 37 cananian 1.2.2.1 public class ReachingDefsCachingImpl<HCE extends HCodeElement> 38 cananian 1.2.2.1 extends ReachingDefsAltImpl<HCE> { 39 pnkfelix 1.1.2.1 40 pnkfelix 1.1.2.1 /** Tracks the last basic block a query was done on. */ 41 cananian 1.2.2.1 BasicBlock<HCE> lastBlock = null; 42 pnkfelix 1.1.2.1 43 pnkfelix 1.1.2.1 /** Maps Temp:t -> HCodeElement:h -> Set:s where s is the result 44 pnkfelix 1.1.2.1 of calling reachingDefs(h, t). 45 pnkfelix 1.1.2.1 */ 46 cananian 1.2.2.1 Map<Temp,Map<HCE,Set<HCE>>> myCache; 47 pnkfelix 1.1.2.1 48 pnkfelix 1.1.2.1 /** Creates a <code>ReachingDefsCachingImpl</code>. */ 49 cananian 1.2.2.1 public ReachingDefsCachingImpl(HCode<HCE> hc) { 50 pnkfelix 1.1.2.1 super(hc); 51 pnkfelix 1.1.2.1 } 52 pnkfelix 1.1.2.1 53 pnkfelix 1.1.2.1 /** Creates a <code>ReachingDefsCachingImpl</code>. */ 54 cananian 1.2.2.1 public ReachingDefsCachingImpl(HCode<HCE> hc, CFGrapher<HCE> c) { 55 pnkfelix 1.1.2.1 super(hc, c); 56 pnkfelix 1.1.2.1 } 57 pnkfelix 1.1.2.1 58 pnkfelix 1.1.2.1 /** Creates a <code>ReachingDefsCachingImpl</code>. */ 59 cananian 1.2.2.1 public ReachingDefsCachingImpl(HCode<HCE> hc, CFGrapher<HCE> c, UseDefer<HCE> ud) { 60 pnkfelix 1.1.2.1 super(hc, c, ud); 61 pnkfelix 1.1.2.1 } 62 pnkfelix 1.1.2.1 63 pnkfelix 1.1.2.1 /** Returns the Set of <code>HCodeElement</code>s providing definitions 64 pnkfelix 1.1.2.1 * of <code>Temp</code> <code>t</code> which reach 65 pnkfelix 1.1.2.1 * <code>HCodeElement</code> <code>hce</code>. 66 pnkfelix 1.1.2.1 */ 67 cananian 1.2.2.1 public Set<HCE> reachingDefs(HCE hce, Temp t) { 68 pnkfelix 1.1.2.1 // find out which BasicBlock this HCodeElement is from 69 cananian 1.2.2.1 BasicBlock<HCE> b = bbf.getBlock(hce); 70 pnkfelix 1.1.2.1 if (b == lastBlock) { 71 pnkfelix 1.1.2.2 // System.out.print(" _"+b.statements().size()); 72 pnkfelix 1.1.2.1 if (myCache.keySet().contains(t)) 73 cananian 1.2.2.1 return myCache.get(t).get(hce); 74 pnkfelix 1.1.2.1 } else { 75 pnkfelix 1.1.2.2 // System.out.print(" M"+b.statements().size()); 76 cananian 1.2.2.1 myCache = new HashMap<Temp,Map<HCE,Set<HCE>>>(); 77 pnkfelix 1.1.2.2 lastBlock = b; 78 pnkfelix 1.1.2.1 } 79 pnkfelix 1.1.2.1 80 cananian 1.2.2.1 Map<HCE,Set<HCE>> hceToResults = new HashMap<HCE,Set<HCE>>(); 81 pnkfelix 1.1.2.1 myCache.put(t, hceToResults); 82 pnkfelix 1.1.2.1 83 pnkfelix 1.1.2.1 // get the map for the BasicBlock 84 cananian 1.2.2.1 Record r = cache.get(b); 85 pnkfelix 1.1.2.2 86 pnkfelix 1.1.2.2 // find HCodeElements associated with `t' in the IN Set 87 pnkfelix 1.1.2.2 Set results = bsf.makeSet(r.IN); 88 cananian 1.2.2.1 results.retainAll( tempToAllDefs.get(t) ); 89 pnkfelix 1.1.2.2 90 pnkfelix 1.1.2.2 Iterator pairs = results.iterator(); 91 pnkfelix 1.1.2.2 results = new HashSet(); 92 pnkfelix 1.1.2.2 while(pairs.hasNext()) { 93 pnkfelix 1.1.2.2 results.add( ((List)pairs.next()).get(1) ); 94 pnkfelix 1.1.2.2 } 95 pnkfelix 1.1.2.2 96 pnkfelix 1.1.2.1 // propagate in Set through the HCodeElements 97 pnkfelix 1.1.2.1 // of the BasicBlock in correct order 98 pnkfelix 1.1.2.2 // report("Propagating..."); 99 cananian 1.5 for(HCE curr : b.statements()) { 100 pnkfelix 1.1.2.1 hceToResults.put(curr, results); 101 pnkfelix 1.1.2.1 102 cananian 1.2.2.1 Collection<Temp> defC = null; 103 pnkfelix 1.1.2.1 // special treatment of TYPECAST 104 pnkfelix 1.1.2.1 if(check_typecast && (curr instanceof TYPECAST)) 105 pnkfelix 1.1.2.1 defC = Collections.singleton(((TYPECAST)curr).objectref()); 106 pnkfelix 1.1.2.1 else 107 pnkfelix 1.1.2.1 defC = ud.defC(curr); 108 pnkfelix 1.1.2.2 109 pnkfelix 1.1.2.1 if (defC.contains(t)) 110 pnkfelix 1.1.2.2 results = Collections.singleton(curr); 111 pnkfelix 1.1.2.1 } 112 pnkfelix 1.1.2.1 113 cananian 1.2.2.1 return hceToResults.get(hce); 114 pnkfelix 1.1.2.1 } 115 cananian 1.2 }