changeset 19207:06a0ca03236f

ControlFlowOptimizer: move functionality into inner class.
author Josef Eisl <josef.eisl@jku.at>
date Fri, 06 Feb 2015 19:36:07 +0100
parents 46b04bca6c1b
children 81358265e0e0
files graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ControlFlowOptimizer.java
diffstat 1 files changed, 66 insertions(+), 60 deletions(-) [+]
line wrap: on
line diff
--- 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 <T extends AbstractBlock<T>> void optimize(LIR lir, List<T> codeEmittingOrder) {
-        ControlFlowOptimizer.deleteEmptyBlocks(lir, codeEmittingOrder);
+    public static <B extends AbstractBlock<B>> void optimize(LIR lir, List<B> codeEmittingOrder) {
+        new Optimizer<B>(lir).deleteEmptyBlocks(codeEmittingOrder);
     }
 
-    private ControlFlowOptimizer() {
-    }
+    private static final class Optimizer<B extends AbstractBlock<B>> {
 
-    private static final DebugMetric BLOCKS_DELETED = Debug.metric("BlocksDeleted");
+        private final LIR lir;
 
-    /**
-     * 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;
+        private Optimizer(LIR lir) {
+            this.lir = lir;
         }
 
-        List<LIRInstruction> instructions = lir.getLIRforBlock(block);
+        private static final DebugMetric BLOCKS_DELETED = Debug.metric("BlocksDeleted");
 
-        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";
+        /**
+         * 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;
+            }
 
-        // Block must have exactly one successor.
-        return instructions.size() == 2 && !instructions.get(instructions.size() - 1).hasState() && !block.isExceptionEntry();
-    }
+            List<LIRInstruction> instructions = lir.getLIRforBlock(block);
 
-    private static void alignBlock(LIR lir, AbstractBlock<?> block) {
-        if (!block.isAligned()) {
-            block.setAlign(true);
-            List<LIRInstruction> 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<LIRInstruction> 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<B> blocks) {
+            assert verifyBlocks(lir, blocks);
+            Iterator<B> 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<B> 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 <T extends AbstractBlock<T>> void deleteEmptyBlocks(LIR lir, List<T> blocks) {
-        assert verifyBlocks(lir, blocks);
-        Iterator<T> 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<T> 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);
-    }
 }