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      @Override
054      public Constructor<CompilerPhase> getClassConstructor() {
055        return constructor;
056      }
057    
058      /**
059       * Should this phase be performed?  This is a member of a composite
060       * phase, so always return true.  The parent composite phase will
061       * dictate.
062       * @param options controlling compiler options
063       * @return {@code true}
064       */
065      @Override
066      public boolean shouldPerform(OptOptions options) {
067        return true;
068      }
069    
070      /**
071       * Return a string representation of this phase
072       * @return "Dominators + LpStrTree"
073       */
074      @Override
075      public String getName() {
076        return "Dominators + LpStrTree";
077      }
078    
079      /**
080       * Should the IR be printed before and/or after this phase?
081       * @param options controlling compiler options
082       * @param before query control
083       * @return {@code false}
084       */
085      @Override
086      public boolean printingEnabled(OptOptions options, boolean before) {
087        return false;
088      }
089    
090      /**
091       * Main driver for the dominator calculation.
092       */
093      @Override
094      public void perform(IR ir) {
095        try {
096          // reset flags in case an exception is thrown inside "perform"
097          // and it doesn't return normally
098          ir.HIRInfo.dominatorsAreComputed = false;
099    
100          // compute (forward) dominators,
101          // leaves info in scratch object of basic blocks
102          LTDominators.perform(ir, true, unfactor);
103    
104          // create the dominator tree, relies on dominator info being
105          // in scratch object of basic blocks
106          DominatorTree.perform(ir, true);
107    
108          // create the loop structured tree (LST)
109          LSTGraph.perform(ir);
110    
111          // computation completed, so set flag
112          ir.HIRInfo.dominatorsAreComputed = true;
113        } catch (OperationNotImplementedException e) {
114          OptimizingCompiler.report(e.getMessage());
115        }
116      }
117    }