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 */
013package org.jikesrvm.compilers.opt.driver;
014
015import org.jikesrvm.VM;
016import org.jikesrvm.compilers.opt.OptOptions;
017import org.jikesrvm.compilers.opt.ir.IR;
018import 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 */
031public 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  public OptimizationPlanAtomicElement(CompilerPhase p) {
047    myPhase = p;
048    p.setContainer(this);
049  }
050
051  /**
052   * Update this phase to support the measuring of compilation
053   */
054  @Override
055  public void initializeForMeasureCompilation() {
056    counter1 = 0;
057    counter2 = 0;
058  }
059
060  @Override
061  public boolean shouldPerform(OptOptions options) {
062    return myPhase.shouldPerform(options);
063  }
064
065  @Override
066  public void perform(IR ir) {
067    long start = 0;
068    try {
069      if (VM.MeasureCompilationPhases && VM.runningVM) {
070        start = Time.nanoTime();
071      }
072      CompilerPhase cmpPhase = myPhase.newExecution(ir);
073      cmpPhase.setContainer(this);
074      cmpPhase.performPhase(ir);
075    } finally {
076      if (VM.MeasureCompilationPhases && VM.runningVM) {
077        long end = Time.nanoTime();
078        phaseNanos += end - start;
079      }
080    }
081  }
082
083  @Override
084  public String getName() {
085    return myPhase.getName();
086  }
087
088  @Override
089  public void reportStats(int indent, int timeCol, double totalTime) {
090    if (phaseNanos == 0) return;
091    int curCol = 0;
092    for (curCol = 0; curCol < indent; curCol++) {
093      VM.sysWrite(" ");
094    }
095    String name = myPhase.getName();
096    int namePtr = 0;
097    while (curCol < timeCol && namePtr < name.length()) {
098      VM.sysWrite(name.charAt(namePtr));
099      namePtr++;
100      curCol++;
101    }
102    while (curCol < timeCol) {
103      VM.sysWrite(" ");
104      curCol++;
105    }
106    double myTime = Time.nanosToMillis(phaseNanos);
107    prettyPrintTime(myTime, totalTime);
108    myPhase.reportAdditionalStats();
109    VM.sysWriteln();
110  }
111
112  @Override
113  public double elapsedTime() {
114    return Time.nanosToMillis(phaseNanos);
115  }
116}