1 cananian 1.1.2.4  // ReachingHCodeElements.java, created Fri Dec  3  1:47:33 1999 by duncan
  2 cananian 1.1.2.4  // Copyright (C) 1998 Felix S. Klock II <pnkfelix@mit.edu>
  3 cananian 1.1.2.4  // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 duncan   1.1.2.1  package harpoon.Analysis.DataFlow;
  5 duncan   1.1.2.1  
  6 duncan   1.1.2.1  import harpoon.Analysis.BasicBlock; 
  7 salcianu 1.3      import harpoon.Analysis.BasicBlockInterf;
  8 duncan   1.1.2.1  import harpoon.ClassFile.HCodeElement; 
  9 duncan   1.1.2.1  import harpoon.IR.Properties.CFGraphable; 
 10 cananian 1.1.2.9  import harpoon.IR.Properties.UseDefable; 
 11 duncan   1.1.2.1  import harpoon.Temp.Temp; 
 12 duncan   1.1.2.1  import harpoon.Util.Util; 
 13 cananian 1.4      import net.cscott.jutil.SetFactory; 
 14 duncan   1.1.2.1  
 15 duncan   1.1.2.1  import java.util.HashMap; 
 16 duncan   1.1.2.1  import java.util.HashSet; 
 17 duncan   1.1.2.1  import java.util.Iterator; 
 18 duncan   1.1.2.1  import java.util.Map; 
 19 duncan   1.1.2.1  import java.util.Set; 
 20 duncan   1.1.2.1  
 21 duncan   1.1.2.1  /**
 22 duncan   1.1.2.1   * <code>ReachingHCodeElements</code> is an extension of 
 23 duncan   1.1.2.1   * <code>ReachingDefs</code> for performing reaching definitions analysis on 
 24 duncan   1.1.2.1   * <code>HCodeElements</code>s.  
 25 duncan   1.1.2.1   * 
 26 duncan   1.1.2.1   * @author  Felix S. Klock II <pnkfelix@mit.edu>
 27 cananian 1.1.2.10  * @author  Duncan Bryce <duncan@lcs.mit.edu>
 28 cananian 1.5       * @version $Id: ReachingHCodeElements.java,v 1.5 2004/02/08 03:19:21 cananian Exp $ 
 29 duncan   1.1.2.1   */
 30 pnkfelix 1.1.2.7  public class ReachingHCodeElements extends ReachingDefs.BBVisitor { 
 31 cananian 1.1.2.8      private BasicBlock.Factory bbfactory;
 32 duncan   1.1.2.1      private Map tempsToPrsvs;
 33 duncan   1.1.2.1      private Set universe; 
 34 duncan   1.1.2.3      private Map rdCache = new HashMap(); 
 35 duncan   1.1.2.3  
 36 duncan   1.1.2.1      
 37 duncan   1.1.2.1      /** 
 38 duncan   1.1.2.1       * Constructs a new <code>ReachingHCodeElements</code> for 
 39 cananian 1.1.2.8       * the basic blocks in the supplied <code>BasicBlock.Factory</code>.
 40 duncan   1.1.2.1       * 
 41 duncan   1.1.2.1       * <BR><B>requires:</B> 
 42 duncan   1.1.2.1       * <OL>
 43 cananian 1.1.2.8       *   <LI> <code>bbfactory</code> is a valid
 44 cananian 1.1.2.8       *        <code>BasicBlock.Factory</code>.
 45 duncan   1.1.2.1       *   <LI> All of the instructions in <code>basicBlocks</code> implement
 46 cananian 1.1.2.9       *        <code>UseDefable</code>, 
 47 duncan   1.1.2.1       * </OL>
 48 duncan   1.1.2.1       * <BR> <B>effects:</B> constructs a new <code>BasicBlockVisitor</code> 
 49 duncan   1.1.2.1       *   and initializes internal datasets for analysis of the 
 50 cananian 1.1.2.8       *   <code>BasicBlock</code>s in <code>bbfactory</code>.
 51 duncan   1.1.2.1       *
 52 cananian 1.1.2.8       * @param bbfactory <code>BasicBlock.Factory</code> of
 53 cananian 1.1.2.8       *                  <code>BasicBlock</code>s to be analyzed.
 54 duncan   1.1.2.1       */      
 55 cananian 1.1.2.8      public ReachingHCodeElements(BasicBlock.Factory bbfactory) {
 56 cananian 1.1.2.8          super(bbfactory.blocksIterator());
 57 cananian 1.1.2.8          this.bbfactory = bbfactory;
 58 duncan   1.1.2.1      }
 59 duncan   1.1.2.1      
 60 duncan   1.1.2.1      /** 
 61 duncan   1.1.2.1       * Constructs a new <code>ReachingHCodeElements</code> for 
 62 cananian 1.1.2.8       * the basic blocks in the supplied <code>BasicBlock.Factory</code>.
 63 cananian 1.1.2.8       * Allows the user to specify their own <code>SetFactory</code> for
 64 cananian 1.1.2.8       * constructing sets of <code>HCodeElements</code> in the analysis.  
 65 duncan   1.1.2.1       * 
 66 duncan   1.1.2.1       * <BR><B>requires:</B> 
 67 duncan   1.1.2.1       * <OL>
 68 cananian 1.1.2.8       *   <LI> <code>bbfactory</code> is a valid
 69 cananian 1.1.2.8       *        <code>BasicBlock.Factory</code>.
 70 duncan   1.1.2.1       *   <LI> All of the instructions in <code>basicBlocks</code> implement
 71 cananian 1.1.2.9       *        <code>UseDefable</code>, 
 72 duncan   1.1.2.1       *   <LI> All of the <code>HCodeElements</code> in <code>basicBlocks</code>
 73 duncan   1.1.2.1       *        which have non-empty def sets are members of the universe of
 74 duncan   1.1.2.1       *        <code>setFact</code>. 
 75 duncan   1.1.2.1       * </OL>
 76 duncan   1.1.2.1       * <BR> <B>effects:</B> constructs a new <code>BasicBlockVisitor</code> 
 77 duncan   1.1.2.1       *   and initializes internal datasets for analysis of the 
 78 cananian 1.1.2.8       *   <code>BasicBlock</code>s in <code>bbfactory</code>.
 79 duncan   1.1.2.1       *
 80 cananian 1.1.2.8       * @param bbfactory <code>BasicBlock.Factory</code> of
 81 cananian 1.1.2.8       *                  <code>BasicBlock</code>s to be analyzed.
 82 duncan   1.1.2.1       * @param setFact     the <code>SetFactory</code> to be used in 
 83 duncan   1.1.2.1       *                    the construction of sets of 
 84 duncan   1.1.2.1       *                    <code>HCodeElements</code>. 
 85 duncan   1.1.2.1       */      
 86 cananian 1.1.2.8      public ReachingHCodeElements(BasicBlock.Factory bbfactory,
 87 cananian 1.1.2.8                                   SetFactory setFact) {
 88 cananian 1.1.2.8          super(bbfactory.blocksIterator(), setFact);
 89 cananian 1.1.2.8          this.bbfactory = bbfactory;
 90 duncan   1.1.2.1      }
 91 duncan   1.1.2.1  
 92 duncan   1.1.2.1  
 93 duncan   1.1.2.1      /** 
 94 duncan   1.1.2.1       * Constructs a <code>Set</code> of all of the <code>HCodeElement</code>s
 95 duncan   1.1.2.1       * in <code>blocks</code> which have non-empty def sets. 
 96 duncan   1.1.2.1       * 
 97 duncan   1.1.2.1       * <BR><B>requires:</B> 
 98 duncan   1.1.2.1       * <OL>
 99 duncan   1.1.2.1       *   <LI> <code>blocks</code> is an <code>Iterator</code> of
100 duncan   1.1.2.1       *        <code>BasicBlock</code>s. 
101 duncan   1.1.2.1       *   <LI> All of the instructions in each element of <code>blocks</code> 
102 cananian 1.1.2.9       *        implement <code>UseDefable</code>. 
103 duncan   1.1.2.1       * </OL>
104 duncan   1.1.2.1       * <BR> <B>modifies:</B> <code>blocks</code>
105 duncan   1.1.2.1       * <BR> <B>effects:</B> 
106 duncan   1.1.2.1       *   Iterates through all of the instructions contained in each element 
107 duncan   1.1.2.1       *   of <code>blocks</code>, adding each instruction which has a non-empty
108 duncan   1.1.2.1       *   def set to a universe of values, returning the universe after all of 
109 duncan   1.1.2.1       *   the instructions have been visited.  Internally maintains a reference
110 duncan   1.1.2.1       *   to this computed dataset. 
111 duncan   1.1.2.1       */
112 duncan   1.1.2.1      protected Set findUniverse(Iterator blocks) { 
113 duncan   1.1.2.1          this.universe = new HashSet();
114 duncan   1.1.2.1  
115 duncan   1.1.2.1          for (; blocks.hasNext(); ) {
116 duncan   1.1.2.1              BasicBlock bb = (BasicBlock) blocks.next();
117 cananian 1.5                  for (Object udNextO : bb.statements()) { 
118 cananian 1.5                      UseDefable udNext = (UseDefable) udNextO; 
119 duncan   1.1.2.1                  if (udNext.def().length > 0) { 
120 duncan   1.1.2.1                      this.universe.add(udNext); 
121 duncan   1.1.2.1                  }
122 duncan   1.1.2.1              }
123 duncan   1.1.2.1          }
124 duncan   1.1.2.1          return this.universe; 
125 duncan   1.1.2.1      }
126 duncan   1.1.2.1  
127 duncan   1.1.2.1      /**
128 duncan   1.1.2.1       * Initializes a mapping of temps to the Set of <code>HCodeElement</code>s
129 duncan   1.1.2.1       * which  do not define them.  
130 duncan   1.1.2.1       *
131 duncan   1.1.2.1       * <BR><B>Requires:</B>
132 duncan   1.1.2.1       * <OL>
133 duncan   1.1.2.1       *   <LI> <code>blocks</code> is an <code>Iterator</code> of 
134 duncan   1.1.2.1       *        <code>BasicBlock</code>s.  
135 duncan   1.1.2.1       *   <LI> All of the instructions in each element of <code>blocks</code>
136 cananian 1.1.2.9       *        implement <code>UseDefable</code>. 
137 duncan   1.1.2.1       *   <LI> All of the <code>HCodeElements</code> in <code>basicBlocks</code>
138 duncan   1.1.2.1       *        which have non-empty def sets are members of the universe of
139 duncan   1.1.2.1       *        <code>setFact</code>. 
140 duncan   1.1.2.1       */ 
141 duncan   1.1.2.1      protected void initializeGenPrsv(Iterator blocks, SetFactory sf) { 
142 duncan   1.1.2.3          this.tempsToPrsvs = new HashMap();
143 duncan   1.1.2.1  
144 duncan   1.1.2.2          // Update the universe to use a compatible set factory. 
145 duncan   1.1.2.2          // This is usually much more efficient. 
146 duncan   1.1.2.2          this.universe = sf.makeSet(this.universe); 
147 duncan   1.1.2.2          
148 duncan   1.1.2.1          while (blocks.hasNext()) { 
149 duncan   1.1.2.1              BasicBlock bb = (BasicBlock)blocks.next(); 
150 cananian 1.5                  for (Object udNextO : bb.statements()) { 
151 cananian 1.5                      UseDefable udNext = (UseDefable) udNextO; 
152 duncan   1.1.2.1                  Temp[] defs   = udNext.def();
153 duncan   1.1.2.1                  for (int i=0, n=defs.length; i<n; ++i) {
154 duncan   1.1.2.1                      Temp t    = defs[i];
155 duncan   1.1.2.1                      Set  prsv = (Set)tempsToPrsvs.get(t); 
156 duncan   1.1.2.1                      if (prsv == null) { 
157 duncan   1.1.2.3                          tempsToPrsvs.put(t, prsv = sf.makeSet(this.universe));
158 duncan   1.1.2.1                      }
159 duncan   1.1.2.1                      prsv.remove(udNext); 
160 duncan   1.1.2.1                  }
161 duncan   1.1.2.1              }
162 duncan   1.1.2.1          }
163 duncan   1.1.2.1      }
164 duncan   1.1.2.1          
165 duncan   1.1.2.1      /** 
166 duncan   1.1.2.1       * Initializes the GEN/PRSV information for 'bb' and stores in in
167 duncan   1.1.2.1       * the returned <code>ReachingDefInfo</code>.
168 duncan   1.1.2.1       * 
169 duncan   1.1.2.1       * <BR><B>Requires:</B> 
170 duncan   1.1.2.1       *   <code>initializeGenPrsv</code> has already been called on this
171 duncan   1.1.2.1       *   <code>ReachingHCodeElements</code> object, and <code>bb</code> was
172 duncan   1.1.2.1       *   one of the blocks in the <code>Iterator</code> parameter to the last
173 duncan   1.1.2.1       *   such invocation.  
174 duncan   1.1.2.1       */
175 duncan   1.1.2.1       protected ReachingDefInfo makeGenPrsv(BasicBlock bb, SetFactory sf) { 
176 duncan   1.1.2.1          ReachingDefInfo info = new ReachingDefInfo(sf); 
177 duncan   1.1.2.1  
178 duncan   1.1.2.1          info.prsv.addAll(this.universe); 
179 duncan   1.1.2.1  
180 cananian 1.5              for (Object udNextO : bb.statements()) {
181 cananian 1.5                  UseDefable udNext = (UseDefable) udNextO; 
182 duncan   1.1.2.1              Temp[] defs   = udNext.def();
183 duncan   1.1.2.1              for (int i=0, n=defs.length; i<n; ++i) {
184 duncan   1.1.2.1                  Temp t    = defs[i];
185 duncan   1.1.2.1                  Set  prsv = (Set)tempsToPrsvs.get(t);
186 duncan   1.1.2.1                  info.prsv.retainAll(prsv); 
187 duncan   1.1.2.1                  info.gen.retainAll(prsv); 
188 duncan   1.1.2.1                  info.gen.add(udNext); 
189 duncan   1.1.2.1              }
190 duncan   1.1.2.1          }
191 duncan   1.1.2.1          return info; 
192 duncan   1.1.2.1      }
193 duncan   1.1.2.1  
194 duncan   1.1.2.1      /** 
195 duncan   1.1.2.1       * Returns the <code>Set</code> of <code>HCodeElements</code>s 
196 duncan   1.1.2.1       * which represent a definition that reaches the point directly before
197 duncan   1.1.2.1       * <code>hce</code>.  If <code>hce</code> represents more than one
198 duncan   1.1.2.1       * definition, all definitions which it represents must reach this point.
199 duncan   1.1.2.1       * Because of this, the <code>ReachingHCodeElements</code> class is
200 duncan   1.1.2.1       * most useful for intermediate representations in which each
201 duncan   1.1.2.1       * <code>HCodeElement</code> can represent only 1 definition. 
202 duncan   1.1.2.1       * 
203 duncan   1.1.2.1       * <BR><B>requires:</B> 
204 duncan   1.1.2.1       * A DataFlow Equation Solver has been run to completion on the graph 
205 duncan   1.1.2.1       * of <code>BasicBlock</code>s containing some block that contains 
206 duncan   1.1.2.1       * <code>hce</code>, with <code>this</code> as the  
207 duncan   1.1.2.1       * <code>DataFlowBasicBlockVisitor</code>. 
208 duncan   1.1.2.1       *  
209 duncan   1.1.2.1       * <BR> <B>effects:</B> 
210 duncan   1.1.2.1       * Returns a <code>Set</code> of <code>Temp</code>s that are live on 
211 duncan   1.1.2.1       * entry to <code>hce</code>. 
212 duncan   1.1.2.1       */
213 duncan   1.1.2.1      public Set getReachingBefore(HCodeElement hce) {
214 duncan   1.1.2.3  
215 duncan   1.1.2.3          if (!this.rdCache.containsKey(hce)) { 
216 cananian 1.1.2.8              BasicBlock  bb          = bbfactory.getBlock(hce);
217 duncan   1.1.2.3              Set         reachBefore = new HashSet(); 
218 duncan   1.1.2.3  
219 duncan   1.1.2.3              reachBefore.addAll(this.getReachingOnEntry(bb)); 
220 duncan   1.1.2.3  
221 duncan   1.1.2.3              // Starting from the first element in hce's basic block, traverse
222 duncan   1.1.2.3              // the block until hce is reached.  Each step updates the
223 duncan   1.1.2.3              // reaching def information.
224 cananian 1.5                  for (Object udCurrentO : bb.statements()) { 
225 cananian 1.5                      UseDefable udCurrent = (UseDefable) udCurrentO;
226 duncan   1.1.2.3                  this.rdCache.put(udCurrent, reachBefore);
227 duncan   1.1.2.3                  Temp[] defs = udCurrent.def(); 
228 duncan   1.1.2.3                  for (int n=0; n<defs.length; n++) { 
229 duncan   1.1.2.3                      reachBefore.retainAll
230 duncan   1.1.2.3                          ((Set)this.tempsToPrsvs.get(defs[n])); 
231 duncan   1.1.2.3                      reachBefore.add((HCodeElement)udCurrent); 
232 duncan   1.1.2.3                  }
233 duncan   1.1.2.1              }
234 duncan   1.1.2.1          }
235 duncan   1.1.2.1  
236 duncan   1.1.2.3          return (Set)this.rdCache.get(hce); 
237 duncan   1.1.2.1      }
238 duncan   1.1.2.1  
239 duncan   1.1.2.1      /** 
240 duncan   1.1.2.1       * Returns the <code>Set</code> of <code>HCodeElements</code>s 
241 duncan   1.1.2.1       * which represent a definition that reaches the point directly after 
242 duncan   1.1.2.1       * <code>hce</code>.  If <code>hce</code> represents more than one
243 duncan   1.1.2.1       * definition, all definitions which it represents must reach this point.
244 duncan   1.1.2.1       * Because of this, the <code>ReachingHCodeElements</code> class is
245 duncan   1.1.2.1       * most useful for intermediate representations in which each
246 duncan   1.1.2.1       * <code>HCodeElement</code> can represent only 1 definition. 
247 duncan   1.1.2.1       * 
248 duncan   1.1.2.1       * <BR><B>requires:</B> 
249 duncan   1.1.2.1       * A DataFlow Equation Solver has been run to completion on the graph 
250 duncan   1.1.2.1       * of <code>BasicBlock</code>s containing some block that contains 
251 duncan   1.1.2.1       * <code>hce</code>, with <code>this</code> as the  
252 duncan   1.1.2.1       * <code>DataFlowBasicBlockVisitor</code>. 
253 duncan   1.1.2.1       *  
254 duncan   1.1.2.1       * <BR> <B>effects:</B> 
255 duncan   1.1.2.1       * Returns a <code>Set</code> of <code>Temp</code>s that are live on 
256 duncan   1.1.2.1       * entry to <code>hce</code>. 
257 duncan   1.1.2.1       */
258 duncan   1.1.2.1      public Set getReachingAfter(HCodeElement hce) { 
259 duncan   1.1.2.1          Set reachAfter = this.getReachingBefore(hce); 
260 duncan   1.1.2.2          
261 cananian 1.1.2.9          Temp[] defs = ((UseDefable)hce).def(); 
262 duncan   1.1.2.1          for (int i=0; i<defs.length; i++) { 
263 duncan   1.1.2.1              reachAfter.retainAll((Set)this.tempsToPrsvs.get(defs[i])); 
264 duncan   1.1.2.1          }
265 duncan   1.1.2.1          reachAfter.add(hce); 
266 duncan   1.1.2.1          
267 duncan   1.1.2.1          return reachAfter; 
268 duncan   1.1.2.1      }
269 duncan   1.1.2.1  }
270 duncan   1.1.2.1  
271 cananian 1.2