changeset 2789:aeccd2af4e9e

Fixes around critical edge split and placeholder removal after goto removal.
author Thomas Wuerthinger <thomas@wuerthinger.net>
date Wed, 25 May 2011 16:48:28 +0200
parents df4c5254c5cc
children 50677668afe3
files graal/GraalCompiler/src/com/oracle/max/graal/schedule/Schedule.java graal/GraalCompiler/src/com/sun/c1x/alloc/LinearScan.java 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/GraphBuilder.java graal/GraalCompiler/src/com/sun/c1x/graph/IR.java graal/GraalCompiler/src/com/sun/c1x/lir/LIRBlock.java graal/GraalCompiler/src/com/sun/c1x/lir/LIRInstruction.java graal/GraalGraph/src/com/oracle/graal/graph/NodeArray.java graal/GraalRuntime/src/com/oracle/graal/runtime/HotSpotOptions.java
diffstat 10 files changed, 113 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/graal/GraalCompiler/src/com/oracle/max/graal/schedule/Schedule.java	Wed May 25 14:33:44 2011 +0200
+++ b/graal/GraalCompiler/src/com/oracle/max/graal/schedule/Schedule.java	Wed May 25 16:48:28 2011 +0200
@@ -27,6 +27,7 @@
 import com.oracle.graal.graph.*;
 import com.sun.c1x.debug.*;
 import com.sun.c1x.ir.*;
+import com.sun.c1x.lir.*;
 
 
 public class Schedule {
@@ -67,18 +68,20 @@
     private Block assignBlock(Node n, Block b) {
         assert nodeToBlock.get(n) == null;
         nodeToBlock.set(n, b);
-        b.getInstructions().add((Instruction) n);
+        if (n != n.graph().start()) {
+            b.getInstructions().add((Instruction) n);
+        }
         return b;
     }
 
     private boolean isCFG(Node n) {
-        return n != null && (n instanceof Instruction);
+        return n != null && ((n instanceof Instruction) || n == n.graph().start());
     }
 
     private void identifyBlocks() {
         // Identify blocks.
         final ArrayList<Node> blockBeginNodes = new ArrayList<Node>();
-        NodeIterator.iterate(EdgeType.SUCCESSORS, graph.start().successors().get(0), null, new NodeVisitor() {
+        NodeIterator.iterate(EdgeType.SUCCESSORS, graph.start(), null, new NodeVisitor() {
             @Override
             public boolean visit(Node n) {
                 if (!isCFG(n)) {
@@ -185,8 +188,11 @@
                TTY.print(pred + ";");
            }
            TTY.println();
-           TTY.print("first instr: " + b.getInstructions().get(0));
-           TTY.print("last instr: " + b.getInstructions().get(b.getInstructions().size() - 1));
+
+           if (b.getInstructions().size() > 0) {
+               TTY.print("first instr: " + b.getInstructions().get(0));
+               TTY.print("last instr: " + b.getInstructions().get(b.getInstructions().size() - 1));
+           }
         }
 
 /*
--- a/graal/GraalCompiler/src/com/sun/c1x/alloc/LinearScan.java	Wed May 25 14:33:44 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/alloc/LinearScan.java	Wed May 25 16:48:28 2011 +0200
@@ -725,7 +725,7 @@
         // this is checked by these assertions to be sure about it.
         // the entry block may have incoming
         // values in registers, which is ok.
-        if (!operand.isVariable() /*&& block != ir.startBlock*/) {
+        if (!operand.isVariable() && block != ir.startBlock) {
             if (isProcessed(operand)) {
                 assert liveKill.get(operandNumber(operand)) : "using fixed register that is not defined in this block";
             }
@@ -812,6 +812,8 @@
                 reportFailure(numBlocks);
             }
 
+            TTY.println("preds=" + startBlock.blockPredecessors().size() + ", succs=" + startBlock.blockSuccessors().size());
+
             // bailout of if this occurs in product mode.
             throw new CiBailout("liveIn set of first block must be empty");
         }
--- a/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java	Wed May 25 14:33:44 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java	Wed May 25 16:48:28 2011 +0200
@@ -253,7 +253,7 @@
                 }
             }
         }
-        if (block.blockSuccessors().size() == 1 && !(block.getInstructions().get(block.getInstructions().size() - 1) instanceof BlockEnd)) {
+        if (block.blockSuccessors().size() == 1 && (block.getInstructions().size() == 0  || !(block.getInstructions().get(block.getInstructions().size() - 1) instanceof BlockEnd))) {
             moveToPhi();
             block.lir().jump(block.blockSuccessors().get(0));
         }
@@ -591,7 +591,11 @@
     }
 
     protected LIRBlock getLIRBlock(Instruction b) {
-        return ir.valueToBlock.get(b);
+        LIRBlock result = ir.valueToBlock.get(b);
+        if (result == null) {
+            TTY.println("instruction without lir block: " + b);
+        }
+        return result;
     }
 
     @Override
@@ -1324,7 +1328,7 @@
 
                     PhiResolver resolver = new PhiResolver(this);
                     for (Phi phi : phis) {
-                        if (!phi.isDeadPhi() && phi.valueCount() > predIndex) {
+                        if (!phi.isDeadPhi()) {
                             Value curVal = phi.valueAt(predIndex);
                             if (curVal != null && curVal != phi) {
                                 if (curVal instanceof Phi) {
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/CriticalEdgeFinder.java	Wed May 25 14:33:44 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/graph/CriticalEdgeFinder.java	Wed May 25 16:48:28 2011 +0200
@@ -45,9 +45,9 @@
      * 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<LIRBlock, Set<LIRBlock>> edges = C1XOptions.DetailedAsserts ?
-                    new LinkedHashMap<LIRBlock, Set<LIRBlock>>() :
-                    new HashMap<LIRBlock, Set<LIRBlock>>();
+    private Map<LIRBlock, List<LIRBlock>> edges = C1XOptions.DetailedAsserts ?
+                    new LinkedHashMap<LIRBlock, List<LIRBlock>>() :
+                    new HashMap<LIRBlock, List<LIRBlock>>();
 
     public CriticalEdgeFinder(List<LIRBlock> lirBlocks, Graph graph) {
         this.lirBlocks = lirBlocks;
@@ -71,14 +71,14 @@
 
     private void recordCriticalEdge(LIRBlock block, LIRBlock succ) {
         if (!edges.containsKey(block)) {
-            edges.put(block, new HashSet<LIRBlock>());
+            edges.put(block, new ArrayList<LIRBlock>());
         }
 
         edges.get(block).add(succ);
     }
 
     public void splitCriticalEdges() {
-        for (Map.Entry<LIRBlock, Set<LIRBlock>> entry : edges.entrySet()) {
+        for (Map.Entry<LIRBlock, List<LIRBlock>> entry : edges.entrySet()) {
             LIRBlock from = entry.getKey();
             for (LIRBlock to : entry.getValue()) {
                 LIRBlock split = splitEdge(from, to);
@@ -104,12 +104,21 @@
         lirBlocks.add(newSucc);
 
         // This goto is not a safepoint.
-        Goto e = new Goto(target.getInstructions().get(0), graph);
-        newSucc.getInstructions().add(e);
+        Goto e = new Goto(null, graph);
 
+        //TTY.println("SPLITTING NODE");
         // link predecessor to new block
 //        if (source.getInstructions().size() > 0) {
-            source.getInstructions().get(source.getInstructions().size() - 1).successors().replace(target.getInstructions().get(0), newSucc.getInstructions().get(0));
+
+        Instruction sourceInstruction = source.getInstructions().get(source.getInstructions().size() - 1);
+        Instruction targetInstruction = target.getInstructions().get(0);
+        int replacedIndex = sourceInstruction.successors().indexOf(targetInstruction);
+        assert replacedIndex != -1 && sourceInstruction.successors().get(replacedIndex) != null;
+        e.successors().setAndClear(1, sourceInstruction, replacedIndex);
+        sourceInstruction.successors().set(replacedIndex, e);
+        newSucc.getInstructions().add(e);
+       // assert e.successors().get(0) != null;
+        assert e.defaultSuccessor() != null;
 //        }
 
 
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java	Wed May 25 14:33:44 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java	Wed May 25 16:48:28 2011 +0200
@@ -178,6 +178,7 @@
                 }
             }
             flags |= Flag.HasHandler.mask;
+
         }
 
         // 1. create the start block
@@ -223,15 +224,13 @@
 
                 /*if (p == graph.start().successors().get(0)) {
                     // nothing to do...
-                } else*/ if (p.blockPredecessors().size() == 0) {
+                } else*/
+                if (p.blockPredecessors().size() == 0) {
                     assert p.next() == null;
                     p.delete();
                 } else {
                     assert p.blockPredecessors().size() == 1;
-                    for (Node pred : new ArrayList<Node>(p.predecessors())) {
-                        pred.successors().replace(p, p.next());
-                    }
-                    p.successors().clearAll();
+                    p.successors().replaceKeepOrder(p.next(), p.blockPredecessors().get(0));
                     p.delete();
                 }
             }
@@ -1064,6 +1063,7 @@
     }
 
     private Instruction createTarget(Block block, FrameStateAccess stateAfter) {
+
         assert block != null && stateAfter != null;
         assert block.isLoopHeader || block.firstInstruction == null || block.firstInstruction.next() == null : "non-loop block must be iterated after all its predecessors";
 
@@ -1177,11 +1177,6 @@
     }
 
     private void appendGoto(Instruction target) {
-        //lastInstr.appendNext(target);
-        append(new Goto(target, graph));
-    }
-
-    private void appendGoto2(Instruction target) {
         lastInstr.appendNext(target);
         //append(new Goto(target, graph));
     }
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java	Wed May 25 14:33:44 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java	Wed May 25 16:48:28 2011 +0200
@@ -122,15 +122,17 @@
                 valueToBlock.put(i, b);
             }
         }
-        startBlock = valueToBlock.get(getHIRStartBlock());
+        startBlock = lirBlocks.get(0);
         assert startBlock != null;
+        assert startBlock.blockPredecessors().size() == 0;
 
-        if (startBlock.blockPredecessors().size() > 0) {
+/*        if (startBlock.blockPredecessors().size() > 0) {
             LIRBlock oldStartBlock = startBlock;
             startBlock = new LIRBlock(orderedBlocks.size());
             startBlock.blockSuccessors().add(oldStartBlock);
+
             orderedBlocks.add(startBlock);
-        }
+        }*/
 
         ComputeLinearScanOrder clso = new ComputeLinearScanOrder(lirBlocks.size(), startBlock);
         orderedBlocks = clso.linearScanOrder();
--- a/graal/GraalCompiler/src/com/sun/c1x/lir/LIRBlock.java	Wed May 25 14:33:44 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/lir/LIRBlock.java	Wed May 25 16:48:28 2011 +0200
@@ -256,6 +256,7 @@
         for (int i = 0; i < successors.size(); ++i) {
             if (successors.get(i) == target) {
                 successors.set(i, newSucc);
+                break;
             }
         }
     }
@@ -264,6 +265,7 @@
         for (int i = 0; i < predecessors.size(); ++i) {
             if (predecessors.get(i) == source) {
                 predecessors.set(i, newSucc);
+                break;
             }
         }
     }
--- a/graal/GraalCompiler/src/com/sun/c1x/lir/LIRInstruction.java	Wed May 25 14:33:44 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/lir/LIRInstruction.java	Wed May 25 16:48:28 2011 +0200
@@ -482,7 +482,7 @@
     }
 
     public final LIRBlock exceptionEdge() {
-        return info.exceptionEdge;
+        return (info == null) ? null : info.exceptionEdge;
     }
 
     @Override
--- a/graal/GraalGraph/src/com/oracle/graal/graph/NodeArray.java	Wed May 25 14:33:44 2011 +0200
+++ b/graal/GraalGraph/src/com/oracle/graal/graph/NodeArray.java	Wed May 25 16:48:28 2011 +0200
@@ -24,6 +24,7 @@
 
 import java.util.AbstractList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Iterator;
 
 public class NodeArray extends AbstractList<Node> {
@@ -138,6 +139,67 @@
         return result;
     }
 
+    public void setAndClear(int index, Node clearedNode, int clearedIndex) {
+        assert self().successors == this;
+        Node value = clearedNode.successors.get(clearedIndex);
+        assert value != Node.Null;
+        clearedNode.successors.nodes[clearedIndex] = Node.Null;
+        set(index, Node.Null);
+        nodes[index] = value;
+
+        int numberOfMatchingSuccs = 0;
+        for (int i = 0; i < clearedIndex; ++i) {
+            if (clearedNode.successors.get(i) == value) {
+                numberOfMatchingSuccs++;
+            }
+        }
+
+        for (int i = 0; i < value.predecessors.size(); ++i) {
+            if (value.predecessors.get(i) == clearedNode) {
+                if (numberOfMatchingSuccs == 0) {
+                    value.predecessors.set(i, self());
+                    break;
+                } else {
+                    numberOfMatchingSuccs--;
+                }
+            }
+        }
+    }
+
+    public int replaceKeepOrder(Node targetNode, Node replacement) {
+        int deletedSuccessorIndex = -1;
+        if (this == self().successors) {
+            int firstIndex = -1;
+            for (int i = 0; i < replacement.successors.size(); ++i) {
+                if (replacement.successors.get(i) == self()) {
+                    replacement.successors().set(i, Node.Null);
+                    firstIndex = i;
+                    break;
+                }
+            }
+
+            assert firstIndex != -1;
+
+            for (int i = 0; i < this.size(); ++i) {
+                if (nodes[i] == targetNode) {
+                    replacement.successors().nodes[firstIndex] = targetNode;
+                    for (int j = 0; j < targetNode.predecessors.size(); ++j) {
+                        if (targetNode.predecessors.get(j) == self()) {
+                            targetNode.predecessors.set(j, replacement);
+                            break;
+                        }
+                    }
+                    nodes[i] = Node.Null;
+                    deletedSuccessorIndex = i;
+                    break;
+                }
+            }
+        } else {
+            assert false : "not supported";
+        }
+        return deletedSuccessorIndex;
+    }
+
     public int size() {
         return nodes.length;
     }
--- a/graal/GraalRuntime/src/com/oracle/graal/runtime/HotSpotOptions.java	Wed May 25 14:33:44 2011 +0200
+++ b/graal/GraalRuntime/src/com/oracle/graal/runtime/HotSpotOptions.java	Wed May 25 16:48:28 2011 +0200
@@ -31,7 +31,6 @@
 public class HotSpotOptions {
 
     public static void setDefaultOptions() {
-        C1XOptions.DetailedAsserts = false;
         C1XOptions.CommentedAssembly = false;
         C1XOptions.MethodEndBreakpointGuards = 2;
         C1XOptions.ResolveClassBeforeStaticInvoke = false;