/* * This file is part of the Jikes RVM project (http://jikesrvm.org). * * This file is licensed to You under the Common Public License (CPL); * You may not use this file except in compliance with the License. You * may obtain a copy of the License at * * http://www.opensource.org/licenses/cpl1.0.php * * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. */ package org.jikesrvm.compilers.opt; import org.jikesrvm.compilers.opt.ir.OPT_BasicBlock; import org.jikesrvm.compilers.opt.ir.OPT_BasicBlockEnumeration; import org.jikesrvm.compilers.opt.ir.OPT_IR; import org.jikesrvm.compilers.opt.ir.OPT_Instruction; /** * Splits a large basic block into smaller ones with size <= MAX_NUM_INSTRUCTIONS. */ public final class OPT_SplitBasicBlock extends OPT_CompilerPhase { private static final int MAX_NUM_INSTRUCTIONS = 300; public String getName() { return "SplitBasicBlock"; } public OPT_CompilerPhase newExecution(OPT_IR ir) { return this; } public void perform(OPT_IR ir) { for (OPT_BasicBlockEnumeration e = ir.getBasicBlocks(); e.hasMoreElements();) { OPT_BasicBlock bb = e.nextElement(); if (!bb.isEmpty()) { while (bb != null) { bb = splitEachBlock(bb, ir); } } } } // Splits bb. // Returns null if no splitting is done. // returns the second block if splitting is done. OPT_BasicBlock splitEachBlock(OPT_BasicBlock bb, OPT_IR ir) { int instCount = MAX_NUM_INSTRUCTIONS; for (OPT_Instruction inst = bb.firstInstruction(); inst != bb.lastInstruction(); inst = inst.nextInstructionInCodeOrder()) { if ((--instCount) == 0) { if (inst.isBranch()) { return null; // no need to split because all the rests are just branches } if (inst.isMove()) { // why do we need this?? --dave OPT_Instruction next = inst.nextInstructionInCodeOrder(); if (next != bb.lastInstruction() && next.isImplicitLoad()) { inst = next; } } // Now, split! return bb.splitNodeWithLinksAt(inst, ir); } } return null; // no splitting happened } }