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