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.lir2mir;
014    
015    import java.util.Enumeration;
016    
017    import org.jikesrvm.compilers.opt.driver.CompilerPhase;
018    import org.jikesrvm.compilers.opt.ir.BasicBlock;
019    import org.jikesrvm.compilers.opt.ir.IR;
020    import org.jikesrvm.compilers.opt.ir.Instruction;
021    
022    /**
023     * Splits a large basic block into smaller ones with size <=
024     * OptOptions.L2M_MAX_BLOCK_SIZE
025     */
026    public final class SplitBasicBlock extends CompilerPhase {
027    
028      @Override
029      public String getName() { return "SplitBasicBlock"; }
030    
031      @Override
032      public CompilerPhase newExecution(IR ir) { return this; }
033    
034      @Override
035      public void perform(IR ir) {
036        for (Enumeration<BasicBlock> e = ir.getBasicBlocks(); e.hasMoreElements();) {
037          BasicBlock bb = e.nextElement();
038    
039          if (!bb.isEmpty()) {
040            while (bb != null) {
041              bb = splitEachBlock(bb, ir);
042            }
043          }
044        }
045      }
046    
047      /**
048       * Splits basic block
049       *
050       * @return {@code null} if no splitting is done, returns the second block if splitting is done.
051       */
052      BasicBlock splitEachBlock(BasicBlock bb, IR ir) {
053    
054        int instCount = ir.options.L2M_MAX_BLOCK_SIZE;
055        for (Instruction inst = bb.firstInstruction(); inst != bb.lastInstruction(); inst =
056            inst.nextInstructionInCodeOrder()) {
057          if ((--instCount) <= 0) {
058            if (inst.isBranch()) {
059              return null; // no need to split because all the rests are just branches
060            }
061            // Now, split!
062            return bb.splitNodeWithLinksAt(inst, ir);
063          }
064        }
065    
066        return null; // no splitting happened
067      }
068    
069    }