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.ir.IR;
018 import org.jikesrvm.runtime.Time;
019
020 /**
021 * An element in the opt compiler's optimization plan
022 * that consists of a single CompilerPhase.
023 *
024 * <p> NOTE: Instances of this class are
025 * held in <code> OptimizationPlanner.masterPlan </code>
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 final class OptimizationPlanAtomicElement extends OptimizationPlanElement {
032 /**
033 * The phase to be performed.
034 */
035 private final CompilerPhase myPhase;
036 /**
037 * Accumulated nanoseconds spent in the element.
038 */
039 protected long phaseNanos = 0;
040
041 /**
042 * Counters to be used by myPhase to gather phase specific stats.
043 */
044 public double counter1, counter2;
045
046 /**
047 * Create a plan element corresponding to a particular compiler phase.
048 * @param p
049 */
050 public OptimizationPlanAtomicElement(CompilerPhase p) {
051 myPhase = p;
052 p.setContainer(this);
053 }
054
055 /**
056 * Update this phase to support the measuring of compilation
057 */
058 public void initializeForMeasureCompilation() {
059 counter1 = 0;
060 counter2 = 0;
061 }
062
063 /**
064 * Determine, possibly by consulting the passed options object,
065 * if this optimization plan element should be performed.
066 *
067 * @param options The Options object for the current compilation.
068 * @return true if the plan element should be performed.
069 */
070 public boolean shouldPerform(OptOptions options) {
071 return myPhase.shouldPerform(options);
072 }
073
074 /**
075 * Do the work represented by this element in the optimization plan.
076 * The assumption is that the work will modify the IR in some way.
077 *
078 * @param ir The IR object to work with.
079 */
080 public void perform(IR ir) {
081 long start = 0;
082 try {
083 if (VM.MeasureCompilationPhases && VM.runningVM) {
084 start = Time.nanoTime();
085 }
086 CompilerPhase cmpPhase = myPhase.newExecution(ir);
087 cmpPhase.setContainer(this);
088 cmpPhase.performPhase(ir);
089 } finally {
090 if (VM.MeasureCompilationPhases && VM.runningVM) {
091 long end = Time.nanoTime();
092 phaseNanos += end - start;
093 }
094 }
095 }
096
097 /**
098 * @return a String which is the name of the phase.
099 */
100 public String getName() {
101 return myPhase.getName();
102 }
103
104 /**
105 * Generate (to the sysWrite stream) a report of the
106 * time spent performing this element of the optimization plan.
107 *
108 * @param indent Number of spaces to indent report.
109 * @param timeCol Column number of time portion of report.
110 * @param totalTime Total opt compilation time in ms.
111 */
112 public void reportStats(int indent, int timeCol, double totalTime) {
113 if (phaseNanos == 0) return;
114 int curCol = 0;
115 for (curCol = 0; curCol < indent; curCol++) {
116 VM.sysWrite(" ");
117 }
118 String name = myPhase.getName();
119 int namePtr = 0;
120 while (curCol < timeCol && namePtr < name.length()) {
121 VM.sysWrite(name.charAt(namePtr));
122 namePtr++;
123 curCol++;
124 }
125 while (curCol < timeCol) {
126 VM.sysWrite(" ");
127 curCol++;
128 }
129 double myTime = Time.nanosToMillis(phaseNanos);
130 prettyPrintTime(myTime, totalTime);
131 myPhase.reportAdditionalStats();
132 VM.sysWriteln();
133 }
134
135 /**
136 * Report the total time spent executing the PlanElement
137 * @return time spend in the plan (in ms)
138 */
139 public double elapsedTime() {
140 return Time.nanosToMillis(phaseNanos);
141 }
142 }