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.ia32;
014    
015    import java.util.ArrayList;
016    
017    import org.jikesrvm.compilers.opt.MutateSplits;
018    import org.jikesrvm.compilers.opt.OptOptions;
019    import org.jikesrvm.compilers.opt.controlflow.MIRBranchOptimizations;
020    import org.jikesrvm.compilers.opt.driver.IRPrinter;
021    import org.jikesrvm.compilers.opt.driver.OptimizationPlanElement;
022    import org.jikesrvm.compilers.opt.driver.OptimizationPlanner;
023    import org.jikesrvm.compilers.opt.lir2mir.ConvertLIRtoMIR;
024    import org.jikesrvm.compilers.opt.lir2mir.SplitBasicBlock;
025    import org.jikesrvm.compilers.opt.liveness.LiveAnalysis;
026    import org.jikesrvm.compilers.opt.mir2mc.ConvertMIRtoMC;
027    import org.jikesrvm.compilers.opt.regalloc.ExpandCallingConvention;
028    import org.jikesrvm.compilers.opt.regalloc.PrologueEpilogueCreator;
029    import org.jikesrvm.compilers.opt.regalloc.RegisterAllocator;
030    import org.jikesrvm.compilers.opt.regalloc.ia32.ExpandFPRStackConvention;
031    import org.jikesrvm.compilers.opt.regalloc.ia32.MIRSplitRanges;
032    
033    /**
034     * This class specifies the order in which CompilerPhases are
035     * executed in the target-specific backend of the optimizing compiler.
036     * The methods LIR2MIR, MIROptimizations, and MIR2MC each specify the
037     * elements that make up the main compilation stages.
038     */
039    public class MIROptimizationPlanner extends OptimizationPlanner {
040    
041      /**
042       * Initialize the "master plan" for the IA32 backend of the opt compiler.
043       */
044      public static void intializeMasterPlan(ArrayList<OptimizationPlanElement> temp) {
045        LIR2MIR(temp);
046        MIROptimizations(temp);
047        MIR2MC(temp);
048      }
049    
050      /**
051       * This method defines the optimization plan elements that
052       * are to be performed to convert LIR to IA32 MIR.
053       *
054       * @param p the plan under construction
055       */
056      private static void LIR2MIR(ArrayList<OptimizationPlanElement> p) {
057        composeComponents(p, "Convert LIR to MIR", new Object[]{
058            // Split very large basic blocks into smaller ones.
059            new SplitBasicBlock(),
060            // Optional printing of final LIR
061            new IRPrinter("Final LIR") {
062              @Override
063              public boolean shouldPerform(OptOptions options) {
064                return options.PRINT_FINAL_LIR;
065              }
066            },
067            // Change operations that split live ranges to moves
068            new MutateSplits(),
069            // Instruction Selection
070            new ConvertLIRtoMIR(),
071    
072            // Optional printing of initial MIR
073            new IRPrinter("Initial MIR") {
074              @Override
075              public boolean shouldPerform(OptOptions options) {
076                return options.PRINT_MIR;
077              }
078            }});
079      }
080    
081      /**
082       * This method defines the optimization plan elements that
083       * are to be performed on IA32 MIR.
084       *
085       * @param p the plan under construction
086       */
087      private static void MIROptimizations(ArrayList<OptimizationPlanElement> p) {
088        // Register Allocation
089        composeComponents(p, "Register Mapping", new Object[]{new MIRSplitRanges(),
090                                                              // MANDATORY: Expand calling convention
091                                                              new ExpandCallingConvention(),
092                                                              // MANDATORY: Insert defs/uses due to floating-point stack
093                                                              new ExpandFPRStackConvention(),
094                                                              // MANDATORY: Perform Live analysis and create GC maps
095                                                              new LiveAnalysis(true, false),
096                                                              // MANDATORY: Perform register allocation
097                                                              new RegisterAllocator(),
098                                                              // MANDATORY: Add prologue and epilogue
099                                                              new PrologueEpilogueCreator(),});
100        // Peephole branch optimizations
101        addComponent(p, new MIRBranchOptimizations(1));
102      }
103    
104      /**
105       * This method defines the optimization plan elements that
106       * are to be performed to convert IA32 MIR into
107       * ready-to-execute machinecode (and associated mapping tables).
108       *
109       * @param p the plan under construction
110       */
111      private static void MIR2MC(ArrayList<OptimizationPlanElement> p) {
112        // MANDATORY: Final assembly
113        addComponent(p, new ConvertMIRtoMC());
114      }
115    
116    }