1 salcianu 1.1  // PointerAnalysisCompStage.java, created Thu Apr 17 15:24:32 2003 by salcianu
  2 salcianu 1.1  // Copyright (C) 2003 Alexandru Salcianu <salcianu@MIT.EDU>
  3 salcianu 1.1  // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 salcianu 1.1  package harpoon.Analysis.PointerAnalysis;
  5 salcianu 1.1  
  6 salcianu 1.1  import harpoon.ClassFile.CachingCodeFactory;
  7 salcianu 1.2  import harpoon.ClassFile.HClass;
  8 salcianu 1.2  import harpoon.ClassFile.NoSuchClassException;
  9 salcianu 1.3  import harpoon.ClassFile.HMethod;
 10 salcianu 1.3  import harpoon.ClassFile.HCode;
 11 salcianu 1.3  import harpoon.ClassFile.HCodeFactory;
 12 salcianu 1.3  import harpoon.ClassFile.Linker;
 13 salcianu 1.3  
 14 salcianu 1.3  import harpoon.IR.Quads.Code;
 15 salcianu 1.3  import harpoon.IR.Quads.QuadNoSSA;
 16 salcianu 1.3  import harpoon.IR.Quads.Quad;
 17 salcianu 1.3  import harpoon.IR.Quads.CALL;
 18 salcianu 1.3  
 19 salcianu 1.3  import harpoon.Analysis.Quads.CallGraph;
 20 salcianu 1.3  import harpoon.Analysis.Quads.CallGraphImpl;
 21 salcianu 1.3  import harpoon.Analysis.Quads.CachingCallGraph;
 22 salcianu 1.3  import harpoon.Analysis.ClassHierarchy;
 23 salcianu 1.3  
 24 salcianu 1.3  import harpoon.Analysis.MetaMethods.MetaCallGraph;
 25 salcianu 1.3  import harpoon.Analysis.MetaMethods.MetaMethod;
 26 salcianu 1.3  import harpoon.Analysis.MetaMethods.FakeMetaCallGraph;
 27 salcianu 1.3  import harpoon.Analysis.MetaMethods.SmartCallGraph;
 28 salcianu 1.3  
 29 salcianu 1.3  import harpoon.Util.LightBasicBlocks.CachingLBBConverter;
 30 salcianu 1.3  import harpoon.Util.LightBasicBlocks.CachingSCCLBBFactory;
 31 salcianu 1.3  import harpoon.Util.BasicBlocks.CachingBBConverter;
 32 salcianu 1.3  
 33 salcianu 1.4  import harpoon.Main.CompilerStage;
 34 salcianu 1.3  import harpoon.Main.CompilerStageEZ;
 35 salcianu 1.4  import harpoon.Main.CompStagePipeline;
 36 salcianu 1.3  import harpoon.Main.CompilerState;
 37 salcianu 1.3  import harpoon.Util.Options.Option;
 38 salcianu 1.3  import harpoon.Util.Util;
 39 salcianu 1.3  
 40 salcianu 1.3  import java.util.List;
 41 salcianu 1.3  import java.util.LinkedList;
 42 salcianu 1.3  import java.util.Set;
 43 salcianu 1.3  import java.util.HashSet;
 44 salcianu 1.3  import java.util.Iterator;
 45 salcianu 1.3  import java.util.Collection;
 46 salcianu 1.3  
 47 salcianu 1.3  import java.io.Serializable;
 48 salcianu 1.3  import java.io.IOException;
 49 salcianu 1.3  import java.io.FileInputStream;
 50 salcianu 1.3  import java.io.ObjectInputStream;
 51 salcianu 1.3  import java.io.FileOutputStream;
 52 salcianu 1.3  import java.io.ObjectOutputStream;
 53 salcianu 1.3  import java.io.BufferedReader;
 54 salcianu 1.3  import java.io.InputStreamReader;
 55 salcianu 1.3  
 56 salcianu 1.3  /**
 57 salcianu 1.3   * <code>PointerAnalysisCompStage</code>
 58 salcianu 1.3   * 
 59 salcianu 1.3   * @author  Alexandru Salcianu <salcianu@MIT.EDU>
 60 salcianu 1.10  * @version $Id: PointerAnalysisCompStage.java,v 1.10 2004/03/05 22:18:14 salcianu Exp $
 61 salcianu 1.3   */
 62 salcianu 1.3  public class PointerAnalysisCompStage extends CompilerStageEZ {
 63 salcianu 1.3  
 64 salcianu 1.4      /** Returns a compiler stage that is the sequential composition of
 65 salcianu 1.4          a Pointer Analysis Construction stage
 66 salcianu 1.4          (<code>PointerAnalysisCompStage</code>), a stage that uese
 67 salcianu 1.4          pointer analysis information for allocation optimizations and
 68 salcianu 1.4          synchronization removal (<code>AllocSyncOptCompStage</code>,
 69 salcianu 1.4          and a stage that offers support for debugging and optimizing
 70 salcianu 1.4          RTJ programs (<code>PARTJSupportCompStage</code>).
 71 salcianu 1.4  
 72 salcianu 1.4          @see PointerAnalysisCompStage
 73 salcianu 1.4          @see AllocSyncOptCompStage
 74 salcianu 1.4          @see PARTJSupportCompStage. */
 75 salcianu 1.4      public static CompilerStage getPAAndAppsStage() {
 76 cananian 1.8          List<CompilerStage> paStages = new LinkedList<CompilerStage>();
 77 salcianu 1.4  
 78 salcianu 1.10         final PointerAnalysisCompStage paStage = 
 79 salcianu 1.10             new PointerAnalysisCompStage(true);
 80 salcianu 1.10         paStages.add(paStage);
 81 salcianu 1.4  
 82 salcianu 1.4          final CompilerStage allocSyncOpt = new AllocSyncOptCompStage();
 83 salcianu 1.4          paStages.add(allocSyncOpt);
 84 salcianu 1.4  
 85 salcianu 1.4          final CompilerStage rtjSupport = new PARTJSupportCompStage();
 86 salcianu 1.4          paStages.add(rtjSupport);
 87 salcianu 1.4  
 88 salcianu 1.4          return new CompStagePipeline(paStages, "pa-and-applications") {
 89 salcianu 1.4              public boolean enabled() {
 90 salcianu 1.10                 return 
 91 salcianu 1.10                     paStage.selfEnabled() || 
 92 salcianu 1.10                     allocSyncOpt.enabled() || 
 93 salcianu 1.10                     rtjSupport.enabled();
 94 salcianu 1.4              }
 95 salcianu 1.4          };
 96 salcianu 1.4      }
 97 salcianu 1.4  
 98 salcianu 1.3      /** Creates a <code>PointerAnalysisCompStage</code> object. 
 99 salcianu 1.3  
100 salcianu 1.3          @param extEnabled If <code>true</code>, <code>this</code>
101 salcianu 1.3          compiler stage is enabled even if no direct task is indicated
102 salcianu 1.3          in the command line options.  In general, this corresponds to
103 salcianu 1.3          the case where the <code>PointerAnalysis</code> object created
104 salcianu 1.3          here is required by a later stage. */
105 salcianu 1.3      public PointerAnalysisCompStage(boolean extEnabled) { 
106 salcianu 1.3          super("pointer-analysis");
107 salcianu 1.3          this.extEnabled = extEnabled;
108 salcianu 1.3      }
109 salcianu 1.3  
110 salcianu 1.3      /** Convenient constructor: the created compiler stage is not
111 salcianu 1.3          externally enabled. */
112 salcianu 1.3      public PointerAnalysisCompStage() { this(false); }
113 salcianu 1.3      
114 salcianu 1.3      
115 cananian 1.8      public List<Option> getOptions() {
116 cananian 1.8          List<Option> opts = new LinkedList<Option>();
117 salcianu 1.3          
118 salcianu 1.7          opts.add(new Option("pa:s", "Use SmartCallGraph (more precise than the default callgraph, but really slow)") {
119 salcianu 1.7              public void action() { SMART_CALL_GRAPH = true; }
120 salcianu 1.3          });
121 salcianu 1.3          
122 salcianu 1.3          opts.add(new Option("pa:load-pre-analysis", "<fileName>",
123 salcianu 1.3                              "Deserialize pre-analysis results from a file") {
124 salcianu 1.3              public void action() {
125 salcianu 1.3                  LOAD_PRE_ANALYSIS = true;
126 salcianu 1.3                  preAnalysisFileName = getArg(0);
127 salcianu 1.3              }
128 salcianu 1.3          });
129 salcianu 1.3          
130 salcianu 1.3          opts.add(new Option("pa:save-pre-analysis", "<fileName>",
131 salcianu 1.3                              "Serialize pre-analysis results into a file") {
132 salcianu 1.3              public void action() {
133 salcianu 1.3                  SAVE_PRE_ANALYSIS = true;
134 salcianu 1.3                  preAnalysisFileName = getArg(0);
135 salcianu 1.3              }
136 salcianu 1.3          });
137 salcianu 1.3          
138 salcianu 1.3          opts.add(new Option("pa:ccs", "<level>",
139 salcianu 1.3                              "Pointer analysis call context sensitivity (default none)") {
140 salcianu 1.3              public void action() {
141 salcianu 1.3                  PointerAnalysis.CALL_CONTEXT_SENSITIVE = true;
142 salcianu 1.3                  PointerAnalysis.MAX_SPEC_DEPTH = Integer.parseInt(getArg(0));
143 salcianu 1.3              }
144 salcianu 1.3          });
145 salcianu 1.3  
146 salcianu 1.3          opts.add(new Option("pa:record-actions", "Record thread actions") {
147 salcianu 1.3              public void action() { PointerAnalysis.RECORD_ACTIONS = true; }
148 salcianu 1.3          });
149 salcianu 1.3   
150 salcianu 1.3          if(Boolean.getBoolean("debug.pa"))
151 salcianu 1.3              add_debug_options(opts);
152 salcianu 1.3          
153 salcianu 1.3          return opts;
154 salcianu 1.3      }
155 salcianu 1.3      
156 salcianu 1.3      
157 salcianu 1.3      private void add_debug_options(List opts) {
158 salcianu 1.4          opts.add(new Option("pa:timing", 
159 salcianu 1.4                              "Time pre-analysis for Pointer Analysis") {
160 salcianu 1.3              public void action() { TIMING = true; }
161 salcianu 1.3          });
162 salcianu 1.3          
163 salcianu 1.3          opts.add(new Option("pa:show-cg", "Show Call Graph") {
164 salcianu 1.3              public void action() { SHOW_CG = true; }
165 salcianu 1.3          });
166 salcianu 1.3          
167 salcianu 1.3          opts.add(new Option("pa:a", "<method>", "<detail>", 
168 salcianu 1.3                              "Run Pointer Analysis over one method; if optional argument <detail> is present, the result of analysis is shown for each program point inside the method.") {
169 salcianu 1.3              public void action() {
170 salcianu 1.3                  DO_ANALYSIS = true;
171 salcianu 1.3                  if(methodsToAnalyze == null)
172 salcianu 1.10                     methodsToAnalyze = new LinkedList();
173 salcianu 1.3                  methodsToAnalyze.add(getArg(0));
174 salcianu 1.3                  if(getOptionalArg(0) != null)
175 salcianu 1.3                      INTERACTIVE_ANALYSIS_DETAILS = true;
176 salcianu 1.3              }
177 salcianu 1.3          });
178 salcianu 1.3          
179 salcianu 1.3          opts.add(new Option("pa:i", "", "<detail>",
180 salcianu 1.3                              "Interactive Pointer Analysis; if optional argument <detail> is present, the result of analysis is shown for each program point inside a method.") {
181 salcianu 1.3              public void action() {
182 salcianu 1.3                  INTERACTIVE_ANALYSIS = true;
183 salcianu 1.3                  if(getOptionalArg(0) != null)
184 salcianu 1.3                      INTERACTIVE_ANALYSIS_DETAILS = true;
185 salcianu 1.3              }
186 salcianu 1.3          });
187 salcianu 1.3  
188 salcianu 1.3          opts.add(new Option("pa:cg-stats", "Call graph statistics") {
189 salcianu 1.3              public void action() { CALL_GRAPH_STATS = true; }
190 salcianu 1.3          });
191 salcianu 1.3  
192 salcianu 1.3      };
193 salcianu 1.3      
194 salcianu 1.3      
195 salcianu 1.3      private boolean LOAD_PRE_ANALYSIS = false;
196 salcianu 1.3      private boolean SAVE_PRE_ANALYSIS = false;
197 salcianu 1.3      private String preAnalysisFileName = null;
198 salcianu 1.3      
199 salcianu 1.7      // by default, do not use the SmartCallGraph
200 salcianu 1.7      private boolean SMART_CALL_GRAPH  = false;
201 salcianu 1.3      
202 salcianu 1.3      private boolean TIMING = false;
203 salcianu 1.3      private boolean SHOW_CG = false;
204 salcianu 1.3      
205 salcianu 1.3      private boolean DO_ANALYSIS = false;
206 salcianu 1.10     private List methodsToAnalyze = null;
207 salcianu 1.3      
208 salcianu 1.3      private boolean INTERACTIVE_ANALYSIS = false;
209 salcianu 1.3      private boolean INTERACTIVE_ANALYSIS_DETAILS = false;
210 salcianu 1.3      
211 salcianu 1.3      private boolean CALL_GRAPH_STATS = false;
212 salcianu 1.3  
213 salcianu 1.10     public boolean enabled() { return extEnabled; }
214 salcianu 1.3      private boolean extEnabled = false;
215 salcianu 1.3      
216 salcianu 1.10     public boolean selfEnabled() {
217 salcianu 1.10         return DO_ANALYSIS || INTERACTIVE_ANALYSIS;
218 salcianu 1.10     }
219 salcianu 1.10 
220 salcianu 1.3      protected void real_action() {
221 salcianu 1.3          PreAnalysisRes pre_analysis =
222 salcianu 1.3              LOAD_PRE_ANALYSIS ? load_pre_analysis() : do_pre_analysis();
223 salcianu 1.3          
224 salcianu 1.3          if(SAVE_PRE_ANALYSIS)
225 salcianu 1.3              save_pre_analysis(pre_analysis);
226 salcianu 1.3          
227 salcianu 1.3          PointerAnalysis pa = 
228 salcianu 1.3              new PointerAnalysis(pre_analysis.mcg,
229 salcianu 1.3                                  pre_analysis.caching_scc_lbb_factory,
230 salcianu 1.5                                  linker, classHierarchy);
231 salcianu 1.3          
232 salcianu 1.3          if(DO_ANALYSIS)
233 salcianu 1.3              do_analysis(pa, methodsToAnalyze);
234 salcianu 1.3          
235 salcianu 1.3          if(INTERACTIVE_ANALYSIS)
236 salcianu 1.3              interactive_analysis(pa);
237 salcianu 1.10 
238 salcianu 1.3          attribs = attribs.put("PointerAnalysis", pa);
239 salcianu 1.3      }
240 salcianu 1.3      
241 salcianu 1.3      private static class PreAnalysisRes implements java.io.Serializable {
242 salcianu 1.3          
243 salcianu 1.3          public final MetaCallGraph  mcg;
244 salcianu 1.3          public final CachingSCCLBBFactory caching_scc_lbb_factory;
245 salcianu 1.3          
246 salcianu 1.3          public PreAnalysisRes(MetaCallGraph mcg, CachingSCCLBBFactory fact) {
247 salcianu 1.3              this.mcg = mcg;
248 salcianu 1.3              this.caching_scc_lbb_factory = fact;
249 salcianu 1.3          }
250 salcianu 1.3      }
251 salcianu 1.3      
252 salcianu 1.3      
253 salcianu 1.3      private PreAnalysisRes load_pre_analysis() {
254 salcianu 1.3          try {
255 salcianu 1.3              ObjectInputStream ois = new ObjectInputStream
256 salcianu 1.3                  (new FileInputStream(preAnalysisFileName));
257 salcianu 1.3              _UNPACK_CS((CompilerState) ois.readObject()); // compiler srate
258 salcianu 1.3              PreAnalysisRes pre_analysis = (PreAnalysisRes) ois.readObject();
259 salcianu 1.3              ois.close();
260 salcianu 1.3              return pre_analysis;
261 salcianu 1.3          } catch (Exception e) {
262 salcianu 1.4              handle_fatal_error(e, "Error while deserializing PA pre-analysis");
263 salcianu 1.3              return null;
264 salcianu 1.3          }
265 salcianu 1.3      }
266 salcianu 1.3      
267 salcianu 1.3      
268 salcianu 1.3      private void save_pre_analysis(PreAnalysisRes pre_analysis) {
269 salcianu 1.3          try {
270 salcianu 1.3              ObjectOutputStream oos = new ObjectOutputStream
271 salcianu 1.3                  (new FileOutputStream(preAnalysisFileName));
272 salcianu 1.3              CompilerState cs = _PACK_CS();
273 salcianu 1.3              oos.writeObject(cs); // compiler state
274 salcianu 1.3              _UNPACK_CS(cs);      // don't worry if you don't understand this
275 salcianu 1.3              oos.writeObject(pre_analysis);
276 salcianu 1.3              oos.close();
277 salcianu 1.3          } catch (IOException e) {
278 salcianu 1.3              handle_fatal_error(e, "Error while serializing PA pre-analysis");
279 salcianu 1.3          }
280 salcianu 1.3      }
281 salcianu 1.3      
282 salcianu 1.3      
283 salcianu 1.3      private void handle_fatal_error(Exception e, String message) {
284 salcianu 1.3          System.err.println(message + " " + e);
285 salcianu 1.3          e.printStackTrace();
286 salcianu 1.3          System.exit(1);
287 salcianu 1.3      }
288 salcianu 1.3      
289 salcianu 1.3      
290 salcianu 1.3      private PreAnalysisRes do_pre_analysis() {
291 salcianu 1.3          
292 salcianu 1.4          hcf = new CachingCodeFactory(QuadNoSSA.codeFactory(hcf), true);
293 salcianu 1.3          
294 salcianu 1.3          if(TIMING)
295 salcianu 1.3              time_ir_generation();
296 salcianu 1.3          
297 salcianu 1.3          // there is something crazy here: too messy & too much caching
298 salcianu 1.3          CachingSCCLBBFactory scc_lbb_factory = 
299 salcianu 1.3              new CachingSCCLBBFactory
300 salcianu 1.3              (new CachingLBBConverter
301 salcianu 1.3               (new CachingBBConverter(hcf)));
302 salcianu 1.3          
303 salcianu 1.3          if(TIMING)
304 salcianu 1.3              time_scc_lbb_generation(scc_lbb_factory);
305 salcianu 1.3          
306 salcianu 1.3          MetaCallGraph mcg = get_meta_call_graph();
307 salcianu 1.3  
308 salcianu 1.3          if(CALL_GRAPH_STATS)
309 salcianu 1.3              call_graph_stats(mcg);
310 salcianu 1.3          
311 salcianu 1.3          return
312 salcianu 1.3              new PreAnalysisRes(mcg, scc_lbb_factory);
313 salcianu 1.3      }
314 salcianu 1.3      
315 salcianu 1.3      
316 salcianu 1.3      private void time_ir_generation() {
317 salcianu 1.3          System.out.print(hcf.getCodeName() + " IR generation ... ");
318 salcianu 1.3          long tstart = time();
319 salcianu 1.3          
320 salcianu 1.3          for(Iterator it = classHierarchy.callableMethods().iterator();
321 salcianu 1.3              it.hasNext(); ) {
322 salcianu 1.3              hcf.convert((HMethod) it.next());
323 salcianu 1.3          }
324 salcianu 1.3          
325 salcianu 1.3          System.out.println((time() - tstart) + " ms");
326 salcianu 1.3      }
327 salcianu 1.3      
328 salcianu 1.3      
329 salcianu 1.3      private void time_scc_lbb_generation(CachingSCCLBBFactory scc_lbb_fact) {
330 salcianu 1.3          System.out.print("SCC LBB generation ... ");
331 salcianu 1.3          long tstart = time();
332 salcianu 1.3          
333 cananian 1.9          for(Object hmO : classHierarchy.callableMethods()) {
334 cananian 1.9              HMethod hm = (HMethod) hmO;
335 salcianu 1.3              HCode hcode = hcf.convert(hm);
336 salcianu 1.3              if(hcode != null)
337 salcianu 1.3                  scc_lbb_fact.computeSCCLBB(hm);
338 salcianu 1.3          }
339 salcianu 1.3          
340 salcianu 1.3          System.out.println((time() - tstart) + " ms");
341 salcianu 1.3      }
342 salcianu 1.3      
343 salcianu 1.3      
344 salcianu 1.3      private MetaCallGraph get_meta_call_graph() {
345 salcianu 1.3          long tstart = 0L;
346 salcianu 1.3          
347 salcianu 1.3          if(TIMING)
348 salcianu 1.3              tstart = time();
349 salcianu 1.3          
350 salcianu 1.3          CallGraph cg =
351 salcianu 1.3              SMART_CALL_GRAPH ?
352 salcianu 1.3              (CallGraph) 
353 salcianu 1.3              (new SmartCallGraph((CachingCodeFactory) hcf, linker,
354 salcianu 1.3                                  classHierarchy, roots)) :           
355 salcianu 1.3              (CallGraph)
356 salcianu 1.3              (new CachingCallGraph(new CallGraphImpl(classHierarchy, hcf)));
357 salcianu 1.3          
358 salcianu 1.3          MetaCallGraph mcg = new FakeMetaCallGraph(cg);
359 salcianu 1.3          
360 salcianu 1.3          if(TIMING)
361 salcianu 1.3              System.out.println("(Fake)MetaCallGraph construction " +
362 salcianu 1.3                                 (time() - tstart) + " ms");
363 salcianu 1.3          
364 salcianu 1.3          if(SHOW_CG) {
365 salcianu 1.3              System.out.println("PA: MetaCallGraph:");
366 salcianu 1.3              mcg.print(System.out, true, new MetaMethod(mainM, true));
367 salcianu 1.3          }
368 salcianu 1.3          
369 salcianu 1.3          return mcg;
370 salcianu 1.3      }
371 salcianu 1.3      
372 salcianu 1.3      
373 salcianu 1.10     private void do_analysis(PointerAnalysis pa, List<String> methods) {
374 cananian 1.9          for(String m : methods) {
375 cananian 1.8              display_pa4method(pa, m);
376 cananian 1.8          }
377 salcianu 1.3      }
378 salcianu 1.3      
379 salcianu 1.3      private void interactive_analysis(PointerAnalysis pa) {
380 salcianu 1.3          BufferedReader d = 
381 salcianu 1.3              new BufferedReader(new InputStreamReader(System.in));
382 salcianu 1.3          while(true) {
383 salcianu 1.3              System.out.print("Method name:");
384 salcianu 1.3              String method = null;
385 salcianu 1.3              try {
386 salcianu 1.3                  method = d.readLine();
387 salcianu 1.3              } catch(IOException e) {
388 salcianu 1.3                  handle_fatal_error(e, "Error reading from System.in");
389 salcianu 1.3              }
390 salcianu 1.3              if(method == null) { // EOF received
391 salcianu 1.3                  System.out.println();
392 salcianu 1.3                  break;
393 salcianu 1.3              }
394 salcianu 1.3              display_pa4method(pa, method);
395 salcianu 1.3          }
396 salcianu 1.3      }
397 salcianu 1.3      
398 salcianu 1.3      
399 salcianu 1.3      private void display_pa4method(PointerAnalysis pa, String method) {
400 salcianu 1.10         if(method.equals("QUIT")) System.exit(1);
401 salcianu 1.10 
402 salcianu 1.3          int point_pos = method.lastIndexOf('.');
403 salcianu 1.3          String declClassName = 
404 salcianu 1.3              (point_pos != -1) ?
405 salcianu 1.3              method.substring(0, point_pos) :
406 salcianu 1.3              // by default, same class as root method
407 salcianu 1.3              mainM.getDeclaringClass().getName();
408 salcianu 1.4          String methodName = method.substring(point_pos + 1);
409 salcianu 1.3          
410 salcianu 1.3          HClass hclass = null;
411 salcianu 1.3          try {
412 salcianu 1.3              hclass = linker.forName(declClassName);
413 salcianu 1.3          } catch (NoSuchClassException e) {
414 salcianu 1.3              System.err.println("Class " + declClassName + " not found!");
415 salcianu 1.3              return;
416 salcianu 1.3          }
417 salcianu 1.3          
418 salcianu 1.3          int count = 0;
419 salcianu 1.3          HMethod[] hms  = hclass.getDeclaredMethods();
420 salcianu 1.3          for (int i = 0; i < hms.length; i++) {
421 salcianu 1.3              if(!hms[i].getName().equals(methodName))
422 salcianu 1.3                  continue;
423 salcianu 1.3              count++;
424 salcianu 1.3              HMethod hm = hms[i];
425 salcianu 1.3              
426 salcianu 1.3              long tstart = TIMING ? time() : 0L;
427 salcianu 1.3              ParIntGraph int_pig = pa.getIntParIntGraph(hm);
428 salcianu 1.3              ParIntGraph ext_pig = pa.getExtParIntGraph(hm);
429 salcianu 1.3              if(TIMING)
430 salcianu 1.3                  System.out.println("Analysis took " + (time()-tstart) + "ms");
431 salcianu 1.3              
432 salcianu 1.3              System.out.println("METHOD " + hm);
433 salcianu 1.3              display_pointer_parameters(hm, pa);
434 salcianu 1.3              System.out.print("INT. GRAPH AT THE END OF THE METHOD:");
435 salcianu 1.3              System.out.println(int_pig);
436 salcianu 1.3              System.out.print("EXT. GRAPH AT THE END OF THE METHOD:");
437 salcianu 1.3              System.out.println(ext_pig);
438 salcianu 1.3              
439 salcianu 1.3              if(INTERACTIVE_ANALYSIS_DETAILS) {
440 salcianu 1.3                  HCode hcode = hcf.convert(hm);
441 salcianu 1.3                  for(Iterator itq = hcode.getElementsI(); itq.hasNext(); ) {
442 salcianu 1.3                      Quad q = (Quad) itq.next();
443 salcianu 1.3                      System.out.println("Graph just before <<" + 
444 salcianu 1.3                                         Util.code2str(q) + ">>: " +
445 salcianu 1.3                                         pa.getPIGAtQuad(hm, q));
446 salcianu 1.3                  }
447 salcianu 1.3              }
448 salcianu 1.3          }
449 salcianu 1.3          
450 salcianu 1.3          if(count == 0)
451 salcianu 1.3              System.err.println("Method " + method + " not found!");
452 salcianu 1.3      }
453 salcianu 1.3      
454 salcianu 1.3      
455 salcianu 1.3      // displays the parameter nodes for method hm
456 salcianu 1.3      // TODO: print the sources of all the nodes that appear in displayed pigs.
457 salcianu 1.3      private void display_pointer_parameters(HMethod hm, PointerAnalysis pa) {
458 salcianu 1.3          PANode[] nodes = pa.getParamNodes(new MetaMethod(hm, true));
459 salcianu 1.3          System.out.print("POINTER PARAMETERS: ");
460 salcianu 1.3          System.out.print("[ ");
461 salcianu 1.3          for(int j = 0; j < nodes.length; j++)
462 salcianu 1.3              System.out.print(nodes[j] + " ");
463 salcianu 1.3          System.out.println("]");
464 salcianu 1.3      }
465 salcianu 1.3      
466 salcianu 1.3      
467 salcianu 1.3      
468 salcianu 1.3      private void call_graph_stats(MetaCallGraph mcg) {
469 salcianu 1.3          long nb_nvirtual_calls  = 0L;
470 salcianu 1.3          long nb_virtual_calls = 0L;
471 salcianu 1.3          long vcalls[] = new long[100];
472 salcianu 1.3          long nb_total_callees = 0L;
473 salcianu 1.3          for(int i = 0; i < vcalls.length; i++)
474 salcianu 1.3              vcalls[i] = 0L;
475 salcianu 1.3          
476 cananian 1.9          for(Object mmO : mcg.getAllMetaMethods()) {
477 cananian 1.9              MetaMethod mm = (MetaMethod) mmO;
478 salcianu 1.3              HCode hcode = hcf.convert(mm.getHMethod());
479 salcianu 1.3              if(hcode == null) continue;
480 salcianu 1.3              Collection calls = ((Code) hcode).selectCALLs();
481 salcianu 1.3              
482 cananian 1.9              for(Object callO : calls) {
483 cananian 1.9                  CALL call = (CALL) callO;
484 salcianu 1.3                  MetaMethod[] callees = mcg.getCallees(mm, call);
485 salcianu 1.3                  int nb_callees = callees.length;
486 salcianu 1.3                  if(callees.length == 0)
487 salcianu 1.3                      System.out.println("EMPTY CALL " + Util.code2str(call) +
488 salcianu 1.3                                         "\n  in " + mm);
489 salcianu 1.3                  nb_total_callees += nb_callees;
490 salcianu 1.3                  if(call.isVirtual()) {
491 salcianu 1.3                      nb_virtual_calls++;
492 salcianu 1.3                      if(nb_callees >= vcalls.length)
493 salcianu 1.3                          nb_callees = vcalls.length - 1;
494 salcianu 1.3                      vcalls[nb_callees]++;
495 salcianu 1.3                  }
496 salcianu 1.3                  else
497 salcianu 1.3                      nb_nvirtual_calls++;
498 salcianu 1.3              }
499 salcianu 1.3          }
500 salcianu 1.3          
501 salcianu 1.3          long nb_calls = nb_virtual_calls + nb_nvirtual_calls;
502 salcianu 1.3          System.out.println("\nCALL SITES STATISTICS:\n");
503 salcianu 1.3          System.out.println("Total calls       = " + nb_calls);
504 salcianu 1.3          System.out.println("Non-virtual calls = " + nb_nvirtual_calls + "\t" +
505 salcianu 1.3                             Util.percentage(nb_nvirtual_calls, nb_calls));
506 salcianu 1.3          System.out.println("Virtual calls     = " + nb_virtual_calls + "\t" +
507 salcianu 1.3                             Util.percentage(nb_virtual_calls, nb_calls));
508 salcianu 1.3          for(int i = 0; i < vcalls.length; i++)
509 salcianu 1.3              if(vcalls[i] > 0)
510 salcianu 1.3                  System.out.println
511 salcianu 1.3                      ("  " + i + " callee(s) = " + vcalls[i] +
512 salcianu 1.3                       "\t" + Util.percentage(vcalls[i], nb_virtual_calls));
513 salcianu 1.3          System.out.println
514 salcianu 1.3              ("Average callees/call site = " + 
515 salcianu 1.3               Util.doubleRep(((double) nb_total_callees) / nb_calls, 2));
516 salcianu 1.3          System.out.println("-----------------------------------------------");
517 salcianu 1.3      }
518 salcianu 1.3      
519 salcianu 1.3      
520 salcianu 1.3      private static long time() {
521 salcianu 1.3          return System.currentTimeMillis();
522 salcianu 1.3      }
523 salcianu 1.3      
524 salcianu 1.1  }