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.lir2mir; 014 015import java.util.Enumeration; 016 017import org.jikesrvm.compilers.opt.OptimizingCompilerException; 018import org.jikesrvm.compilers.opt.driver.CompilerPhase; 019import org.jikesrvm.compilers.opt.ir.BasicBlock; 020import org.jikesrvm.compilers.opt.ir.IR; 021import org.jikesrvm.compilers.opt.ir.Instruction; 022 023/** 024 * Splits a large basic block into smaller ones with {@code size <= 025 * OptOptions.L2M_MAX_BLOCK_SIZE} 026 */ 027public final class SplitBasicBlock extends CompilerPhase { 028 029 @Override 030 public String getName() { 031 return "SplitBasicBlock"; 032 } 033 034 @Override 035 public CompilerPhase newExecution(IR ir) { 036 return this; 037 } 038 039 @Override 040 public void perform(IR ir) { 041 for (Enumeration<BasicBlock> e = ir.getBasicBlocks(); e.hasMoreElements();) { 042 BasicBlock bb = e.nextElement(); 043 044 if (!bb.isEmpty()) { 045 while (bb != null) { 046 bb = splitEachBlock(bb, ir); 047 } 048 } 049 } 050 } 051 052 /** 053 * Splits a basic block. 054 * 055 * @param bb the block to process 056 * @param ir the IR that contains the block 057 * 058 * @return {@code null} if no splitting is done, returns the second block 059 * if splitting is done. 060 */ 061 BasicBlock splitEachBlock(BasicBlock bb, IR ir) { 062 if (ir.options.L2M_MAX_BLOCK_SIZE <= 0) { 063 throw new OptimizingCompilerException("Maximum block size must be a" + 064 " positive number but was " + 065 ir.options.L2M_MAX_BLOCK_SIZE + "!", true); 066 } 067 068 int remainingInstCount = ir.options.L2M_MAX_BLOCK_SIZE; 069 070 Enumeration<Instruction> instructions = bb.forwardRealInstrEnumerator(); 071 while (instructions.hasMoreElements()) { 072 Instruction inst = instructions.nextElement(); 073 remainingInstCount--; 074 if (remainingInstCount <= 0) { 075 // no need to split because all the rests are just branches 076 if (inst.isBranch()) { 077 return null; 078 } 079 // no need to split because the basic block does not contain any more instructions 080 if (!instructions.hasMoreElements()) { 081 return null; 082 } 083 084 return bb.splitNodeWithLinksAt(inst, ir); 085 } 086 } 087 088 return null; 089 } 090 091}