/* * This file is part of the Jikes RVM project (http://jikesrvm.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. You * may obtain a copy of the License at * * http://www.opensource.org/licenses/eclipse-1.0.php * * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. */ package org.jikesrvm.compilers.opt.driver; import org.jikesrvm.VM; import org.jikesrvm.compilers.opt.OptOptions; import org.jikesrvm.compilers.opt.OptimizingCompilerException; import org.jikesrvm.compilers.opt.ir.IR; /** * An element in the opt compiler's optimzation plan * that aggregates together other OptimizationPlan elements. * * NOTE: Instances of subclasses of this class are * held in OptimizationPlanner.masterPlan * and thus represent global state. * It is therefore incorrect for any per-compilation * state to be stored in an instance field of * one of these objects. */ public class OptimizationPlanCompositeElement extends OptimizationPlanElement { /** * Name of this element. */ private final String myName; /** * Ordered list of elements that together comprise this element. */ private final OptimizationPlanElement[] myElements; /** * Compose together the argument elements into a composite element * of an optimization plan. * * @param n The name for this phase * @param e The elements to compose */ public OptimizationPlanCompositeElement(String n, OptimizationPlanElement[] e) { myName = n; myElements = e; } /** * Compose together the argument elements into a composite element * of an optimization plan. * * @param n The name for this phase * @param e The elements to compose */ public OptimizationPlanCompositeElement(String n, Object[] e) { myName = n; myElements = new OptimizationPlanElement[e.length]; for (int i = 0; i < e.length; i++) { if (e[i] instanceof OptimizationPlanElement) { myElements[i] = (OptimizationPlanElement) (e[i]); } else if (e[i] instanceof CompilerPhase) { myElements[i] = new OptimizationPlanAtomicElement((CompilerPhase) e[i]); } else { throw new OptimizingCompilerException("Unsupported plan element " + e[i]); } } } /** * This method is called to initialize the optimization plan support * measuring compilation. */ public void initializeForMeasureCompilation() { // initialize each composite object for (OptimizationPlanElement myElement : myElements) { myElement.initializeForMeasureCompilation(); } } /** * Compose together the argument elements into a composite element * of an optimization plan. * * @param name The name associated with this composite. * @param elems An Object[] of CompilerPhases or * OptimizationPlanElements to be composed * @return an OptimizationPlanCompositeElement that * represents the composition. */ public static OptimizationPlanCompositeElement compose(String name, Object[] elems) { return new OptimizationPlanCompositeElement(name, elems); } /** * Determine, possibly by consulting the passed options object, * if this optimization plan element should be performed. * * @param options The Options object for the current compilation. * @return true if the plan element should be performed. */ public boolean shouldPerform(OptOptions options) { for (OptimizationPlanElement myElement : myElements) { if (myElement.shouldPerform(options)) { return true; } } return false; } /** * Returns true if the phase wants the IR dumped before and/or after it runs. * By default, printing is not enabled. * Subclasses should overide this method if they want to provide IR dumping. * * @param options the compiler options for the compilation * @param before true when invoked before perform, false otherwise. * @return true if the IR should be printed, false otherwise. */ public boolean printingEnabled(OptOptions options, boolean before) { return false; } /** * Do the work represented by this element in the optimization plan. * The assumption is that the work will modify the IR in some way. * * @param ir The IR object to work with. */ public final void perform(IR ir) { if (printingEnabled(ir.options, true)) { if (!ir.options.hasMETHOD_TO_PRINT() || ir.options.fuzzyMatchMETHOD_TO_PRINT(ir.method.toString())) { CompilerPhase.dumpIR(ir, "Before " + getName()); } } for (OptimizationPlanElement myElement : myElements) { if (myElement.shouldPerform(ir.options)) { myElement.perform(ir); } } if (printingEnabled(ir.options, false)) { if (!ir.options.hasMETHOD_TO_PRINT() || ir.options.fuzzyMatchMETHOD_TO_PRINT(ir.method.toString())) { CompilerPhase.dumpIR(ir, "After " + getName()); } } } /** * @return a String which is the name of the phase. */ public String getName() { return myName; } /** * Generate (to the sysWrite stream) a report of the * time spent performing this element of the optimization plan. * * @param indent Number of spaces to indent report. * @param timeCol Column number of time portion of report. * @param totalTime Total opt compilation time in seconds. */ public final void reportStats(int indent, int timeCol, double totalTime) { double myTime = elapsedTime(); if (myTime < 0.000001) { return; } // (1) Print header. int curCol = 0; for (curCol = 0; curCol < indent; curCol++) { VM.sysWrite(" "); } int myNamePtr = 0; while (curCol < timeCol && myNamePtr < myName.length()) { VM.sysWrite(myName.charAt(myNamePtr)); myNamePtr++; curCol++; } VM.sysWrite("\n"); // (2) print elements for (OptimizationPlanElement myElement : myElements) { myElement.reportStats(indent + 4, timeCol, totalTime); } // (3) print total curCol = 0; for (curCol = 0; curCol < indent + 4; curCol++) { VM.sysWrite(" "); } VM.sysWrite("TOTAL "); curCol += 6; while (curCol < timeCol) { VM.sysWrite(" "); curCol++; } prettyPrintTime(myTime, totalTime); VM.sysWriteln(); } /** * Report the elapsed time spent in the PlanElement * @return time spend in the plan (in seconds) */ public double elapsedTime() { double total = 0.0; for (OptimizationPlanElement myElement : myElements) { total += myElement.elapsedTime(); } return total; } }