1 pnkfelix 1.1.2.1 // SAMain.java, created Mon Aug 2 19:41:06 1999 by pnkfelix 2 pnkfelix 1.1.2.1 // Copyright (C) 1999 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.Main; 5 pnkfelix 1.1.2.1 6 cananian 1.12 import harpoon.Analysis.AbstractClassFixupRelinker; 7 pnkfelix 1.1.2.1 import harpoon.ClassFile.CachingCodeFactory; 8 pnkfelix 1.1.2.1 import harpoon.ClassFile.HClass; 9 pnkfelix 1.1.2.1 import harpoon.ClassFile.HCodeFactory; 10 pnkfelix 1.1.2.1 import harpoon.ClassFile.HMethod; 11 cananian 1.1.2.54 import harpoon.ClassFile.Linker; 12 cananian 1.1.2.54 import harpoon.ClassFile.Loader; 13 cananian 1.1.2.96 import harpoon.ClassFile.NoSuchClassException; 14 cananian 1.1.2.101 import harpoon.ClassFile.Relinker; 15 salcianu 1.45 import harpoon.IR.Quads.QuadWithTry; 16 salcianu 1.31 import harpoon.IR.Quads.QuadNoSSA; 17 salcianu 1.45 import harpoon.IR.Quads.QuadSSI; 18 salcianu 1.38 import harpoon.Backend.Backend; 19 witchel 1.1.2.81 import harpoon.Backend.Generic.Frame; 20 cananian 1.1.2.21 import harpoon.Analysis.ClassHierarchy; 21 cananian 1.1.2.92 import harpoon.Analysis.CallGraph; 22 salcianu 1.1.2.70 import harpoon.Analysis.Quads.CallGraphImpl; 23 cananian 1.1.2.93 import harpoon.Analysis.Quads.CallGraphImpl2; 24 cananian 1.1.2.29 import harpoon.Analysis.Quads.QuadClassHierarchy; 25 bdemsky 1.1.2.121 26 cananian 1.61 import net.cscott.jutil.CombineIterator; 27 cananian 1.61 import net.cscott.jutil.Default; 28 cananian 1.1.2.119 import harpoon.Util.ParseUtil; 29 pnkfelix 1.1.2.4 import harpoon.Util.Util; 30 pnkfelix 1.1.2.1 31 salcianu 1.33 import harpoon.Backend.Runtime1.AllocationStrategy; 32 salcianu 1.33 import harpoon.Backend.Runtime1.AllocationStrategyFactory; 33 salcianu 1.33 34 salcianu 1.23 import harpoon.IR.Quads.Quad; 35 salcianu 1.47 36 salcianu 1.48 import harpoon.Instrumentation.AllocationStatistics.AllocationInstrCompStage; 37 wbeebee 1.1.2.113 import harpoon.Analysis.Realtime.Realtime; 38 salcianu 1.47 import harpoon.Analysis.MemOpt.PreallocOpt; 39 salcianu 1.51 import harpoon.Analysis.PointerAnalysis.PointerAnalysisCompStage; 40 salcianu 1.54 import harpoon.Analysis.PointerAnalysis.AllocSyncOptCompStage; 41 salcianu 1.47 42 salcianu 1.49 import harpoon.Util.Options.Option; 43 salcianu 1.49 44 cananian 1.1.2.25 import java.lang.reflect.Modifier; 45 cananian 1.1.2.55 import java.util.Arrays; 46 cananian 1.1.2.55 import java.util.Collections; 47 bdemsky 1.1.2.121 import java.util.Collection; 48 salcianu 1.49 import java.util.Iterator; 49 salcianu 1.49 import java.util.Set; 50 cananian 1.1.2.55 import java.util.HashSet; 51 cananian 1.1.2.55 import java.util.List; 52 salcianu 1.48 import java.util.LinkedList; 53 salcianu 1.19 import java.util.Map; 54 salcianu 1.21 import java.util.HashMap; 55 salcianu 1.49 56 cananian 1.1.2.55 import java.io.File; 57 cananian 1.1.2.55 import java.io.FileInputStream; 58 cananian 1.1.2.55 import java.io.FileOutputStream; 59 cananian 1.1.2.55 import java.io.IOException; 60 pnkfelix 1.1.2.5 import java.io.ObjectInputStream; 61 pnkfelix 1.1.2.5 import java.io.ObjectOutputStream; 62 cananian 1.1.2.55 import java.io.PrintStream; 63 salcianu 1.48 64 pnkfelix 1.1.2.1 /** 65 pnkfelix 1.1.2.1 * <code>SAMain</code> is a program to compile java classes to some 66 pnkfelix 1.1.2.1 * approximation of StrongARM assembly. It is for development testing 67 pnkfelix 1.1.2.1 * purposes, not production use. 68 pnkfelix 1.1.2.1 * 69 pnkfelix 1.1.2.1 * @author Felix S. Klock II <pnkfelix@mit.edu> 70 cananian 1.62 * @version $Id: SAMain.java,v 1.62 2004/02/08 03:21:38 cananian Exp $ 71 pnkfelix 1.1.2.1 */ 72 pnkfelix 1.1.2.1 public class SAMain extends harpoon.IR.Registration { 73 pnkfelix 1.1.2.1 74 jwhaley 1.1.2.86 static boolean OPTIMIZE = false; 75 jwhaley 1.1.2.86 static boolean LOOPOPTIMIZE = false; 76 salcianu 1.43 static boolean QUIET = false; 77 salcianu 1.38 78 salcianu 1.38 /** Backend kind. Has to be one of the constants defined in 79 salcianu 1.38 <code>harpoon.Backend.Backend</code>; 80 salcianu 1.38 <code>Backend.PRECISEC</code> by default. */ 81 salcianu 1.38 static String BACKEND = Backend.PRECISEC; 82 salcianu 1.23 83 jwhaley 1.1.2.86 static String className; 84 cananian 1.1.2.96 static String rootSetFilename; 85 cananian 1.1.2.96 86 kkz 1.1.2.163 // Support for precise garbage collection 87 kkz 1.1.2.163 static boolean PRECISEGC = false; 88 kkz 1.1.2.138 static boolean MULTITHREADED = false; 89 salcianu 1.43 90 cananian 1.58 private static List<CompilerStage> stages; 91 bdemsky 1.1.2.73 92 pnkfelix 1.1.2.1 public static void main(String[] args) { 93 salcianu 1.48 buildCompilerPipeline(); 94 salcianu 1.53 95 cananian 1.58 List<Option> allOptions = getAllOptions(); 96 salcianu 1.52 parseOpts(args, allOptions); 97 salcianu 1.53 98 salcianu 1.39 if(className == null) { 99 salcianu 1.39 System.err.println("must pass a class to be compiled"); 100 salcianu 1.53 System.err.println("Use option \"-h\" to find all options"); 101 salcianu 1.39 System.exit(1); 102 salcianu 1.39 } 103 salcianu 1.53 104 salcianu 1.39 checkOptionConsistency(); 105 salcianu 1.53 106 salcianu 1.52 CompilerState cs = CompilerState.EMPTY_STATE; 107 salcianu 1.48 108 cananian 1.62 for(CompilerStage stage : stages) { 109 salcianu 1.53 if(stage.enabled()) { 110 salcianu 1.53 System.out.println("Execute stage " + stage.name()); 111 salcianu 1.53 cs = stage.action(cs); 112 salcianu 1.53 } 113 salcianu 1.48 } 114 salcianu 1.48 } 115 salcianu 1.48 116 salcianu 1.48 117 salcianu 1.48 private static void addStage(CompilerStage cs) { stages.add(cs); } 118 salcianu 1.48 119 salcianu 1.48 private static void buildCompilerPipeline() { 120 cananian 1.58 stages = new LinkedList<CompilerStage>(); 121 salcianu 1.48 122 salcianu 1.54 // build a "nascent" compiler state: 123 salcianu 1.54 // main method, root set, linker and frame 124 salcianu 1.52 addStage(new BuildInitialCompState()); 125 salcianu 1.52 126 salcianu 1.54 // add code factory, i.e., parse the code into QuadWithTry IR; 127 salcianu 1.54 // also build class hierarchy 128 salcianu 1.48 addStage(new BuildQuadForm()); 129 salcianu 1.50 // At this point in the pipeline, we have a full compiler 130 salcianu 1.50 // state (including class hierarchy). Let it roll! 131 salcianu 1.48 132 salcianu 1.50 // quad-form analyses 133 salcianu 1.50 buildQuadFormPipeline(); 134 salcianu 1.48 135 salcianu 1.54 // convert quad IR -> tree IR 136 salcianu 1.50 addStage(new LowQuadToTree()); 137 salcianu 1.48 138 salcianu 1.50 // tree-form analyses 139 salcianu 1.48 buildTreeFormPipeline(); 140 salcianu 1.48 141 salcianu 1.50 // final compilation stage 142 salcianu 1.48 addStage(new CodeGenerator()); 143 salcianu 1.48 } 144 salcianu 1.48 145 salcianu 1.48 146 salcianu 1.48 private static void buildQuadFormPipeline() { 147 salcianu 1.54 // adds a stage that does pointer analysis and uses its 148 salcianu 1.54 // results for memory allocation, sync removal, and/or RTJ 149 salcianu 1.54 // programs debug and optimization 150 salcianu 1.54 addStage(PointerAnalysisCompStage.getPAAndAppsStage()); 151 salcianu 1.51 152 salcianu 1.54 // allocation instrumentation stage 153 salcianu 1.48 AllocationInstrCompStage aics = new AllocationInstrCompStage(); 154 salcianu 1.48 addStage(aics); 155 cananian 1.58 // memory preallocation via incompatibility analysis 156 salcianu 1.48 addStage(new PreallocOpt.QuadPass(aics)); 157 salcianu 1.51 158 salcianu 1.48 addStage(new EventDrivenTransformation.QuadPass1()); 159 salcianu 1.48 addStage(new RoleInference()); 160 cananian 1.59 addStage(new DynamicSyncRemoval.QuadPass()); 161 salcianu 1.48 addStage(new Transactions.QuadPass()); 162 salcianu 1.48 addStage(new Realtime.QuadPass()); 163 salcianu 1.48 addStage(new MZFCompilerStage()); 164 salcianu 1.48 addStage(new MIPSOptimizations.QuadPass()); 165 salcianu 1.54 166 salcianu 1.54 // general quad optimizations (disabled by default) 167 salcianu 1.48 addStage(new GeneralQuadOptimizations()); 168 salcianu 1.54 169 salcianu 1.48 addStage(new EventDrivenTransformation.QuadPass2()); 170 salcianu 1.48 addStage(new WriteBarriers.WBQuadPass()); 171 salcianu 1.48 addStage(new WriteBarriers.DynamicWBQuadPass()); 172 salcianu 1.48 173 salcianu 1.54 // common processing and small optimizations 174 salcianu 1.48 addStage(new RegularQuadPass()); 175 salcianu 1.48 } 176 salcianu 1.48 177 salcianu 1.48 178 salcianu 1.48 private static void buildTreeFormPipeline() { 179 salcianu 1.48 addStage(new WriteBarriers.WBDynamicWBTreePass()); 180 salcianu 1.48 addStage(new PreallocOpt.TreePass()); 181 salcianu 1.48 addStage(new Realtime.TreePass()); 182 cananian 1.59 addStage(new DynamicSyncRemoval.TreePass()); 183 salcianu 1.48 addStage(new Transactions.TreePass()); 184 salcianu 1.48 185 salcianu 1.48 addStage(new RegularTreePass()); 186 salcianu 1.48 187 salcianu 1.48 // special case: the DACache MIPS optimizations allocated 188 salcianu 1.48 // special DACache registers during this phase; I *think* that 189 salcianu 1.48 // we shouldn't touch the tree form after this allocation has 190 salcianu 1.48 // been done, which means it must be the very last thing we 191 salcianu 1.48 // do. In general, your tree form passes shouldn't be this 192 salcianu 1.48 // fragile! [CSA 08-apr-2003] 193 salcianu 1.48 addStage(new MIPSOptimizations.TreePass()); 194 salcianu 1.48 195 salcianu 1.54 // perform basic sanity checks on the produced tree form 196 salcianu 1.48 addStage(new RegularCompilerStageEZ("sanity-check-tree") { 197 salcianu 1.48 protected void real_action() { 198 salcianu 1.48 hcf = harpoon.Analysis.Tree.DerivationChecker.codeFactory(hcf); 199 salcianu 1.48 hcf = new CachingCodeFactory(hcf); 200 salcianu 1.48 } 201 salcianu 1.48 }); 202 salcianu 1.48 } 203 salcianu 1.48 204 salcianu 1.48 205 jwhaley 1.1.2.86 206 salcianu 1.48 // ADD YOUR OPTION CONSISTENCY TESTS HERE 207 salcianu 1.48 private static void checkOptionConsistency() { 208 salcianu 1.48 // Check for compatibility of precise gc options. 209 salcianu 1.48 if (PRECISEGC) 210 salcianu 1.48 assert (BACKEND == Backend.PRECISEC) : 211 salcianu 1.48 "Precise gc is only implemented for the precise C backend."; 212 salcianu 1.48 if (MULTITHREADED) { 213 salcianu 1.48 assert PRECISEGC || Realtime.REALTIME_JAVA : 214 salcianu 1.48 "Multi-threaded option is valid only for precise gc."; 215 salcianu 1.48 assert WriteBarriers.wbOptLevel == 0 : 216 salcianu 1.48 "Write barrier removal not supported " + 217 salcianu 1.48 "for multi-threaded programs."; 218 salcianu 1.48 } 219 salcianu 1.48 if (WriteBarriers.WRITEBARRIERS || WriteBarriers.DYNAMICWBS) 220 salcianu 1.48 assert PRECISEGC : 221 salcianu 1.48 "Write barrier options are valid only for precise gc."; 222 salcianu 1.40 } 223 salcianu 1.40 224 salcianu 1.40 225 salcianu 1.52 private static void parseOpts(String[] args, 226 cananian 1.58 List<Option> allOptions) { 227 salcianu 1.48 PRECISEGC = System.getProperty("harpoon.alloc.strategy", 228 salcianu 1.48 "malloc").equalsIgnoreCase("precise"); 229 salcianu 1.48 args = Option.parseOptions(allOptions, args); 230 salcianu 1.48 if(args.length != 0) { 231 salcianu 1.53 System.err.println("Don't know what to do with " + args[0]); 232 salcianu 1.53 System.err.println("Use option \"-h\" to find all options"); 233 salcianu 1.48 System.exit(1); 234 salcianu 1.42 } 235 salcianu 1.42 } 236 salcianu 1.42 237 salcianu 1.42 238 cananian 1.58 private static List<Option> getAllOptions() { 239 cananian 1.58 List<Option> opts = new LinkedList<Option>(); 240 cananian 1.58 Map<String,String> opt2stage = new HashMap<String,String>(); 241 cananian 1.62 for(CompilerStage stage : stages){ 242 salcianu 1.52 addOptions(stage, opts, opt2stage); 243 salcianu 1.48 } 244 salcianu 1.48 return opts; 245 salcianu 1.48 } 246 salcianu 1.48 247 salcianu 1.52 248 salcianu 1.52 private static void addOptions(CompilerStage stage, 249 cananian 1.58 List<Option> allOpts, 250 cananian 1.58 Map<String,String> opt2stage) { 251 cananian 1.62 for(Option option : stage.getOptions()) { 252 salcianu 1.48 String old_stage = 253 cananian 1.58 opt2stage.put(option.optionName(), stage.name()); 254 salcianu 1.48 if(old_stage != null) { 255 salcianu 1.48 System.err.println 256 salcianu 1.48 ("Ambiguity: Option " + option + 257 salcianu 1.48 " is defined in two compiler stages: " + 258 salcianu 1.52 old_stage + " and " + stage.name()); 259 salcianu 1.48 System.exit(1); 260 salcianu 1.48 } 261 salcianu 1.48 allOpts.add(option); 262 salcianu 1.42 } 263 salcianu 1.42 } 264 salcianu 1.42 265 salcianu 1.42 266 salcianu 1.48 // construct list of top level compiler options 267 cananian 1.58 private static List<Option> getTopLevelOptions() { 268 cananian 1.58 return Arrays.asList 269 cananian 1.58 (new Option[] { 270 cananian 1.58 new Option("c", "<class>", "Compile <class> (required)") { 271 cananian 1.58 public void action() { className = getArg(0); } 272 cananian 1.58 }, 273 cananian 1.58 new Option("r", "<rootSetFileName>", 274 salcianu 1.60 "Read additional roots (classes and/or methods) from file") { 275 cananian 1.58 public void action() { rootSetFilename = getArg(0); } 276 cananian 1.58 }, 277 cananian 1.58 new Option("b", "<backendName>", 278 cananian 1.58 "Supported backends are StrongARM (default), MIPS, Sparc, or PreciseC") { 279 cananian 1.58 public void action() { 280 cananian 1.58 BACKEND = Options.getBackendID(getArg(0)); 281 cananian 1.58 } 282 cananian 1.58 }, 283 cananian 1.58 new Option("F", "Enable standard optimizations") { 284 cananian 1.58 public void action() { OPTIMIZE = true; } 285 cananian 1.58 }, 286 cananian 1.58 new Option("l", "Loop Optimizations") { 287 cananian 1.58 public void action() { LOOPOPTIMIZE = true; } 288 cananian 1.58 }, 289 cananian 1.58 new Option("q", "Quiet mode (status messages not output)") { 290 cananian 1.58 public void action() { QUIET = true; } 291 cananian 1.58 }, 292 cananian 1.58 new Option("h", "Print help") { 293 cananian 1.58 public void action() { 294 cananian 1.58 SAMain.printHelp(System.out); 295 cananian 1.58 System.exit(1); 296 cananian 1.58 } 297 cananian 1.58 }, 298 cananian 1.58 new Option("m", "Multi-threading support for PreciseGC") { 299 cananian 1.58 public void action() { 300 cananian 1.58 MULTITHREADED = true; 301 cananian 1.58 System.out.println 302 cananian 1.58 ("Compiling with precise gc for multiple threads."); 303 cananian 1.58 } 304 cananian 1.58 }, 305 cananian 1.58 }); 306 salcianu 1.23 } 307 salcianu 1.23 308 salcianu 1.48 private static void printHelp(PrintStream ps) { 309 cananian 1.58 ps.println("Usage:\n\tjava "+SAMain.class.getName()+" <options>*"); 310 salcianu 1.52 ps.println("Options:"); 311 cananian 1.58 for(Iterator<CompilerStage> it = stages.iterator(); it.hasNext(); ) { 312 cananian 1.58 printStageOptions(it.next()); 313 salcianu 1.52 } 314 salcianu 1.52 } 315 salcianu 1.52 316 salcianu 1.52 private static void printStageOptions(CompilerStage stage) { 317 cananian 1.62 for(Option option : stage.getOptions()) { 318 salcianu 1.52 option.printHelp(System.out); 319 salcianu 1.48 } 320 pnkfelix 1.1.2.10 } 321 pnkfelix 1.1.2.10 322 salcianu 1.36 protected static void printHelp() { 323 salcianu 1.48 printHelp(System.out); 324 pnkfelix 1.1.2.13 } 325 pnkfelix 1.1.2.13 326 salcianu 1.48 protected static void message(String msg) { 327 salcianu 1.48 if(!QUIET) System.out.print(msg); 328 salcianu 1.48 } 329 salcianu 1.47 330 salcianu 1.48 protected static void messageln(String msg) { 331 salcianu 1.48 if(!QUIET) System.out.println(msg); 332 salcianu 1.46 } 333 salcianu 1.52 334 salcianu 1.52 335 salcianu 1.52 336 salcianu 1.53 private static class BuildInitialCompState extends RegularCompilerStageEZ { 337 salcianu 1.52 public BuildInitialCompState() { super("compiler-initialization"); } 338 cananian 1.58 public List<Option> getOptions() { return getTopLevelOptions(); } 339 salcianu 1.52 340 salcianu 1.52 protected void real_action() { 341 salcianu 1.52 // create an initial compiler state 342 salcianu 1.55 linker = new AbstractClassFixupRelinker(Loader.systemLinker); 343 salcianu 1.55 mainM = getMainMethod(linker); // main method 344 salcianu 1.55 frame = construct_frame(mainM); // target frame 345 salcianu 1.55 roots = getRoots(linker, mainM, frame); // set of roots 346 salcianu 1.52 } 347 salcianu 1.52 348 salcianu 1.52 // returns the main method of the program to compile 349 salcianu 1.52 private static HMethod getMainMethod(Linker linker) { 350 salcianu 1.52 // find main method 351 salcianu 1.52 HClass hcl = linker.forName(className); 352 salcianu 1.52 HMethod mainM; 353 salcianu 1.52 try { 354 salcianu 1.52 mainM = hcl.getDeclaredMethod("main","([Ljava/lang/String;)V"); 355 salcianu 1.52 } catch (NoSuchMethodError e) { 356 salcianu 1.52 throw new Error("Class " + className + " has no main method"); 357 salcianu 1.52 } 358 salcianu 1.52 assert mainM != null; 359 salcianu 1.52 assert Modifier.isStatic(mainM.getModifiers()) : 360 salcianu 1.52 "main is not static"; 361 salcianu 1.52 assert Modifier.isPublic(mainM.getModifiers()) : 362 salcianu 1.52 "main is not public"; 363 salcianu 1.52 364 salcianu 1.52 return mainM; 365 salcianu 1.52 } 366 salcianu 1.52 367 salcianu 1.52 368 salcianu 1.52 // constructs and returns the target Frame 369 salcianu 1.52 // the frame specifies the combination of target architecture, 370 salcianu 1.52 // runtime, and allocation strategy we want to use. 371 salcianu 1.52 // ADD YOUR FRAME SETTING CODE HERE 372 salcianu 1.52 private static Frame construct_frame(HMethod mainM) { 373 salcianu 1.52 Frame frame = Backend.getFrame(BACKEND, mainM, 374 salcianu 1.52 getAllocationStrategyFactory()); 375 salcianu 1.52 376 salcianu 1.52 // check the configuration of the runtime. 377 salcianu 1.52 // (in particular, the --with-precise-c option) 378 salcianu 1.52 if (BACKEND == Backend.PRECISEC) 379 salcianu 1.52 frame.getRuntime().configurationSet.add 380 salcianu 1.52 ("check_with_precise_c_needed"); 381 salcianu 1.52 else 382 salcianu 1.52 frame.getRuntime().configurationSet.add 383 salcianu 1.52 ("check_with_precise_c_not_needed"); 384 salcianu 1.52 385 salcianu 1.52 return frame; 386 salcianu 1.52 } 387 salcianu 1.52 388 salcianu 1.52 389 salcianu 1.52 // construct the set of roots for the program we compile 390 salcianu 1.52 static Set getRoots(Linker linker, HMethod mainM, Frame frame) { 391 salcianu 1.52 // ask the runtime which roots it requires. 392 salcianu 1.52 Set roots = new java.util.HashSet 393 salcianu 1.52 (frame.getRuntime().runtimeCallableMethods()); 394 salcianu 1.52 395 salcianu 1.52 // and our main method is a root, too... 396 salcianu 1.52 roots.add(mainM); 397 salcianu 1.52 398 salcianu 1.52 // load roots from file (if any) 399 salcianu 1.52 if (rootSetFilename!=null) 400 salcianu 1.52 addToRootSet(roots, rootSetFilename, linker); 401 salcianu 1.52 402 salcianu 1.52 // other optimization specific roots 403 salcianu 1.52 if (EventDrivenTransformation.EVENTDRIVEN) { 404 salcianu 1.52 roots.add(linker.forName 405 salcianu 1.52 ("harpoon.Analysis.ContBuilder.Scheduler") 406 salcianu 1.52 .getMethod("loop",new HClass[0])); 407 salcianu 1.52 } 408 salcianu 1.52 409 salcianu 1.52 if (Realtime.REALTIME_JAVA) 410 salcianu 1.52 roots.addAll(Realtime.getRoots(linker)); 411 salcianu 1.52 412 salcianu 1.52 return roots; 413 salcianu 1.52 } 414 salcianu 1.52 415 salcianu 1.52 private static void addToRootSet(final Set roots, 416 salcianu 1.52 final String fileName, 417 salcianu 1.52 final Linker linker) { 418 salcianu 1.52 try { 419 salcianu 1.52 ParseUtil.readResource(fileName, new ParseUtil.StringParser() { 420 salcianu 1.52 public void parseString(String s) 421 salcianu 1.52 throws ParseUtil.BadLineException { 422 salcianu 1.52 if (s.indexOf('(') < 0) // parse as class name. 423 salcianu 1.52 roots.add(ParseUtil.parseClass(linker, s)); 424 salcianu 1.52 else // parse as method name. 425 salcianu 1.52 roots.add(ParseUtil.parseMethod(linker, s)); 426 salcianu 1.52 } 427 salcianu 1.52 }); 428 salcianu 1.52 } catch(IOException ex) { 429 salcianu 1.52 System.err.println("Error reading " + fileName + ": " + ex); 430 salcianu 1.52 ex.printStackTrace(); 431 salcianu 1.52 System.exit(1); 432 salcianu 1.52 } 433 salcianu 1.52 } 434 salcianu 1.52 } 435 salcianu 1.52 436 salcianu 1.52 437 salcianu 1.52 private static AllocationStrategyFactory getAllocationStrategyFactory() { 438 salcianu 1.52 439 salcianu 1.52 return new AllocationStrategyFactory() { 440 salcianu 1.52 public AllocationStrategy getAllocationStrategy(Frame frame) { 441 salcianu 1.52 442 salcianu 1.52 System.out.print("Allocation strategy: "); 443 salcianu 1.52 444 salcianu 1.52 if(AllocationInstrCompStage.INSTRUMENT_ALLOCS && 445 salcianu 1.52 (AllocationInstrCompStage.INSTRUMENT_ALLOCS_TYPE == 2)) { 446 salcianu 1.52 System.out.println("InstrumentedAllocationStrategy"); 447 salcianu 1.52 return new harpoon.Instrumentation.AllocationStatistics. 448 salcianu 1.52 InstrumentedAllocationStrategy(frame); 449 salcianu 1.52 } 450 salcianu 1.52 451 salcianu 1.52 if(PreallocOpt.PREALLOC_OPT) { 452 salcianu 1.52 System.out.println("PreallocAllocationStrategy"); 453 salcianu 1.52 return new harpoon.Analysis.MemOpt. 454 salcianu 1.52 PreallocAllocationStrategy(frame); 455 salcianu 1.52 } 456 salcianu 1.52 457 salcianu 1.52 if(Realtime.REALTIME_JAVA) { 458 salcianu 1.52 System.out.println("RTJ"); 459 salcianu 1.52 return new harpoon.Analysis.Realtime. 460 salcianu 1.52 RealtimeAllocationStrategy(frame); 461 salcianu 1.52 } 462 salcianu 1.52 463 salcianu 1.52 String alloc_strategy = 464 cananian 1.56 System.getProperty("harpoon.alloc.strategy", "bdw"); 465 salcianu 1.52 466 salcianu 1.52 System.out.println(alloc_strategy); 467 salcianu 1.52 468 cananian 1.57 if (frame instanceof harpoon.Backend.PreciseC.Frame) { 469 cananian 1.57 // these strategies only work with the PreciseC backend 470 cananian 1.57 if(alloc_strategy.equalsIgnoreCase("nifty")) 471 cananian 1.57 return new harpoon.Backend.PreciseC. 472 cananian 1.57 PGCNiftyAllocationStrategy(frame); 473 cananian 1.57 474 cananian 1.57 if(alloc_strategy.equalsIgnoreCase("niftystats")) 475 cananian 1.57 return new harpoon.Backend.PreciseC. 476 cananian 1.57 PGCNiftyAllocationStrategyWithStats(frame); 477 cananian 1.57 } else { 478 cananian 1.57 // non-precisec version of the 'nifty' alloc strategy 479 cananian 1.57 if(alloc_strategy.equalsIgnoreCase("nifty")) 480 cananian 1.57 return new harpoon.Backend.Runtime1. 481 cananian 1.57 NiftyAllocationStrategy(frame); 482 cananian 1.57 } 483 salcianu 1.52 484 salcianu 1.52 if(alloc_strategy.equalsIgnoreCase("bdw")) 485 salcianu 1.52 return new harpoon.Backend.Runtime1. 486 salcianu 1.52 BDWAllocationStrategy(frame); 487 salcianu 1.52 488 salcianu 1.52 if(alloc_strategy.equalsIgnoreCase("sp")) 489 salcianu 1.52 return new harpoon.Backend.Runtime1. 490 salcianu 1.52 SPAllocationStrategy(frame); 491 salcianu 1.52 492 salcianu 1.52 if(alloc_strategy.equalsIgnoreCase("precise")) 493 salcianu 1.52 return new harpoon.Backend.Runtime1. 494 salcianu 1.52 MallocAllocationStrategy(frame, "precise_malloc"); 495 salcianu 1.52 496 salcianu 1.52 if(alloc_strategy.equalsIgnoreCase("heapstats")) 497 salcianu 1.52 return new harpoon.Backend.Runtime1. 498 salcianu 1.52 HeapStatsAllocationStrategy(frame); 499 salcianu 1.52 500 salcianu 1.54 assert alloc_strategy.equalsIgnoreCase("malloc") : 501 salcianu 1.54 "unknown allocation strategy " + alloc_strategy; 502 salcianu 1.52 503 salcianu 1.52 // default, "malloc" strategy. 504 salcianu 1.52 return 505 salcianu 1.52 new harpoon.Backend.Runtime1.MallocAllocationStrategy 506 salcianu 1.52 (frame, 507 salcianu 1.52 System.getProperty("harpoon.alloc.func", "malloc")); 508 salcianu 1.52 } 509 salcianu 1.52 }; 510 salcianu 1.52 }; 511 salcianu 1.52 512 salcianu 1.52 513 salcianu 1.40 514 salcianu 1.48 private static class BuildQuadForm extends RegularCompilerStageEZ { 515 salcianu 1.48 public BuildQuadForm() { super("build-quad-form"); } 516 salcianu 1.53 517 salcianu 1.48 protected void real_action() { 518 salcianu 1.48 // default code factory. 519 salcianu 1.48 hcf = new CachingCodeFactory 520 salcianu 1.48 (harpoon.IR.Quads.QuadWithTry.codeFactory()); 521 salcianu 1.48 522 salcianu 1.48 // the new mover will try to put NEWs closer to their 523 salcianu 1.48 // constructors. in the words of a PLDI paper, this 524 salcianu 1.48 // reduces "drag time". it also improves some analysis 525 salcianu 1.48 // results. =) 526 salcianu 1.48 hcf = new harpoon.Analysis.Quads.NewMover(hcf).codeFactory(); 527 salcianu 1.48 528 salcianu 1.48 if (Realtime.REALTIME_JAVA) 529 salcianu 1.48 Realtime.setupObject(linker); 530 salcianu 1.48 531 salcianu 1.48 if(PreallocOpt.PREALLOC_OPT) { 532 salcianu 1.48 PreallocOpt.updateRoots(roots, linker); 533 salcianu 1.48 hcf = PreallocOpt.getHCFWithEmptyInitCode(hcf); 534 salcianu 1.48 } 535 salcianu 1.48 536 salcianu 1.48 // make a rough class hierarchy. 537 salcianu 1.40 hcf = new CachingCodeFactory(hcf); 538 salcianu 1.40 classHierarchy = new QuadClassHierarchy(linker, roots, hcf); 539 salcianu 1.48 540 salcianu 1.48 // use the rough class hierarchy to devirtualize as many call 541 salcianu 1.48 // sites as possible. 542 salcianu 1.48 hcf = new harpoon.Analysis.Quads.Nonvirtualize 543 salcianu 1.48 (hcf, new harpoon.Backend.Maps.CHFinalMap(classHierarchy), 544 salcianu 1.48 classHierarchy).codeFactory(); 545 salcianu 1.48 546 salcianu 1.48 handle_class_initializers(); 547 salcianu 1.48 } 548 salcianu 1.48 549 salcianu 1.48 // Class initialization is delicate in an ahead of time compiler. 550 salcianu 1.48 // The JVM deals with it by explicitly testing before each each 551 salcianu 1.48 // class member access whether the class is initialized or not; we 552 salcianu 1.48 // try to be more effcient: we run the initializers of all the 553 salcianu 1.48 // classes from the program before the main method. Only the code 554 salcianu 1.48 // of the static initializers checks for un-initialized classes; 555 salcianu 1.48 // when the main method is called, all the relevant classes have 556 salcianu 1.48 // been initialized. 557 salcianu 1.48 private void handle_class_initializers() { 558 salcianu 1.55 // transform the class initializers using the class hierarchy. 559 salcianu 1.55 String resource = frame.getRuntime().resourcePath 560 salcianu 1.55 ("init-safe.properties"); 561 salcianu 1.55 hcf = new harpoon.Analysis.Quads.InitializerTransform 562 salcianu 1.55 (hcf, classHierarchy, linker, resource).codeFactory(); 563 salcianu 1.55 // recompute the hierarchy after transformation. 564 salcianu 1.55 hcf = new CachingCodeFactory(hcf); 565 salcianu 1.55 classHierarchy = new QuadClassHierarchy(linker, roots, hcf); 566 salcianu 1.55 // config checking 567 salcianu 1.55 frame.getRuntime().configurationSet.add 568 salcianu 1.55 ("check_with_init_check_needed"); 569 salcianu 1.40 } 570 salcianu 1.40 } 571 salcianu 1.40 572 salcianu 1.40 573 salcianu 1.48 private static class RegularQuadPass extends RegularCompilerStageEZ { 574 salcianu 1.48 public RegularQuadPass() { super("regular-quad-pass"); } 575 salcianu 1.48 576 salcianu 1.48 protected void real_action() { 577 salcianu 1.48 // now we can finally set the (final?) classHierarchy and 578 salcianu 1.48 // callGraph which the frame will use (among other things, 579 salcianu 1.48 // for vtable numbering) 580 salcianu 1.48 frame.setClassHierarchy(classHierarchy); 581 salcianu 1.51 582 salcianu 1.48 // virtualize any uncallable methods using the final classhierarchy 583 salcianu 1.48 // (this keeps us from later getting link errors) 584 salcianu 1.48 hcf = new harpoon.Analysis.Quads.Virtualize(hcf, classHierarchy) 585 salcianu 1.48 .codeFactory(); 586 salcianu 1.48 // non-virtualize any final methods -- this used to be done 587 salcianu 1.48 // in the low-quad translation, but doing so is unsafe unless 588 salcianu 1.48 // you've got a classHierarchy handy -- you could inadventently 589 salcianu 1.48 // create a new dangling reference to an uncallable method. 590 salcianu 1.48 hcf = new harpoon.Analysis.Quads.Nonvirtualize 591 salcianu 1.48 (hcf, new harpoon.Backend.Maps.CHFinalMap(classHierarchy), 592 salcianu 1.48 classHierarchy).codeFactory(); 593 salcianu 1.48 594 salcianu 1.48 if (LOOPOPTIMIZE) 595 salcianu 1.48 loop_optimizations(); 596 salcianu 1.48 597 salcianu 1.48 hcf = harpoon.IR.LowQuad.LowQuadSSA.codeFactory(hcf); 598 salcianu 1.48 } 599 salcianu 1.48 600 salcianu 1.48 private void loop_optimizations() { 601 salcianu 1.48 // XXX: you might have to add a TypeSwitchRemover here, if 602 salcianu 1.48 // LoopOptimize doesn't handle TYPESWITCHes. --CSA 603 salcianu 1.48 System.out.println("Loop Optimizations On"); 604 salcianu 1.48 hcf = harpoon.IR.LowQuad.LowQuadSSI.codeFactory(hcf); 605 salcianu 1.48 hcf = harpoon.Analysis.LowQuad.Loop.LoopOptimize.codeFactory(hcf); 606 salcianu 1.48 hcf = harpoon.Analysis.LowQuad.DerivationChecker.codeFactory(hcf); 607 salcianu 1.40 } 608 salcianu 1.40 } 609 salcianu 1.40 610 salcianu 1.40 611 salcianu 1.48 // 1. sparse (i.e., SSI) conditional constant propagation 612 salcianu 1.48 // 2. represent native method arraycopy into quad IR (such that 613 salcianu 1.48 // we can optimize it) 614 salcianu 1.48 // 3. inline small methods 615 salcianu 1.48 private static class GeneralQuadOptimizations extends CompilerStageEZ { 616 salcianu 1.48 public GeneralQuadOptimizations() { 617 salcianu 1.48 super("general-quad-optimizations"); 618 salcianu 1.48 } 619 salcianu 1.48 620 salcianu 1.53 public boolean enabled() { return OPTIMIZE; } 621 salcianu 1.48 622 salcianu 1.48 public void real_action() { 623 salcianu 1.48 // COMMENTED UNTIL BUG DISCOVERED 624 salcianu 1.48 /* 625 salcianu 1.48 hcf = new harpoon.Analysis.Quads.DispatchTreeTransformation 626 salcianu 1.48 (hcf, classHierarchy).codeFactory(); 627 salcianu 1.48 */ 628 salcianu 1.48 hcf = harpoon.IR.Quads.QuadSSI.codeFactory(hcf); 629 salcianu 1.48 hcf = harpoon.Analysis.Quads.SCC.SCCOptimize.codeFactory(hcf); 630 salcianu 1.48 hcf = harpoon.IR.Quads.QuadSSA.codeFactory(hcf); 631 salcianu 1.48 if (Boolean.getBoolean("harpoon.inline.arraycopy")) { 632 salcianu 1.48 // inline System.arraycopy in particular. 633 salcianu 1.48 hcf = new harpoon.Analysis.Transactions.ArrayCopyImplementer 634 salcianu 1.48 (hcf, linker); 635 salcianu 1.48 hcf = new CachingCodeFactory(hcf); 636 salcianu 1.48 classHierarchy = new QuadClassHierarchy(linker, roots, hcf); 637 salcianu 1.48 hcf = new harpoon.Analysis.Quads.ArrayCopyInliner 638 salcianu 1.48 (hcf, classHierarchy); 639 salcianu 1.48 } else { 640 salcianu 1.48 // TODO: why is there a XOR between these two optimizations? 641 salcianu 1.48 // just inline small methods. 642 salcianu 1.48 hcf = new harpoon.Analysis.Quads.SmallMethodInliner 643 salcianu 1.48 (hcf, classHierarchy); 644 salcianu 1.48 } 645 salcianu 1.48 hcf = harpoon.IR.Quads.QuadSSI.codeFactory(hcf); 646 salcianu 1.48 hcf = harpoon.Analysis.Quads.SCC.SCCOptimize.codeFactory(hcf); 647 salcianu 1.48 hcf = new harpoon.ClassFile.CachingCodeFactory(hcf); 648 salcianu 1.40 } 649 salcianu 1.40 } 650 salcianu 1.40 651 salcianu 1.48 652 salcianu 1.48 private static class LowQuadToTree extends RegularCompilerStageEZ { 653 salcianu 1.48 public LowQuadToTree() { super("lowquad-to-tree"); } 654 salcianu 1.40 655 salcianu 1.48 protected void real_action() { 656 salcianu 1.48 // low quad -> tree form 657 salcianu 1.48 // XXX: ToTree doesn't handle TYPESWITCHes right now. 658 salcianu 1.48 hcf = 659 salcianu 1.48 new harpoon.Analysis.Quads.TypeSwitchRemover(hcf). 660 salcianu 1.48 codeFactory(); 661 salcianu 1.48 hcf = harpoon.IR.Tree.TreeCode.codeFactory(hcf, frame); 662 salcianu 1.48 // Implement the native method call interface. (JNI) 663 salcianu 1.48 hcf = frame.getRuntime().nativeTreeCodeFactory(hcf); 664 salcianu 1.48 // put it in canonical form 665 salcianu 1.48 hcf = harpoon.IR.Tree.CanonicalTreeCode.codeFactory(hcf, frame); 666 salcianu 1.48 // sanity check 667 salcianu 1.48 hcf = harpoon.Analysis.Tree.DerivationChecker.codeFactory(hcf); 668 salcianu 1.47 } 669 salcianu 1.47 } 670 salcianu 1.47 671 salcianu 1.48 672 salcianu 1.48 private static class RegularTreePass extends RegularCompilerStageEZ { 673 salcianu 1.48 public RegularTreePass() { super("regular-tree-pass"); } 674 salcianu 1.48 675 salcianu 1.48 protected void real_action() { 676 salcianu 1.48 if (MULTITHREADED) /* pass to insert GC polling calls */ 677 salcianu 1.48 hcf = harpoon.Backend.Analysis.MakeGCThreadSafe. 678 salcianu 1.48 codeFactory(hcf, frame); 679 salcianu 1.48 680 salcianu 1.48 // -- general tree form optimizations -- 681 salcianu 1.48 682 salcianu 1.48 hcf = 683 salcianu 1.48 harpoon.Analysis.Tree.AlgebraicSimplification.codeFactory(hcf); 684 salcianu 1.48 685 salcianu 1.48 // CSA 08-apr-2003: this code was turned off in feb 17, 2000 with 686 salcianu 1.48 // the comment: "Turn off DeadCodeElimination, as it seems to be 687 salcianu 1.48 // generating bogus code --- removing too many moves?" 688 salcianu 1.48 // Hopefully this bug will be fixed soon and this pass re-enabled. 689 salcianu 1.48 //hcf = harpoon.Analysis.Tree.DeadCodeElimination.codeFactory(hcf); 690 salcianu 1.48 691 salcianu 1.48 // CSA 07-11-2002: Temporarily turn off JumpOptimization. It 692 salcianu 1.48 // has a bug but I can't get the assertion to fail anymore. 693 salcianu 1.48 // demo.grid.Server from the JacORB 1.3.30 distribution 694 salcianu 1.48 // compiles to an infinite loop with JumpOptimization enabled, 695 salcianu 1.48 // however. 696 salcianu 1.48 //hcf = harpoon.Analysis.Tree.JumpOptimization.codeFactory(hcf); 697 salcianu 1.40 } 698 salcianu 1.43 } 699 cananian 1.2 }