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      @Override
059      public void initializeForMeasureCompilation() {
060        counter1 = 0;
061        counter2 = 0;
062      }
063    
064      @Override
065      public boolean shouldPerform(OptOptions options) {
066        return myPhase.shouldPerform(options);
067      }
068    
069      @Override
070      public void perform(IR ir) {
071        long start = 0;
072        try {
073          if (VM.MeasureCompilationPhases && VM.runningVM) {
074            start = Time.nanoTime();
075          }
076          CompilerPhase cmpPhase = myPhase.newExecution(ir);
077          cmpPhase.setContainer(this);
078          cmpPhase.performPhase(ir);
079        } finally {
080          if (VM.MeasureCompilationPhases && VM.runningVM) {
081            long end = Time.nanoTime();
082            phaseNanos += end - start;
083          }
084        }
085      }
086    
087      @Override
088      public String getName() {
089        return myPhase.getName();
090      }
091    
092      @Override
093      public void reportStats(int indent, int timeCol, double totalTime) {
094        if (phaseNanos == 0) return;
095        int curCol = 0;
096        for (curCol = 0; curCol < indent; curCol++) {
097          VM.sysWrite(" ");
098        }
099        String name = myPhase.getName();
100        int namePtr = 0;
101        while (curCol < timeCol && namePtr < name.length()) {
102          VM.sysWrite(name.charAt(namePtr));
103          namePtr++;
104          curCol++;
105        }
106        while (curCol < timeCol) {
107          VM.sysWrite(" ");
108          curCol++;
109        }
110        double myTime = Time.nanosToMillis(phaseNanos);
111        prettyPrintTime(myTime, totalTime);
112        myPhase.reportAdditionalStats();
113        VM.sysWriteln();
114      }
115    
116      @Override
117      public double elapsedTime() {
118        return Time.nanosToMillis(phaseNanos);
119      }
120    }