# HG changeset patch # User Josef Eisl # Date 1423247767 -3600 # Node ID 06a0ca03236fda4996ecaef16bcbec90c02907ce # Parent 46b04bca6c1bd37cc9cef333b85700c3e627e242 ControlFlowOptimizer: move functionality into inner class. diff -r 46b04bca6c1b -r 06a0ca03236f graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ControlFlowOptimizer.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ControlFlowOptimizer.java Fri Feb 06 17:20:12 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ControlFlowOptimizer.java Fri Feb 06 19:36:07 2015 +0100 @@ -37,76 +37,82 @@ /** * Performs control flow optimizations on the given LIR graph. */ - public static > void optimize(LIR lir, List codeEmittingOrder) { - ControlFlowOptimizer.deleteEmptyBlocks(lir, codeEmittingOrder); - } - - private ControlFlowOptimizer() { - } - - private static final DebugMetric BLOCKS_DELETED = Debug.metric("BlocksDeleted"); - - /** - * Checks whether a block can be deleted. Only blocks with exactly one successor and an - * unconditional branch to this successor are eligable. - * - * @param block the block checked for deletion - * @return whether the block can be deleted - */ - private static boolean canDeleteBlock(LIR lir, AbstractBlock block) { - if (block.getSuccessorCount() != 1 || block.getPredecessorCount() == 0 || block.getSuccessors().iterator().next() == block) { - return false; - } - - List instructions = lir.getLIRforBlock(block); - - assert instructions.size() >= 2 : "block must have label and branch"; - assert instructions.get(0) instanceof StandardOp.LabelOp : "first instruction must always be a label"; - assert instructions.get(instructions.size() - 1) instanceof StandardOp.JumpOp : "last instruction must always be a branch"; - assert ((StandardOp.JumpOp) instructions.get(instructions.size() - 1)).destination().label() == ((StandardOp.LabelOp) lir.getLIRforBlock(block.getSuccessors().iterator().next()).get(0)).getLabel() : "branch target must be the successor"; - - // Block must have exactly one successor. - return instructions.size() == 2 && !instructions.get(instructions.size() - 1).hasState() && !block.isExceptionEntry(); + public static > void optimize(LIR lir, List codeEmittingOrder) { + new Optimizer(lir).deleteEmptyBlocks(codeEmittingOrder); } - private static void alignBlock(LIR lir, AbstractBlock block) { - if (!block.isAligned()) { - block.setAlign(true); + private static final class Optimizer> { + + private final LIR lir; + + private Optimizer(LIR lir) { + this.lir = lir; + } + + private static final DebugMetric BLOCKS_DELETED = Debug.metric("BlocksDeleted"); + + /** + * Checks whether a block can be deleted. Only blocks with exactly one successor and an + * unconditional branch to this successor are eligable. + * + * @param block the block checked for deletion + * @return whether the block can be deleted + */ + private boolean canDeleteBlock(B block) { + if (block.getSuccessorCount() != 1 || block.getPredecessorCount() == 0 || block.getSuccessors().iterator().next() == block) { + return false; + } + List instructions = lir.getLIRforBlock(block); + + assert instructions.size() >= 2 : "block must have label and branch"; assert instructions.get(0) instanceof StandardOp.LabelOp : "first instruction must always be a label"; - StandardOp.LabelOp label = (StandardOp.LabelOp) instructions.get(0); - instructions.set(0, new StandardOp.LabelOp(label.getLabel(), true)); + assert instructions.get(instructions.size() - 1) instanceof StandardOp.JumpOp : "last instruction must always be a branch"; + assert ((StandardOp.JumpOp) instructions.get(instructions.size() - 1)).destination().label() == ((StandardOp.LabelOp) lir.getLIRforBlock(block.getSuccessors().iterator().next()).get(0)).getLabel() : "branch target must be the successor"; + + // Block must have exactly one successor. + return instructions.size() == 2 && !instructions.get(instructions.size() - 1).hasState() && !block.isExceptionEntry(); + } + + private void alignBlock(B block) { + if (!block.isAligned()) { + block.setAlign(true); + List instructions = lir.getLIRforBlock(block); + assert instructions.get(0) instanceof StandardOp.LabelOp : "first instruction must always be a label"; + StandardOp.LabelOp label = (StandardOp.LabelOp) instructions.get(0); + instructions.set(0, new StandardOp.LabelOp(label.getLabel(), true)); + } + } + + private void deleteEmptyBlocks(List blocks) { + assert verifyBlocks(lir, blocks); + Iterator iterator = blocks.iterator(); + while (iterator.hasNext()) { + B block = iterator.next(); + if (canDeleteBlock(block)) { + // adjust successor and predecessor lists + B other = block.getSuccessors().iterator().next(); + for (AbstractBlock pred : block.getPredecessors()) { + Collections.replaceAll(pred.getSuccessors(), block, other); + } + for (int i = 0; i < other.getPredecessorCount(); i++) { + if (other.getPredecessors().get(i) == block) { + other.getPredecessors().remove(i); + other.getPredecessors().addAll(i, block.getPredecessors()); + } + } + block.getSuccessors().clear(); + block.getPredecessors().clear(); + + if (block.isAligned()) { + alignBlock(other); + } + + BLOCKS_DELETED.increment(); + iterator.remove(); + } + } + assert verifyBlocks(lir, blocks); } } - - private static > void deleteEmptyBlocks(LIR lir, List blocks) { - assert verifyBlocks(lir, blocks); - Iterator iterator = blocks.iterator(); - while (iterator.hasNext()) { - T block = iterator.next(); - if (canDeleteBlock(lir, block)) { - // adjust successor and predecessor lists - T other = block.getSuccessors().iterator().next(); - for (AbstractBlock pred : block.getPredecessors()) { - Collections.replaceAll(pred.getSuccessors(), block, other); - } - for (int i = 0; i < other.getPredecessorCount(); i++) { - if (other.getPredecessors().get(i) == block) { - other.getPredecessors().remove(i); - other.getPredecessors().addAll(i, block.getPredecessors()); - } - } - block.getSuccessors().clear(); - block.getPredecessors().clear(); - - if (block.isAligned()) { - alignBlock(lir, other); - } - - BLOCKS_DELETED.increment(); - iterator.remove(); - } - } - assert verifyBlocks(lir, blocks); - } }