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    }