1 cananian 1.1.2.11 // ReachingDefs.java, created Wed Mar 10 9:00:54 1999 by jwhaley 2 cananian 1.1.2.19 // Copyright (C) 1998 John Whaley <jwhaley@alum.mit.edu> 3 cananian 1.1.2.10 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 jwhaley 1.1.2.1 package harpoon.Analysis.DataFlow; 5 jwhaley 1.1.2.1 6 jwhaley 1.1.2.1 7 pnkfelix 1.1.2.12 import harpoon.Analysis.BasicBlock; 8 salcianu 1.3 import harpoon.Analysis.BasicBlockInterf; 9 pnkfelix 1.1.2.3 import harpoon.ClassFile.HCodeElement; 10 cananian 1.1.2.18 import harpoon.IR.Properties.UseDefable; 11 jwhaley 1.1.2.1 import harpoon.Temp.Temp; 12 duncan 1.1.2.15 import harpoon.Util.CloneableIterator; 13 pnkfelix 1.1.2.13 import harpoon.Util.Util; 14 cananian 1.5 import net.cscott.jutil.BitSetFactory; 15 cananian 1.5 import net.cscott.jutil.SetFactory; 16 pnkfelix 1.1.2.13 17 duncan 1.1.2.15 import java.util.HashMap; 18 duncan 1.1.2.15 import java.util.HashSet; 19 duncan 1.1.2.15 import java.util.Iterator; 20 duncan 1.1.2.15 import java.util.Map; 21 duncan 1.1.2.15 import java.util.Set; 22 pnkfelix 1.1.2.9 23 duncan 1.1.2.15 /** 24 duncan 1.1.2.15 * <code>ReachingDefs</code> is a <code>ForwardDataFlowBasicBlockVisitor</code> 25 duncan 1.1.2.15 * for performing reaching definitions analysis on any IR that implements 26 duncan 1.1.2.15 * <code>HCodeElement</code>, <code>CFGraphable</code>, and 27 cananian 1.1.2.18 * <code>UseDefable</code>. 28 duncan 1.1.2.15 * 29 cananian 1.1.2.19 * @author John Whaley <jwhaley@alum.mit.edu> 30 cananian 1.1.2.19 * @author Felix S. Klock II <pnkfelix@mit.edu> 31 duncan 1.1.2.15 * @author Duncan Bryce <duncan@lcs.mit.edu> 32 cananian 1.6 * @version $Id: ReachingDefs.java,v 1.6 2004/02/08 03:19:21 cananian Exp $ 33 duncan 1.1.2.15 */ 34 pnkfelix 1.1.2.17 public abstract class ReachingDefs { 35 pnkfelix 1.1.2.17 36 duncan 1.1.2.15 private static final boolean DEBUG = false; 37 pnkfelix 1.1.2.17 38 duncan 1.1.2.15 39 pnkfelix 1.1.2.17 40 pnkfelix 1.1.2.17 abstract static class BBVisitor extends ForwardDataFlowBasicBlockVisitor { 41 pnkfelix 1.1.2.17 42 pnkfelix 1.1.2.17 private Map bbToRdi; 43 pnkfelix 1.1.2.17 44 duncan 1.1.2.15 /** 45 duncan 1.1.2.15 * Constructs a new <code>ReachingDefs</code> for <code>basicblocks</code>. 46 duncan 1.1.2.15 * 47 duncan 1.1.2.15 * <BR><B>requires:</B> 48 duncan 1.1.2.15 * <OL> 49 duncan 1.1.2.15 * <LI> <code>basicBlocks</code> is an <code>Iterator</code> of 50 duncan 1.1.2.15 * <code>BasicBlock</code>s, 51 duncan 1.1.2.15 * <LI> All of the instructions in <code>basicBlocks</code> implement 52 cananian 1.1.2.18 * <code>UseDefable</code>, 53 duncan 1.1.2.15 * <LI> No element of <code>basicblocks</code> links to a 54 duncan 1.1.2.15 * <code>BasicBlock</code> not contained within 55 duncan 1.1.2.15 * <code>basicBlocks</code>, 56 duncan 1.1.2.15 * <LI> No <code>BasicBlock</code> is repeatedly iterated 57 duncan 1.1.2.15 * by <code>basicBlocks</code> 58 duncan 1.1.2.15 * </OL> 59 duncan 1.1.2.15 * <BR> <B>modifies:</B> <code>basicBlocks</code> 60 duncan 1.1.2.15 * <BR> <B>effects:</B> constructs a new <code>BasicBlockVisitor</code> 61 duncan 1.1.2.15 * and initializes internal datasets for analysis of the 62 duncan 1.1.2.15 * <code>BasicBlock</code>s in <code>basicBlocks</code>, iterating over 63 duncan 1.1.2.15 * all of <code>basicBlocks</code> in the process. 64 duncan 1.1.2.15 * 65 duncan 1.1.2.15 * @param basicBlocks <code>Iterator</code> of <code>BasicBlock</code>s 66 duncan 1.1.2.15 * to be analyzed. 67 duncan 1.1.2.15 */ 68 pnkfelix 1.1.2.17 public BBVisitor(Iterator basicblocks) { 69 duncan 1.1.2.15 CloneableIterator blocks = new CloneableIterator(basicblocks); 70 duncan 1.1.2.15 Set universe = findUniverse((Iterator) blocks.clone()); 71 duncan 1.1.2.15 SetFactory setFact = new BitSetFactory(universe); 72 duncan 1.1.2.15 73 duncan 1.1.2.15 this.initializeGenPrsv( (Iterator)blocks.clone(), setFact ); 74 duncan 1.1.2.15 this.initializeBBtoRDI( blocks, setFact ); 75 duncan 1.1.2.15 } 76 pnkfelix 1.1.2.6 77 duncan 1.1.2.15 /** 78 duncan 1.1.2.15 * Constructs a new <code>ReachingDefs</code> for 79 duncan 1.1.2.15 * <code>basicblocks</code>. Allows the user to specify their own 80 duncan 1.1.2.15 * <code>SetFactory</code> for constructing sets of definitions in the 81 duncan 1.1.2.15 * analysis. 82 duncan 1.1.2.15 * 83 duncan 1.1.2.15 * <BR><B>requires:</B> 84 duncan 1.1.2.15 * <OL> 85 duncan 1.1.2.15 * <LI> <code>basicBlocks</code> is an <code>Iterator</code> of 86 duncan 1.1.2.15 * <code>BasicBlock</code>s, 87 duncan 1.1.2.15 * <LI> All of the instructions in <code>basicBlocks</code> implement 88 cananian 1.1.2.18 * <code>UseDefable</code>, 89 duncan 1.1.2.15 * <LI> No element of <code>basicblocks</code> links to a 90 duncan 1.1.2.15 * <code>BasicBlock</code> not contained within 91 duncan 1.1.2.15 * <code>basicBlocks</code>, 92 duncan 1.1.2.15 * <LI> No <code>BasicBlock</code> is repeatedly iterated 93 duncan 1.1.2.15 * by <code>basicBlocks</code> 94 duncan 1.1.2.15 * </OL> 95 duncan 1.1.2.15 * <BR> <B>modifies:</B> <code>basicBlocks</code> 96 duncan 1.1.2.15 * <BR> <B>effects:</B> constructs a new <code>BasicBlockVisitor</code> 97 duncan 1.1.2.15 * and initializes internal datasets for analysis of the 98 duncan 1.1.2.15 * <code>BasicBlock</code>s in <code>basicBlocks</code>, iterating over 99 duncan 1.1.2.15 * all of <code>basicBlocks</code> in the process. 100 duncan 1.1.2.15 * 101 duncan 1.1.2.15 * @param basicBlocks <code>Iterator</code> of <code>BasicBlock</code>s 102 duncan 1.1.2.15 * to be analyzed. 103 duncan 1.1.2.15 * @param setFact the <code>SetFactory</code> to be used in 104 duncan 1.1.2.15 * the construction of sets of definitions. 105 duncan 1.1.2.15 */ 106 pnkfelix 1.1.2.17 public BBVisitor(Iterator basicblocks, SetFactory setFact) { 107 duncan 1.1.2.15 CloneableIterator blocks = new CloneableIterator(basicblocks); 108 jwhaley 1.1.2.1 109 duncan 1.1.2.15 initializeBBtoRDI( blocks, setFact ); 110 pnkfelix 1.1.2.3 } 111 pnkfelix 1.1.2.3 112 duncan 1.1.2.15 /** 113 duncan 1.1.2.15 * Initializes an internal mapping of <code>BasicBlock</code>s to 114 duncan 1.1.2.15 * <code>ReachingDefInfo</code>s. 115 duncan 1.1.2.15 */ 116 duncan 1.1.2.15 protected void initializeBBtoRDI(Iterator blocks, SetFactory setFact) { 117 duncan 1.1.2.15 bbToRdi = new HashMap(); 118 duncan 1.1.2.15 119 duncan 1.1.2.15 while(blocks.hasNext()) { 120 duncan 1.1.2.15 BasicBlock bb = (BasicBlock) blocks.next(); 121 duncan 1.1.2.15 ReachingDefInfo rdi = makeGenPrsv(bb, setFact); 122 duncan 1.1.2.15 bbToRdi.put(bb, rdi); 123 pnkfelix 1.1.2.6 } 124 pnkfelix 1.1.2.6 } 125 duncan 1.1.2.15 126 duncan 1.1.2.15 /** 127 duncan 1.1.2.15 * Merge (Confluence) operator. 128 duncan 1.1.2.15 * <BR> RDin(bb) = Union over (j elem Pred(bb)) of ( RDout(j) ) 129 duncan 1.1.2.15 * <code>from</code> corresponds to a member of Pred('bb'). It 130 duncan 1.1.2.15 * is the responsibility of the DataFlow Equation Solver to run 131 duncan 1.1.2.15 * <code>merge</code> on all of the Pred('bb') 132 duncan 1.1.2.15 * 133 duncan 1.1.2.15 * <BR> This method isn't meant to be called by application code; 134 duncan 1.1.2.15 * instead, look at one of the DataFlow Equation Solvers in 135 duncan 1.1.2.15 * the <code>harpoon.Analysis.DataFlow</code> package. 136 duncan 1.1.2.15 * <BR> <B>requires:</B> 137 duncan 1.1.2.15 * <code>child</code> and <code>parent</code> are contained in 138 duncan 1.1.2.15 * <code>this</code> 139 duncan 1.1.2.15 * <BR> <B>effects:</B> 140 duncan 1.1.2.15 * Updates the internal information associated with <code>to</code> to 141 duncan 1.1.2.15 * include information associated with <code>from</code>. 142 duncan 1.1.2.15 */ 143 salcianu 1.3 public boolean merge(BasicBlockInterf from, BasicBlockInterf to) { 144 duncan 1.1.2.15 ReachingDefInfo fInfo = (ReachingDefInfo)this.bbToRdi.get(from); 145 duncan 1.1.2.15 ReachingDefInfo tInfo = (ReachingDefInfo)this.bbToRdi.get(to); 146 duncan 1.1.2.15 boolean result = tInfo.rdIN.addAll(fInfo.rdOUT); 147 duncan 1.1.2.15 148 duncan 1.1.2.15 if (DEBUG) 149 duncan 1.1.2.15 System.out.println 150 duncan 1.1.2.15 ("merge( from: " + from +" to: "+ to +" ) \n" + 151 duncan 1.1.2.15 from + ".rdOut: "+ fInfo.rdOUT + "\n" + 152 duncan 1.1.2.15 to + ".rdIN: "+ tInfo.rdIN + "\n"); 153 pnkfelix 1.1.2.6 154 pnkfelix 1.1.2.6 return result; 155 pnkfelix 1.1.2.6 } 156 pnkfelix 1.1.2.6 157 duncan 1.1.2.15 /** 158 duncan 1.1.2.15 * Visit (Transfer) function. 159 duncan 1.1.2.15 * <BR> RDout(bb) = ( RDin(bb) intersection PRSV(bb) ) union GEN(bb) 160 duncan 1.1.2.15 */ 161 duncan 1.1.2.15 public void visit(BasicBlock b) { 162 duncan 1.1.2.15 ReachingDefInfo info = (ReachingDefInfo)bbToRdi.get(b); 163 duncan 1.1.2.15 info.rdOUT.clear(); 164 duncan 1.1.2.15 info.rdOUT.addAll(info.rdIN); 165 duncan 1.1.2.15 info.rdOUT.retainAll(info.prsv); 166 duncan 1.1.2.15 info.rdOUT.addAll(info.gen); 167 duncan 1.1.2.15 168 duncan 1.1.2.15 if (DEBUG) 169 duncan 1.1.2.15 System.out.println 170 duncan 1.1.2.15 ("visit( " + b + "):\n " + 171 duncan 1.1.2.15 b + ".LiveOut: " + info.rdOUT + "\n" + 172 duncan 1.1.2.15 b + ".LiveIn: " + info.rdIN + "\n"); 173 jwhaley 1.1.2.1 174 pnkfelix 1.1.2.6 } 175 duncan 1.1.2.15 176 duncan 1.1.2.15 /** 177 duncan 1.1.2.15 * Constructs a <code>Set</code> of all of the referenced definitions in 178 duncan 1.1.2.15 * <code>blocks</code>. 179 duncan 1.1.2.15 * 180 duncan 1.1.2.15 * For example, in some analyses this universe will be made up of 181 duncan 1.1.2.15 * all of the <code>HCodeElement</code>s referenced in 182 duncan 1.1.2.15 * <code>blocks</code>. However, for flexibility I have allowed 183 duncan 1.1.2.15 * users to define their own universe of values. 184 duncan 1.1.2.15 */ 185 duncan 1.1.2.15 protected abstract Set findUniverse(Iterator blocks); 186 duncan 1.1.2.15 187 duncan 1.1.2.15 /** 188 duncan 1.1.2.15 * Performs initialization necessary to calculate GEN/PRSV sets. 189 duncan 1.1.2.15 * 190 duncan 1.1.2.15 * For example, this might consist of constructing a mapping of 191 duncan 1.1.2.15 * <code>Temp</code>s to <code>HCodeElement</code>s which do not define 192 duncan 1.1.2.15 * them. 193 duncan 1.1.2.15 */ 194 duncan 1.1.2.15 protected abstract void initializeGenPrsv(Iterator blocks, SetFactory sf); 195 pnkfelix 1.1.2.6 196 duncan 1.1.2.15 /** 197 duncan 1.1.2.15 * Initializes the GEN/PRSV information for bb and stores it in 198 duncan 1.1.2.15 * the returned <code>ReachingDefInfo</code>. An example implementation 199 duncan 1.1.2.15 * would use <code>HCodeElement</code>s to make up their 200 duncan 1.1.2.15 * <code>ReachingDefInfo</code>s. 201 duncan 1.1.2.15 */ 202 duncan 1.1.2.15 protected abstract ReachingDefInfo makeGenPrsv(BasicBlock bb, SetFactory sf); 203 duncan 1.1.2.15 204 duncan 1.1.2.15 /** 205 duncan 1.1.2.15 * Returns the <code>Set</code> of definitions that reach the exit of 206 duncan 1.1.2.15 * <code>b</code>. 207 duncan 1.1.2.15 * 208 duncan 1.1.2.15 * <BR> <B>requires:</B> A DataFlow Equation Solver has been run to 209 duncan 1.1.2.15 * completion on the graph of <code>BasicBlock</code>s containing 210 duncan 1.1.2.15 * <code>b</code> with <code>this</code> as the 211 duncan 1.1.2.15 * <code>DataFlowBasicBlockVisitor</code>. 212 duncan 1.1.2.15 */ 213 duncan 1.1.2.15 public Set getReachingOnEntry(BasicBlock b) { 214 duncan 1.1.2.15 ReachingDefInfo rdi = (ReachingDefInfo) bbToRdi.get(b); 215 duncan 1.1.2.15 return rdi.rdIN; 216 pnkfelix 1.1.2.6 } 217 duncan 1.1.2.15 218 duncan 1.1.2.15 /** 219 duncan 1.1.2.15 * Returns the <code>Set</code> of definitions that reach the exit of 220 duncan 1.1.2.15 * <code>b</code>. 221 duncan 1.1.2.15 * 222 duncan 1.1.2.15 * <BR> <B>requires:</B> A DataFlow Equation Solver has been run to 223 duncan 1.1.2.15 * completion on the graph of <code>BasicBlock</code>s containing 224 duncan 1.1.2.15 * <code>b</code> with <code>this</code> as the 225 duncan 1.1.2.15 * <code>DataFlowBasicBlockVisitor</code>. 226 duncan 1.1.2.15 */ 227 duncan 1.1.2.15 public Set getReachingOnExit(BasicBlock b) { 228 duncan 1.1.2.15 ReachingDefInfo rdi = (ReachingDefInfo) bbToRdi.get(b); 229 duncan 1.1.2.15 return rdi.rdOUT; 230 duncan 1.1.2.15 } 231 duncan 1.1.2.15 232 pnkfelix 1.1.2.6 public String dump() { 233 pnkfelix 1.1.2.6 StringBuffer s = new StringBuffer(); 234 cananian 1.6 for (Object bbO : this.bbToRdi.keySet()) { 235 cananian 1.6 BasicBlock bb = (BasicBlock) bbO; 236 pnkfelix 1.1.2.6 s.append("Basic block "+bb); 237 duncan 1.1.2.15 ReachingDefInfo rdi = (ReachingDefInfo)this.bbToRdi.get(bb); 238 pnkfelix 1.1.2.6 s.append("\n"+rdi); 239 pnkfelix 1.1.2.6 } 240 pnkfelix 1.1.2.6 return s.toString(); 241 pnkfelix 1.1.2.6 } 242 duncan 1.1.2.15 243 duncan 1.1.2.15 // ReachingDefInfo is a record type grouping together four sets: 244 duncan 1.1.2.15 // gen(bb): set of definitions in 'bb' which are not subsequently killed 245 duncan 1.1.2.15 // in 'bb'. 246 duncan 1.1.2.15 // prsv(bb): set of definitions in 'bb' which are not killed in 'bb'. 247 duncan 1.1.2.15 // rdIN(bb): Union over (j elem Pred(bb)) of ( rdOUT(j) ) 248 duncan 1.1.2.15 // rdOUT(bb): ( rdIN(bb) intersection prsv(bb) ) union ( gen(bb) ) 249 duncan 1.1.2.15 // 250 duncan 1.1.2.15 protected static class ReachingDefInfo { 251 duncan 1.1.2.15 public Set gen; 252 duncan 1.1.2.15 public Set prsv; 253 duncan 1.1.2.15 public Set rdIN; 254 duncan 1.1.2.15 public Set rdOUT; 255 duncan 1.1.2.15 256 duncan 1.1.2.15 ReachingDefInfo(SetFactory sf) { 257 duncan 1.1.2.15 gen = sf.makeSet(); 258 duncan 1.1.2.15 prsv = sf.makeSet(); 259 duncan 1.1.2.15 rdIN = sf.makeSet(); 260 duncan 1.1.2.15 rdOUT = sf.makeSet(); 261 duncan 1.1.2.15 } 262 duncan 1.1.2.15 263 duncan 1.1.2.15 public String toString() { 264 duncan 1.1.2.15 StringBuffer s = new StringBuffer(); 265 duncan 1.1.2.15 Iterator iter; 266 duncan 1.1.2.15 s.append("\tGEN set: " ); 267 duncan 1.1.2.15 iter = gen.iterator(); 268 duncan 1.1.2.15 while(iter.hasNext()) { s.append(iter.next() + " "); } 269 duncan 1.1.2.15 s.append("\n"); 270 duncan 1.1.2.15 271 duncan 1.1.2.15 s.append("\tPRSV set: " ); 272 duncan 1.1.2.15 iter = prsv.iterator(); 273 duncan 1.1.2.15 while(iter.hasNext()) { s.append(iter.next() + " "); } 274 duncan 1.1.2.15 s.append("\n"); 275 duncan 1.1.2.15 276 duncan 1.1.2.15 s.append("\tRDin set: " ); 277 duncan 1.1.2.15 iter = rdIN.iterator(); 278 duncan 1.1.2.15 while(iter.hasNext()) { s.append(iter.next() + " "); } 279 duncan 1.1.2.15 s.append("\n"); 280 duncan 1.1.2.15 281 duncan 1.1.2.15 s.append("\tRDout set: " ); 282 duncan 1.1.2.15 iter = rdOUT.iterator(); 283 duncan 1.1.2.15 while(iter.hasNext()) { s.append(iter.next() + " "); } 284 duncan 1.1.2.15 s.append("\n"); 285 duncan 1.1.2.15 286 duncan 1.1.2.15 return s.toString(); 287 duncan 1.1.2.15 } 288 pnkfelix 1.1.2.17 } 289 duncan 1.1.2.15 } 290 jwhaley 1.1.2.1 } 291 cananian 1.2