1 salcianu 1.1 // AllocSyncOptCompStage.java, created Fri Apr 18 22:13:12 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.HMethod; 7 salcianu 1.1 8 salcianu 1.1 import harpoon.Analysis.PointerAnalysis.MAInfo; 9 salcianu 1.1 import harpoon.Analysis.PointerAnalysis.MAInfo.MAInfoOptions; 10 salcianu 1.1 11 salcianu 1.1 import harpoon.Analysis.MetaMethods.MetaCallGraph; 12 salcianu 1.1 import harpoon.Analysis.MetaMethods.MetaMethod; 13 salcianu 1.1 14 salcianu 1.1 import harpoon.Main.CompilerState; 15 salcianu 1.1 import harpoon.Main.CompilerStage; 16 salcianu 1.1 import harpoon.Main.CompilerStageEZ; 17 salcianu 1.1 import harpoon.Main.CompStagePipeline; 18 salcianu 1.1 import harpoon.Util.Options.Option; 19 salcianu 1.1 20 salcianu 1.1 import java.util.List; 21 salcianu 1.1 import java.util.LinkedList; 22 salcianu 1.1 import java.util.Set; 23 salcianu 1.2 import java.util.HashSet; 24 salcianu 1.1 import java.util.Iterator; 25 salcianu 1.1 26 salcianu 1.1 27 salcianu 1.1 /** 28 salcianu 1.1 * <code>AllocSyncOptCompStage</code> 29 salcianu 1.1 * 30 salcianu 1.1 * @author Alexandru Salcianu <salcianu@MIT.EDU> 31 cananian 1.4 * @version $Id: AllocSyncOptCompStage.java,v 1.4 2004/02/08 03:20:02 cananian Exp $ 32 salcianu 1.1 */ 33 salcianu 1.1 public class AllocSyncOptCompStage extends CompilerStageEZ { 34 salcianu 1.1 35 salcianu 1.1 /** Returns a compiler stage consisting of the sequential 36 salcianu 1.1 composition of a pointer analysis stage and a stack/heap 37 salcianu 1.1 allocation and sync removal optimization stage. */ 38 salcianu 1.1 public static CompilerStage getFullStage() { 39 salcianu 1.1 final CompilerStage optStage = new AllocSyncOptCompStage(); 40 salcianu 1.1 return 41 salcianu 1.1 new CompStagePipeline(new PointerAnalysisCompStage(true), 42 salcianu 1.1 optStage) { 43 salcianu 1.1 public boolean enabled() { return optStage.enabled(); } 44 salcianu 1.1 }; 45 salcianu 1.1 } 46 salcianu 1.1 47 salcianu 1.1 48 salcianu 1.1 public AllocSyncOptCompStage() { super("alloc-sync-opt"); } 49 salcianu 1.1 50 salcianu 1.1 private MAInfoOptions maio = new MAInfoOptions(); 51 salcianu 1.1 private boolean SHOW_ALLOC_PROPERTIES = false; 52 salcianu 1.1 53 salcianu 1.1 public List/*<Option>*/ getOptions() { 54 salcianu 1.1 List/*<Option>*/ opts = new LinkedList/*<Option>*/(); 55 salcianu 1.1 56 salcianu 1.1 opts.add(new Option("stack-alloc", "<policy>", "<inlining-depth>", 57 salcianu 1.1 "Stack allocation policy: 1 (not in loops) | 2 (whenever it's possible); the optional argument <inlining-depth> specifies the maximul level of inlining for improving the stack allocation opportunities (no inlining by default)") { 58 salcianu 1.1 public void action() { 59 salcianu 1.1 int policy = Integer.parseInt(getArg(0)); 60 salcianu 1.1 switch(policy) { 61 salcianu 1.1 case MAInfoOptions.STACK_ALLOCATE_NOT_IN_LOOPS: 62 salcianu 1.1 case MAInfoOptions.STACK_ALLOCATE_ALWAYS: 63 salcianu 1.1 maio.DO_STACK_ALLOCATION = true; 64 salcianu 1.1 maio.STACK_ALLOCATION_POLICY = policy; 65 salcianu 1.1 // see if any inlining depth is specified 66 salcianu 1.1 if(getOptionalArg(0) != null) { 67 salcianu 1.1 int depth = Integer.parseInt(getOptionalArg(0)); 68 salcianu 1.1 assert depth >= 0 : "Invalid inlining depth " + depth; 69 salcianu 1.1 maio.DO_INLINING_FOR_SA = true; 70 salcianu 1.1 maio.MAX_INLINING_LEVEL = depth; 71 salcianu 1.1 } 72 salcianu 1.1 break; 73 salcianu 1.1 default: 74 salcianu 1.1 System.err.println("Unknown stack allocation policy " + 75 salcianu 1.1 policy); 76 salcianu 1.1 System.exit(1); 77 salcianu 1.1 } 78 salcianu 1.1 } 79 salcianu 1.1 }); 80 salcianu 1.1 81 salcianu 1.1 opts.add(new Option("thread-alloc", "", "<inlining-depth>", 82 salcianu 1.1 "Thread allocation; the optional argument <inlining-depth> specifies the maximul level of inlining for improving the thread allocation opportunities (no inlining by default)") { 83 salcianu 1.1 public void action() { 84 salcianu 1.1 maio.DO_THREAD_ALLOCATION = true; 85 salcianu 1.1 if(getOptionalArg(0) != null) { 86 salcianu 1.1 int depth = Integer.parseInt(getOptionalArg(0)); 87 salcianu 1.1 assert depth >= 0 : "Invalid inlining depth " + depth; 88 salcianu 1.1 maio.DO_INLINING_FOR_TA = true; 89 salcianu 1.1 // TODO: currently, we have the same 90 salcianu 1.1 // MAX_INLINING_LEVEL for both SA and TA; they 91 salcianu 1.1 // should be either condensed in a single option; 92 salcianu 1.1 // or separated. 93 salcianu 1.1 maio.MAX_INLINING_LEVEL = depth; 94 salcianu 1.1 } 95 salcianu 1.1 } 96 salcianu 1.1 }); 97 salcianu 1.1 98 salcianu 1.1 opts.add(new Option("thread-arg-prealloc", 99 salcianu 1.1 "Preallocate thread parameters in thread local heap; DISCOURAGED! Makes sense only in the context of thread allocation.") { 100 salcianu 1.1 public void action() { maio.DO_PREALLOCATION = true; } 101 salcianu 1.1 }); 102 salcianu 1.1 103 salcianu 1.1 opts.add(new Option("sync-removal", "", "wit", 104 salcianu 1.2 "Synchronization removal optimization; if optional argument \"wit\" is present, use the inter-thread pointer analysis (unrecommended).") { 105 salcianu 1.1 public void action() { 106 salcianu 1.1 maio.GEN_SYNC_FLAG = true; 107 salcianu 1.1 if(getOptionalArg(0) != null) { 108 salcianu 1.1 assert getOptionalArg(0).equals("wit") : 109 salcianu 1.1 "Unknown optional arg for sync-removal" + 110 salcianu 1.1 getOptionalArg(0); 111 salcianu 1.1 maio.USE_INTER_THREAD = true; 112 salcianu 1.1 } 113 salcianu 1.1 // make sure we use Runtime2 - Runtime1 disconsiders 114 salcianu 1.1 // the noSync flags 115 salcianu 1.1 System.setProperty("harpoon.runtime", "2"); 116 salcianu 1.1 } 117 salcianu 1.1 }); 118 salcianu 1.1 119 salcianu 1.1 opts.add(new Option("show-ap", "Show alocation properties") { 120 salcianu 1.1 public void action() { SHOW_ALLOC_PROPERTIES = true; } 121 salcianu 1.1 }); 122 salcianu 1.2 123 salcianu 1.2 opts.add(new Option("pa-optimize-all", "Optimize all code, including the static initializers (by default, optimize only code reachable from the main method)") { 124 salcianu 1.2 public void action() { OPTIMIZE_ALL = true; } 125 salcianu 1.2 }); 126 salcianu 1.1 127 salcianu 1.1 return opts; 128 salcianu 1.1 } 129 salcianu 1.1 130 salcianu 1.2 /** Controls whether we optimize all the code or not. By default, 131 salcianu 1.2 do not optimize the static initializers - some of them are 132 salcianu 1.2 really big (ex: jaca.util.Locale) and there is little interest 133 salcianu 1.2 in optimizing them anyway: they are executed only once.*/ 134 salcianu 1.2 private boolean OPTIMIZE_ALL = false; 135 salcianu 1.1 136 salcianu 1.1 public boolean enabled() { 137 salcianu 1.1 return 138 salcianu 1.1 maio.DO_STACK_ALLOCATION || 139 salcianu 1.1 maio.DO_THREAD_ALLOCATION || 140 salcianu 1.1 maio.GEN_SYNC_FLAG; 141 salcianu 1.1 } 142 salcianu 1.1 143 salcianu 1.1 protected void real_action() { 144 salcianu 1.1 PointerAnalysis pa = 145 salcianu 1.1 (PointerAnalysis) attribs.get("PointerAnalysis"); 146 salcianu 1.1 147 salcianu 1.1 MetaCallGraph mcg = pa.getMetaCallGraph(); 148 salcianu 1.2 149 salcianu 1.2 Set/*<MetaMethod>*/ mms = 150 salcianu 1.2 OPTIMIZE_ALL ? mcg.getAllMetaMethods() : 151 salcianu 1.3 mcg.transitiveSucc(mainAndRuns(mcg)); 152 salcianu 1.2 153 salcianu 1.2 time_analysis(pa, mms); 154 salcianu 1.1 155 salcianu 1.2 System.out.println("MAInfo options: "); 156 salcianu 1.2 maio.print("\t"); 157 salcianu 1.2 158 salcianu 1.2 long g_tstart = time(); 159 salcianu 1.2 MAInfo mainfo = new MAInfo(pa, hcf, linker, mms, maio); 160 salcianu 1.2 System.out.println("GENERATION OF MA INFO TIME : " + 161 salcianu 1.2 (time() - g_tstart) + "ms"); 162 salcianu 1.2 System.out.println("===================================\n"); 163 salcianu 1.2 164 salcianu 1.2 if(SHOW_ALLOC_PROPERTIES) // show allocation policies 165 salcianu 1.2 mainfo.print(); 166 salcianu 1.3 } 167 salcianu 1.3 168 salcianu 1.3 private Set/*<MetaMethod>*/ mainAndRuns(MetaCallGraph mcg) { 169 salcianu 1.3 Set roots = new HashSet(); 170 salcianu 1.3 roots.add(new MetaMethod(mainM, true)); 171 salcianu 1.3 roots.addAll(mcg.getRunMetaMethods()); 172 salcianu 1.3 173 salcianu 1.3 System.out.println("MAINANDRUNS: " + roots); 174 salcianu 1.3 175 salcianu 1.3 return roots; 176 salcianu 1.2 } 177 salcianu 1.2 178 salcianu 1.2 // time the pointer analysis over all (meta)methods from mms. 179 salcianu 1.2 private void time_analysis(PointerAnalysis pa, Set/*<MetaMethod>*/ mms) { 180 salcianu 1.2 // The following loop times the analysis of the relevant part 181 salcianu 1.2 // of the program (i.e., methods from mms). Doing it here, 182 salcianu 1.2 // before any optimization, allows us to time it accurately. 183 salcianu 1.1 long g_tstart = time(); 184 salcianu 1.2 if(OPTIMIZE_ALL) { 185 cananian 1.4 for(Object mmO : mms) { 186 cananian 1.4 MetaMethod mm = (MetaMethod) mmO; 187 salcianu 1.2 if(!analyzable(mm)) continue; 188 salcianu 1.2 pa.getIntParIntGraph(mm); 189 salcianu 1.2 } 190 salcianu 1.1 } 191 salcianu 1.2 else pa.getIntParIntGraph(new MetaMethod(mainM, true)); 192 salcianu 1.1 System.out.println("Intrathread Analysis time: " + 193 salcianu 1.1 (time() - g_tstart) + "ms"); 194 salcianu 1.1 System.out.println("===================================\n"); 195 salcianu 1.1 196 salcianu 1.1 if (maio.USE_INTER_THREAD) { 197 salcianu 1.1 g_tstart = System.currentTimeMillis(); 198 cananian 1.4 for(Object mmO : mms) { 199 cananian 1.4 MetaMethod mm = (MetaMethod) mmO; 200 salcianu 1.1 if(!analyzable(mm)) continue; 201 salcianu 1.1 pa.getIntThreadInteraction(mm); 202 salcianu 1.1 } 203 salcianu 1.1 System.out.println("Interthread Analysis time: " + 204 salcianu 1.1 (time() - g_tstart) + "ms"); 205 salcianu 1.1 System.out.println("===================================\n"); 206 salcianu 1.1 } 207 salcianu 1.1 } 208 salcianu 1.2 209 salcianu 1.1 210 salcianu 1.1 // TODO: change this to invoke hcf.convert and check result against null 211 salcianu 1.1 private static boolean analyzable(MetaMethod mm) { 212 salcianu 1.1 HMethod hm = mm.getHMethod(); 213 salcianu 1.1 if(java.lang.reflect.Modifier.isNative(hm.getModifiers())) 214 salcianu 1.1 return false; 215 salcianu 1.1 if(java.lang.reflect.Modifier.isAbstract(hm.getModifiers())) 216 salcianu 1.1 return false; 217 salcianu 1.1 return true; 218 salcianu 1.1 } 219 salcianu 1.1 220 salcianu 1.1 private static long time() { 221 salcianu 1.1 return System.currentTimeMillis(); 222 salcianu 1.1 } 223 salcianu 1.1 }