001 /*
002 * This file is part of the Jikes RVM project (http://jikesrvm.org).
003 *
004 * This file is licensed to You under the Eclipse Public License (EPL);
005 * You may not use this file except in compliance with the License. You
006 * may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/eclipse-1.0.php
009 *
010 * See the COPYRIGHT.txt file distributed with this work for information
011 * regarding copyright ownership.
012 */
013 package org.jikesrvm.compilers.opt.driver;
014
015 import org.jikesrvm.VM;
016 import org.jikesrvm.compilers.opt.OptOptions;
017 import org.jikesrvm.compilers.opt.OptimizingCompilerException;
018 import org.jikesrvm.compilers.opt.ir.IR;
019
020 /**
021 * An element in the opt compiler's optimzation plan
022 * that aggregates together other OptimizationPlan elements.
023 *
024 * NOTE: Instances of subclasses of this class are
025 * held in OptimizationPlanner.masterPlan
026 * and thus represent global state.
027 * It is therefore incorrect for any per-compilation
028 * state to be stored in an instance field of
029 * one of these objects.
030 */
031 public class OptimizationPlanCompositeElement extends OptimizationPlanElement {
032 /**
033 * Name of this element.
034 */
035 private final String myName;
036 /**
037 * Ordered list of elements that together comprise this element.
038 */
039 private final OptimizationPlanElement[] myElements;
040
041 /**
042 * Compose together the argument elements into a composite element
043 * of an optimization plan.
044 *
045 * @param n The name for this phase
046 * @param e The elements to compose
047 */
048 public OptimizationPlanCompositeElement(String n, OptimizationPlanElement[] e) {
049 myName = n;
050 myElements = e;
051 }
052
053 /**
054 * Compose together the argument elements into a composite element
055 * of an optimization plan.
056 *
057 * @param n The name for this phase
058 * @param e The elements to compose
059 */
060 public OptimizationPlanCompositeElement(String n, Object[] e) {
061 myName = n;
062 myElements = new OptimizationPlanElement[e.length];
063 for (int i = 0; i < e.length; i++) {
064 if (e[i] instanceof OptimizationPlanElement) {
065 myElements[i] = (OptimizationPlanElement) (e[i]);
066 } else if (e[i] instanceof CompilerPhase) {
067 myElements[i] = new OptimizationPlanAtomicElement((CompilerPhase) e[i]);
068 } else {
069 throw new OptimizingCompilerException("Unsupported plan element " + e[i]);
070 }
071 }
072 }
073
074 /**
075 * This method is called to initialize the optimization plan support
076 * measuring compilation.
077 */
078 public void initializeForMeasureCompilation() {
079 // initialize each composite object
080 for (OptimizationPlanElement myElement : myElements) {
081 myElement.initializeForMeasureCompilation();
082 }
083 }
084
085 /**
086 * Compose together the argument elements into a composite element
087 * of an optimization plan.
088 *
089 * @param name The name associated with this composite.
090 * @param elems An Object[] of CompilerPhases or
091 * OptimizationPlanElements to be composed
092 * @return an OptimizationPlanCompositeElement that
093 * represents the composition.
094 */
095 public static OptimizationPlanCompositeElement compose(String name, Object[] elems) {
096 return new OptimizationPlanCompositeElement(name, elems);
097 }
098
099 /**
100 * Determine, possibly by consulting the passed options object,
101 * if this optimization plan element should be performed.
102 *
103 * @param options The Options object for the current compilation.
104 * @return true if the plan element should be performed.
105 */
106 public boolean shouldPerform(OptOptions options) {
107 for (OptimizationPlanElement myElement : myElements) {
108 if (myElement.shouldPerform(options)) {
109 return true;
110 }
111 }
112 return false;
113 }
114
115 /**
116 * Returns true if the phase wants the IR dumped before and/or after it runs.
117 * By default, printing is not enabled.
118 * Subclasses should overide this method if they want to provide IR dumping.
119 *
120 * @param options the compiler options for the compilation
121 * @param before true when invoked before perform, false otherwise.
122 * @return true if the IR should be printed, false otherwise.
123 */
124 public boolean printingEnabled(OptOptions options, boolean before) {
125 return false;
126 }
127
128 /**
129 * Do the work represented by this element in the optimization plan.
130 * The assumption is that the work will modify the IR in some way.
131 *
132 * @param ir The IR object to work with.
133 */
134 public final void perform(IR ir) {
135 if (printingEnabled(ir.options, true)) {
136 if (!ir.options.hasMETHOD_TO_PRINT() || ir.options.fuzzyMatchMETHOD_TO_PRINT(ir.method.toString())) {
137 CompilerPhase.dumpIR(ir, "Before " + getName());
138 }
139 }
140
141 for (OptimizationPlanElement myElement : myElements) {
142 if (myElement.shouldPerform(ir.options)) {
143 myElement.perform(ir);
144 }
145 }
146
147 if (printingEnabled(ir.options, false)) {
148 if (!ir.options.hasMETHOD_TO_PRINT() || ir.options.fuzzyMatchMETHOD_TO_PRINT(ir.method.toString())) {
149 CompilerPhase.dumpIR(ir, "After " + getName());
150 }
151 }
152 }
153
154 /**
155 * @return a String which is the name of the phase.
156 */
157 public String getName() {
158 return myName;
159 }
160
161 /**
162 * Generate (to the sysWrite stream) a report of the
163 * time spent performing this element of the optimization plan.
164 *
165 * @param indent Number of spaces to indent report.
166 * @param timeCol Column number of time portion of report.
167 * @param totalTime Total opt compilation time in seconds.
168 */
169 public final void reportStats(int indent, int timeCol, double totalTime) {
170 double myTime = elapsedTime();
171 if (myTime < 0.000001) {
172 return;
173 }
174 // (1) Print header.
175 int curCol = 0;
176 for (curCol = 0; curCol < indent; curCol++) {
177 VM.sysWrite(" ");
178 }
179 int myNamePtr = 0;
180 while (curCol < timeCol && myNamePtr < myName.length()) {
181 VM.sysWrite(myName.charAt(myNamePtr));
182 myNamePtr++;
183 curCol++;
184 }
185 VM.sysWrite("\n");
186 // (2) print elements
187 for (OptimizationPlanElement myElement : myElements) {
188 myElement.reportStats(indent + 4, timeCol, totalTime);
189 }
190 // (3) print total
191 curCol = 0;
192 for (curCol = 0; curCol < indent + 4; curCol++) {
193 VM.sysWrite(" ");
194 }
195 VM.sysWrite("TOTAL ");
196 curCol += 6;
197 while (curCol < timeCol) {
198 VM.sysWrite(" ");
199 curCol++;
200 }
201 prettyPrintTime(myTime, totalTime);
202 VM.sysWriteln();
203 }
204
205 /**
206 * Report the elapsed time spent in the PlanElement
207 * @return time spend in the plan (in seconds)
208 */
209 public double elapsedTime() {
210 double total = 0.0;
211 for (OptimizationPlanElement myElement : myElements) {
212 total += myElement.elapsedTime();
213 }
214 return total;
215 }
216 }