changeset 2779:93ec3f067420

Changed CriticalEdgeFinder to use LIRBlock.
author Thomas Wuerthinger <thomas@wuerthinger.net>
date Wed, 25 May 2011 11:04:59 +0200
parents 2ac7b30b7290
children 79dda81dd337
files graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java graal/GraalCompiler/src/com/sun/c1x/graph/CriticalEdgeFinder.java graal/GraalCompiler/src/com/sun/c1x/graph/IR.java graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java graal/GraalCompiler/src/com/sun/c1x/ir/BlockEnd.java graal/GraalCompiler/src/com/sun/c1x/ir/ExceptionDispatch.java graal/GraalCompiler/src/com/sun/c1x/ir/Goto.java graal/GraalCompiler/src/com/sun/c1x/ir/LookupSwitch.java graal/GraalCompiler/src/com/sun/c1x/ir/TableSwitch.java graal/GraalCompiler/src/com/sun/c1x/lir/LIRBlock.java graal/GraalGraph/src/com/oracle/graal/graph/NodeArray.java
diffstat 11 files changed, 122 insertions(+), 103 deletions(-) [+]
line wrap: on
line diff
--- a/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java	Tue May 24 21:39:45 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java	Wed May 25 11:04:59 2011 +0200
@@ -578,7 +578,6 @@
     }
 
     protected LIRBlock getLIRBlock(Instruction b) {
-        assert b instanceof BlockBegin : "only BlockBegin, for now...";
         return ir.valueToBlock.get(b);
     }
 
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/CriticalEdgeFinder.java	Tue May 24 21:39:45 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/graph/CriticalEdgeFinder.java	Wed May 25 11:04:59 2011 +0200
@@ -24,9 +24,11 @@
 
 import java.util.*;
 
+import com.oracle.graal.graph.*;
 import com.sun.c1x.*;
 import com.sun.c1x.debug.*;
 import com.sun.c1x.ir.*;
+import com.sun.c1x.lir.*;
 
 /**
  * This class finds and splits "critical" edges in the control flow graph.
@@ -34,26 +36,31 @@
  * has more than one successor and {@code B} has more than one predecessor. Such
  * edges are split by adding a block between the two blocks.
  */
-public class CriticalEdgeFinder implements BlockClosure {
+public class CriticalEdgeFinder {
 
-    private final IR ir;
+    private final List<LIRBlock> lirBlocks;
+    private final Graph graph;
 
     /**
      * The graph edges represented as a map from source to target nodes.
      * Using a linked hash map makes compilation tracing more deterministic and thus eases debugging.
      */
-    private Map<BlockBegin, Set<BlockBegin>> edges = C1XOptions.DetailedAsserts ?
-                    new LinkedHashMap<BlockBegin, Set<BlockBegin>>() :
-                    new HashMap<BlockBegin, Set<BlockBegin>>();
+    private Map<LIRBlock, Set<LIRBlock>> edges = C1XOptions.DetailedAsserts ?
+                    new LinkedHashMap<LIRBlock, Set<LIRBlock>>() :
+                    new HashMap<LIRBlock, Set<LIRBlock>>();
 
-    public CriticalEdgeFinder(IR ir) {
-        this.ir = ir;
+    public CriticalEdgeFinder(List<LIRBlock> lirBlocks, Graph graph) {
+        this.lirBlocks = lirBlocks;
+        this.graph = graph;
+        for (LIRBlock block : lirBlocks) {
+            apply(block);
+        }
+
     }
 
-    public void apply(BlockBegin block) {
-        BlockEnd end = block.end();
-        if (end.blockSuccessorCount() >= 2) {
-            for (BlockBegin succ : end.blockSuccessors()) {
+    private void apply(LIRBlock block) {
+        if (block.numberOfSux() >= 2) {
+            for (LIRBlock succ : block.blockSuccessors()) {
                 if (succ.numberOfPreds() >= 2) {
                     // TODO: (tw) probably we don't have to make it a critical edge if succ only contains the _same_ predecessor multiple times.
                     recordCriticalEdge(block, succ);
@@ -62,23 +69,78 @@
         }
     }
 
-    private void recordCriticalEdge(BlockBegin block, BlockBegin succ) {
+    private void recordCriticalEdge(LIRBlock block, LIRBlock succ) {
         if (!edges.containsKey(block)) {
-            edges.put(block, new HashSet<BlockBegin>());
+            edges.put(block, new HashSet<LIRBlock>());
         }
 
         edges.get(block).add(succ);
     }
 
     public void splitCriticalEdges() {
-        for (Map.Entry<BlockBegin, Set<BlockBegin>> entry : edges.entrySet()) {
-            BlockBegin from = entry.getKey();
-            for (BlockBegin to : entry.getValue()) {
-                BlockBegin split = ir.splitEdge(from, to);
+        for (Map.Entry<LIRBlock, Set<LIRBlock>> entry : edges.entrySet()) {
+            LIRBlock from = entry.getKey();
+            for (LIRBlock to : entry.getValue()) {
+                LIRBlock split = splitEdge(from, to);
                 if (C1XOptions.PrintHIR) {
-                    TTY.println("Split edge between block %d and block %d, creating new block %d", from.blockID, to.blockID, split.blockID);
+                    TTY.println("Split edge between block %d and block %d, creating new block %d", from.blockID(), to.blockID(), split.blockID());
                 }
             }
         }
     }
+
+
+    /**
+     * Creates and inserts a new block between this block and the specified successor,
+     * altering the successor and predecessor lists of involved blocks appropriately.
+     * @param source the source of the edge
+     * @param target the successor before which to insert a block
+     * @return the new block inserted
+     */
+    public LIRBlock splitEdge(LIRBlock source, LIRBlock target) {
+
+        int backEdgeIndex = target.blockPredecessors().indexOf(source);
+
+        // create new successor and mark it for special block order treatment
+        LIRBlock newSucc = new LIRBlock(lirBlocks.size());
+        lirBlocks.add(newSucc);
+
+        List<Integer> removePhiInputs = null;
+        for (int i = backEdgeIndex + 1; i < target.blockPredecessors().size(); ++i) {
+            if (target.blockPredecessors().get(i) == source) {
+                if (removePhiInputs == null) {
+                    removePhiInputs = new ArrayList<Integer>(4);
+                }
+                removePhiInputs.add(i);
+            }
+        }
+
+        // This goto is not a safepoint.
+        Goto e = new Goto(target.getInstructions().get(0), graph);
+        newSucc.getInstructions().add(e);
+        //e.reorderSuccessor(0, backEdgeIndex);
+
+        // link predecessor to new block
+        ((BlockEnd) source.getInstructions().get(source.getInstructions().size() - 1)).successors().replace(target.getInstructions().get(0), newSucc.getInstructions().get(0));
+/*        if (removePhiInputs != null && removePhiInputs.size() > 0) {
+
+            for (Node n : target.getInstructions().get(0).usages()) {
+                if (n instanceof Phi) {
+                    Phi phi = (Phi) n;
+                    int correction = 0;
+                    for (int index : removePhiInputs) {
+                        phi.removeInput(index - correction);
+                        correction++;
+                    }
+                }
+            }
+        }*/
+
+        source.substituteSuccessor(target, newSucc);
+        target.substitutePredecessor(source, newSucc);
+        newSucc.blockPredecessors().add(source);
+        newSucc.blockSuccessors().add(target);
+
+        return newSucc;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java	Tue May 24 21:39:45 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java	Wed May 25 11:04:59 2011 +0200
@@ -80,10 +80,6 @@
             C1XTimers.HIR_OPTIMIZE.start();
         }
 
-        CriticalEdgeFinder finder = new CriticalEdgeFinder(this);
-        getHIRStartBlock().iteratePreOrder(finder);
-        finder.splitCriticalEdges();
-
         Schedule schedule = new Schedule(this.compilation.graph);
         List<Block> blocks = schedule.getBlocks();
         List<LIRBlock> lirBlocks = new ArrayList<LIRBlock>();
@@ -116,9 +112,14 @@
         //computeLinearScanOrder();
 
 //        assert orderedBlocks.size() == lirBlocks.size();
+
+
+        CriticalEdgeFinder finder = new CriticalEdgeFinder(lirBlocks, compilation.graph);
+        finder.splitCriticalEdges();
+
+
         orderedBlocks = lirBlocks;
 
-
         valueToBlock = new HashMap<Value, LIRBlock>();
         for (LIRBlock b : orderedBlocks) {
             for (Instruction i : b.getInstructions()) {
@@ -256,55 +257,6 @@
         }
     }
 
-    /**
-     * Creates and inserts a new block between this block and the specified successor,
-     * altering the successor and predecessor lists of involved blocks appropriately.
-     * @param source the source of the edge
-     * @param target the successor before which to insert a block
-     * @return the new block inserted
-     */
-    public BlockBegin splitEdge(BlockBegin source, BlockBegin target) {
-        int bci = -2;
-
-        int backEdgeIndex = target.predecessors().indexOf(source.end());
-
-        // create new successor and mark it for special block order treatment
-        BlockBegin newSucc = new BlockBegin(bci, nextBlockNumber(), false, compilation.graph);
-
-        List<Integer> removePhiInputs = null;
-        for (int i = backEdgeIndex + 1; i < target.predecessors().size(); ++i) {
-            if (target.predecessors().get(i) == source.end()) {
-                if (removePhiInputs == null) {
-                    removePhiInputs = new ArrayList<Integer>();
-                }
-                removePhiInputs.add(i);
-            }
-        }
-
-        // This goto is not a safepoint.
-        Goto e = new Goto(target, compilation.graph);
-        newSucc.appendNext(e);
-        e.reorderSuccessor(0, backEdgeIndex);
-
-        // link predecessor to new block
-        source.end().substituteSuccessor(target, newSucc);
-        if (removePhiInputs != null && removePhiInputs.size() > 0) {
-
-            for (Node n : target.usages()) {
-                if (n instanceof Phi) {
-                    Phi phi = (Phi) n;
-                    int correction = 0;
-                    for (int index : removePhiInputs) {
-                        phi.removeInput(index - correction);
-                        correction++;
-                    }
-                }
-            }
-
-        }
-
-        return newSucc;
-    }
 
     public int nextBlockNumber() {
         return compilation.stats.blockCount++;
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java	Tue May 24 21:39:45 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java	Wed May 25 11:04:59 2011 +0200
@@ -343,25 +343,4 @@
     public String shortName() {
         return "BlockBegin #" + blockID;
     }
-
-    /**
-     * Iterates over all successors of this block: successors of the end node and exception handler.
-     */
-    public void allSuccessorsDo(boolean backwards, BlockClosure closure) {
-        BlockEnd end = end();
-        if (backwards) {
-            for (int i = end.blockSuccessorCount() - 1; i >= 0; i--) {
-                closure.apply(end.blockSuccessor(i));
-            }
-        } else {
-            for (int i = 0; i < end.blockSuccessorCount(); i++) {
-                closure.apply(end.blockSuccessor(i));
-            }
-        }
-        for (Instruction x = next(); x != null; x = x.next()) {
-            if (x instanceof ExceptionEdgeInstruction && ((ExceptionEdgeInstruction) x).exceptionEdge() != null) {
-                closure.apply(((ExceptionEdgeInstruction) x).exceptionEdge());
-            }
-        }
-    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/BlockEnd.java	Tue May 24 21:39:45 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/BlockEnd.java	Wed May 25 11:04:59 2011 +0200
@@ -52,9 +52,9 @@
     /**
      * The list of instructions that produce input for this instruction.
      */
-    public BlockBegin blockSuccessor(int index) {
+    public Instruction blockSuccessor(int index) {
         assert index >= 0 && index < blockSuccessorCount;
-        return (BlockBegin) successors().get(super.successorCount() + SUCCESSOR_COUNT + index);
+        return (Instruction) successors().get(super.successorCount() + SUCCESSOR_COUNT + index);
     }
 
     public Instruction setBlockSuccessor(int index, Instruction n) {
@@ -123,7 +123,7 @@
      * Gets the successor corresponding to the default (fall through) case.
      * @return the default successor
      */
-    public BlockBegin defaultSuccessor() {
+    public Instruction defaultSuccessor() {
         return blockSuccessor(blockSuccessorCount - 1);
     }
 
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/ExceptionDispatch.java	Tue May 24 21:39:45 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/ExceptionDispatch.java	Wed May 25 11:04:59 2011 +0200
@@ -80,7 +80,7 @@
      * Gets the block corresponding to the catch block.
      * @return the true successor
      */
-    public BlockBegin catchSuccessor() {
+    public Instruction catchSuccessor() {
         return blockSuccessor(1);
     }
 
@@ -88,7 +88,7 @@
      * Gets the block corresponding to the rest of the dispatch chain.
      * @return the false successor
      */
-    public BlockBegin otherSuccessor() {
+    public Instruction otherSuccessor() {
         return blockSuccessor(0);
     }
 
@@ -97,7 +97,7 @@
      * @param istrue {@code true} if the true successor is requested, {@code false} otherwise
      * @return the corresponding successor
      */
-    public BlockBegin successor(boolean istrue) {
+    public Instruction successor(boolean istrue) {
         return blockSuccessor(istrue ? 1 : 0);
     }
 
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/Goto.java	Tue May 24 21:39:45 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Goto.java	Wed May 25 11:04:59 2011 +0200
@@ -52,6 +52,6 @@
 
     @Override
     public void print(LogStream out) {
-        out.print("goto B").print(defaultSuccessor().blockID);
+        out.print("goto ").print(defaultSuccessor());
     }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/LookupSwitch.java	Tue May 24 21:39:45 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/LookupSwitch.java	Wed May 25 11:04:59 2011 +0200
@@ -81,6 +81,6 @@
             out.printf("case %5d: B%d%n", keyAt(i), blockSuccessors().get(i).blockID);
         }
         INSTRUCTION.advance(out);
-        out.print("default   : B").print(defaultSuccessor().blockID);
+        out.print("default   : ").print(defaultSuccessor());
     }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/TableSwitch.java	Tue May 24 21:39:45 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/TableSwitch.java	Wed May 25 11:04:59 2011 +0200
@@ -83,6 +83,6 @@
             out.printf("case %5d: B%d%n", lowKey() + i, blockSuccessors().get(i).blockID);
         }
         INSTRUCTION.advance(out);
-        out.print("default   : B").print(defaultSuccessor().blockID);
+        out.print("default   : ").print(defaultSuccessor());
     }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/lir/LIRBlock.java	Tue May 24 21:39:45 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/lir/LIRBlock.java	Wed May 25 11:04:59 2011 +0200
@@ -249,4 +249,20 @@
     public void setInstructions(List<Instruction> list) {
         instructions = list;
     }
+
+    public void substituteSuccessor(LIRBlock target, LIRBlock newSucc) {
+        for (int i = 0; i < successors.size(); ++i) {
+            if (successors.get(i) == target) {
+                successors.set(i, newSucc);
+            }
+        }
+    }
+
+    public void substitutePredecessor(LIRBlock source, LIRBlock newSucc) {
+        for (int i = 0; i < predecessors.size(); ++i) {
+            if (predecessors.get(i) == source) {
+                predecessors.set(i, newSucc);
+            }
+        }
+    }
 }
--- a/graal/GraalGraph/src/com/oracle/graal/graph/NodeArray.java	Tue May 24 21:39:45 2011 +0200
+++ b/graal/GraalGraph/src/com/oracle/graal/graph/NodeArray.java	Wed May 25 11:04:59 2011 +0200
@@ -127,6 +127,17 @@
         return false;
     }
 
+    public int replace(Node toReplace, Node replacement) {
+        int result = 0;
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] == toReplace) {
+                set(i, replacement);
+                result++;
+            }
+        }
+        return result;
+    }
+
     public int size() {
         return nodes.length;
     }