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.controlflow;
014    
015    import java.lang.reflect.Constructor;
016    
017    import org.jikesrvm.compilers.opt.OperationNotImplementedException;
018    import org.jikesrvm.compilers.opt.OptOptions;
019    import org.jikesrvm.compilers.opt.driver.CompilerPhase;
020    import org.jikesrvm.compilers.opt.driver.OptimizingCompiler;
021    import org.jikesrvm.compilers.opt.ir.IR;
022    
023    /**
024     * Driver routine for dominator computation.  This phase invokes
025     * the Lengauer-Tarjan dominator calculation.
026     */
027    public final class DominatorsPhase extends CompilerPhase {
028    
029      /**
030       * Should we unfactor the CFG?
031       */
032      private final boolean unfactor;
033    
034      /**
035       * @param unfactor Should we unfactor the CFG before computing
036       * dominators?
037       */
038      public DominatorsPhase(boolean unfactor) {
039        super(new Object[]{unfactor});
040        this.unfactor = unfactor;
041      }
042    
043      /**
044       * Constructor for this compiler phase
045       */
046      private static final Constructor<CompilerPhase> constructor =
047          getCompilerPhaseConstructor(DominatorsPhase.class, new Class[]{Boolean.TYPE});
048    
049      /**
050       * Get a constructor object for this compiler phase
051       * @return compiler phase constructor
052       */
053      public Constructor<CompilerPhase> getClassConstructor() {
054        return constructor;
055      }
056    
057      /**
058       * Should this phase be performed?  This is a member of a composite
059       * phase, so always return true.  The parent composite phase will
060       * dictate.
061       * @param options controlling compiler options
062       */
063      public boolean shouldPerform(OptOptions options) {
064        return true;
065      }
066    
067      /**
068       * Return a string representation of this phase
069       * @return "Dominators + LpStrTree"
070       */
071      public String getName() {
072        return "Dominators + LpStrTree";
073      }
074    
075      /**
076       * Should the IR be printed before and/or after this phase?
077       * @param options controlling compiler options
078       * @param before query control
079       * @return true or false
080       */
081      public boolean printingEnabled(OptOptions options, boolean before) {
082        return false;
083      }
084    
085      /**
086       * Main driver for the dominator calculation.
087       */
088      public void perform(IR ir) {
089        try {
090          // reset flags in case an exception is thrown inside "perform"
091          // and it doesn't return normally
092          ir.HIRInfo.dominatorsAreComputed = false;
093    
094          // compute (forward) dominators,
095          // leaves info in scratch object of basic blocks
096          LTDominators.perform(ir, true, unfactor);
097    
098          // create the dominator tree, relies on dominator info being
099          // in scratch object of basic blocks
100          DominatorTree.perform(ir, true);
101    
102          // create the loop structured tree (LST)
103          LSTGraph.perform(ir);
104    
105          // computation completed, so set flag
106          ir.HIRInfo.dominatorsAreComputed = true;
107        } catch (OperationNotImplementedException e) {
108          OptimizingCompiler.report(e.getMessage());
109        }
110      }
111    }