changeset 2781:bda5972a40a5

remove unnecessary BlockBegin nodes in frontend
author Lukas Stadler <lukas.stadler@jku.at>
date Tue, 24 May 2011 15:31:52 +0200
parents 398b8fa5dc81
children 915456e4959e
files graal/GraalCompiler/src/com/sun/c1x/debug/CFGPrinterObserver.java graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.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/ir/BlockBegin.java graal/GraalCompiler/src/com/sun/c1x/ir/BlockEnd.java graal/GraalCompiler/src/com/sun/c1x/ir/ExceptionEdgeInstruction.java graal/GraalCompiler/src/com/sun/c1x/ir/Placeholder.java graal/GraalCompiler/src/com/sun/c1x/ir/Throw.java graal/GraalCompiler/src/com/sun/c1x/observer/CompilationEvent.java graal/GraalGraph/src/com/oracle/graal/graph/NodeArray.java
diffstat 11 files changed, 100 insertions(+), 101 deletions(-) [+]
line wrap: on
line diff
--- a/graal/GraalCompiler/src/com/sun/c1x/debug/CFGPrinterObserver.java	Tue May 24 13:55:56 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/debug/CFGPrinterObserver.java	Tue May 24 15:31:52 2011 +0200
@@ -25,6 +25,7 @@
 import java.io.*;
 
 import com.sun.c1x.*;
+import com.sun.c1x.ir.*;
 import com.sun.c1x.observer.*;
 import com.sun.cri.ri.*;
 
@@ -74,7 +75,7 @@
         }
 
         if (event.getStartBlock() != null) {
-            cfgPrinter.printCFG(event.getStartBlock(), label, event.isHIRValid(), event.isLIRValid());
+            cfgPrinter.printCFG((BlockBegin) event.getStartBlock(), label, event.isHIRValid(), event.isLIRValid());
             cfgprinted = true;
         }
 
--- a/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java	Tue May 24 13:55:56 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java	Tue May 24 15:31:52 2011 +0200
@@ -1462,7 +1462,7 @@
         assert state != null;
         LIRBlock exceptionEdge = null;
         if (x instanceof ExceptionEdgeInstruction) {
-            BlockBegin begin = ((ExceptionEdgeInstruction) x).exceptionEdge();
+            Instruction begin = ((ExceptionEdgeInstruction) x).exceptionEdge();
             if (begin != null) {
                 exceptionEdge = getLIRBlock(begin);
             }
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java	Tue May 24 13:55:56 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java	Tue May 24 15:31:52 2011 +0200
@@ -165,13 +165,6 @@
 //            System.out.println("block " + blockID + " @ " + block.startBci);
         }
 
-        // 1. create the start block
-        Block startBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI);
-        BlockBegin startBlockBegin = new BlockBegin(0, startBlock.blockID, false, graph);
-        startBlock.firstInstruction = startBlockBegin;
-
-        graph.start().setStart(startBlockBegin);
-
         RiExceptionHandler[] handlers = rootMethod.exceptionHandlers();
         if (handlers != null && handlers.length > 0) {
             exceptionHandlers = new ArrayList<ExceptionHandler>(handlers.length);
@@ -187,13 +180,12 @@
             flags |= Flag.HasHandler.mask;
         }
 
-        mergeOrClone(startBlock, frameState);
+        // 1. create the start block
+        Block startBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI);
+        markOnWorkList(startBlock);
+        lastInstr = createTarget(startBlock, frameState);
+        graph.start().setStart(lastInstr);
 
-        // 3. setup internal state for appending instructions
-        lastInstr = startBlockBegin;
-        lastInstr.appendNext(null);
-
-        BlockBegin syncHandler = null;
         Block syncBlock = null;
         if (isSynchronized(rootMethod.accessFlags())) {
             // 4A.1 add a monitor enter to the start block
@@ -204,15 +196,8 @@
 
             // 4A.3 setup an exception handler to unlock the root method synchronized object
             syncBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI);
-            syncHandler = new BlockBegin(Instruction.SYNCHRONIZATION_ENTRY_BCI, syncBlock.blockID, false, graph);
-            syncBlock.firstInstruction = syncHandler;
             markOnWorkList(syncBlock);
 
-            ExceptionBlock excBlock = new ExceptionBlock();
-            excBlock.startBci = -1;
-            excBlock.endBci = -1;
-            excBlock.blockID = ir.nextBlockNumber();
-            blockList.add(excBlock);
             ExceptionHandler h = new ExceptionHandler(new CiExceptionHandler(0, rootMethod.code().length, -1, 0, null));
             h.setEntryBlock(syncBlock);
             addExceptionHandler(h);
@@ -227,27 +212,45 @@
         addToWorkList(blockFromBci[0]);
         iterateAllBlocks();
 
-        if (syncBlock != null && syncHandler.stateBefore() != null) {
+        if (syncBlock != null && syncBlock.firstInstruction != null) {
             // generate unlocking code if the exception handler is reachable
             fillSyncHandler(rootMethodSynchronizedObject, syncBlock);
         }
 
-//        for (Node n : graph.getNodes()) {
-//            if (n instanceof FrameState) {
-//                boolean delete = false;
-//                if (n.usages().size() == 0 && n.predecessors().size() == 0) {
-//                    delete = true;
-//                }
+        for (Node n : graph.getNodes()) {
+            if (n instanceof Placeholder) {
+                Placeholder p = (Placeholder) n;
+
+                if (p == graph.start().successors().get(0)) {
+                    // nothing to do...
+                } 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.delete();
+                }
+            }
+        }
+        for (Node n : graph.getNodes()) {
+            if (n instanceof FrameState) {
+                boolean delete = false;
+                if (n.usages().size() == 0 && n.predecessors().size() == 0) {
+                    delete = true;
+                }
 //                if (n.predecessors().size() == 0 && n.usages().size() == 1 && n.usages().get(0) instanceof BlockBegin) {
 //                    n.usages().get(0).inputs().replace(n, null);
 //                    delete = true;
 //                }
-//                if (delete) {
-//                    n.delete();
-//                    System.out.println("deleted framestate");
-//                }
-//            }
-//        }
+                if (delete) {
+                    n.delete();
+                }
+            }
+        }
     }
 
     private Block nextBlock(int bci) {
@@ -287,44 +290,44 @@
 
     public void mergeOrClone(Block target, FrameStateAccess newState) {
         Instruction first = target.firstInstruction;
-        int bci = target.startBci;
-        boolean loopHeader = target.isLoopHeader;
+        assert first instanceof StateSplit;
 
-        FrameState existingState;
-        if (first instanceof Placeholder) {
-            existingState = ((Placeholder) first).stateBefore();
-        } else {
-            assert first instanceof BlockBegin;
-            existingState = ((BlockBegin) first).stateBefore();
-        }
+        int bci = target.startBci;
+
+        FrameState existingState = ((StateSplit) first).stateBefore();
 
         if (existingState == null) {
+            assert first instanceof BlockBegin ^ !target.isLoopHeader : "isLoopHeader: " + target.isLoopHeader;
+
             // copy state because it is modified
             FrameState duplicate = newState.duplicate(bci);
 
             // if the block is a loop header, insert all necessary phis
-            if (loopHeader) {
+            if (target.isLoopHeader) {
                 assert first instanceof BlockBegin;
                 insertLoopPhis((BlockBegin) first, duplicate);
                 ((BlockBegin) first).setStateBefore(duplicate);
             } else {
-                if (first instanceof Placeholder) {
-                    ((Placeholder) first).setStateBefore(duplicate);
-                } else {
-                    ((BlockBegin) first).setStateBefore(duplicate);
-                }
+                ((StateSplit) first).setStateBefore(duplicate);
             }
         } else {
-
             if (!C1XOptions.AssumeVerifiedBytecode && !existingState.isCompatibleWith(newState)) {
                 // stacks or locks do not match--bytecodes would not verify
                 throw new CiBailout("stack or locks do not match");
             }
-
             assert existingState.localsSize() == newState.localsSize();
             assert existingState.stackSize() == newState.stackSize();
 
-            existingState.merge((BlockBegin) first, newState);
+            if (first instanceof Placeholder) {
+                BlockBegin merge = new BlockBegin(existingState.bci, target.blockID, target.isLoopHeader, graph);
+                for (Node n : new ArrayList<Node>(first.predecessors())) {
+                    n.successors().replace(first, merge);
+                }
+                target.firstInstruction = merge;
+                merge.setStateBefore(existingState);
+            }
+
+            existingState.merge((BlockBegin) target.firstInstruction, newState);
         }
 
         for (int j = 0; j < frameState.localsSize() + frameState.stackSize(); ++j) {
@@ -411,7 +414,7 @@
             }
             FrameState entryState = frameState.duplicateWithEmptyStack(bci);
 
-            BlockBegin entry = new BlockBegin(bci, ir.nextBlockNumber(), false, graph);
+            StateSplit entry = new Placeholder(graph);
             entry.setStateBefore(entryState);
             ExceptionObject exception = new ExceptionObject(graph);
             entry.appendNext(exception);
@@ -1054,12 +1057,14 @@
 
     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";
+
         if (block.firstInstruction == null) {
-//            if (block.isLoopHeader) {
+            if (block.isLoopHeader) {
                 block.firstInstruction = new BlockBegin(block.startBci, block.blockID, block.isLoopHeader, graph);
-//            } else {
-//                block.firstInstruction = new Placeholder(graph);
-//            }
+            } else {
+                block.firstInstruction = new Placeholder(graph);
+            }
         }
         mergeOrClone(block, stateAfter);
         addToWorkList(block);
@@ -1119,9 +1124,9 @@
             if (!isVisited(block)) {
                 markVisited(block);
                 // now parse the block
-                frameState.initializeFrom(((BlockBegin) block.firstInstruction).stateBefore());
+                frameState.initializeFrom(((StateSplit) block.firstInstruction).stateBefore());
                 lastInstr = block.firstInstruction;
-                assert block.firstInstruction.next() == null;
+                assert block.firstInstruction.next() == null : "instructions already appended at block " + block.blockID;
 
                 if (block instanceof ExceptionBlock) {
                     createExceptionDispatch((ExceptionBlock) block);
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java	Tue May 24 13:55:56 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java	Tue May 24 15:31:52 2011 +0200
@@ -129,9 +129,9 @@
 
         if (orderedBlocks == null) {
             CriticalEdgeFinder finder = new CriticalEdgeFinder(this);
-            getHIRStartBlock().iteratePreOrder(finder);
+            ((BlockBegin) getHIRStartBlock()).iteratePreOrder(finder);
             finder.splitCriticalEdges();
-            ComputeLinearScanOrder computeLinearScanOrder = new ComputeLinearScanOrder(compilation.stats.blockCount, getHIRStartBlock());
+            ComputeLinearScanOrder computeLinearScanOrder = new ComputeLinearScanOrder(compilation.stats.blockCount, (BlockBegin) getHIRStartBlock());
             List<BlockBegin> blocks = computeLinearScanOrder.linearScanOrder();
             orderedBlocks = new ArrayList<LIRBlock>();
 
@@ -187,7 +187,7 @@
             TTY.println("IR for " + compilation.method);
             final InstructionPrinter ip = new InstructionPrinter(TTY.out());
             final BlockPrinter bp = new BlockPrinter(this, ip, cfgOnly);
-            getHIRStartBlock().iteratePreOrder(bp);
+            ((BlockBegin) getHIRStartBlock()).iteratePreOrder(bp);
         }
     }
 
@@ -287,7 +287,7 @@
         return maxLocks;
     }
 
-    public BlockBegin getHIRStartBlock() {
-        return (BlockBegin) compilation.graph.start().successors().get(0);
+    public Instruction getHIRStartBlock() {
+        return (Instruction) compilation.graph.start().successors().get(0);
     }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java	Tue May 24 13:55:56 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java	Tue May 24 15:31:52 2011 +0200
@@ -37,8 +37,7 @@
  */
 public final class BlockBegin extends StateSplit {
 
-    private static final int INPUT_COUNT = 1;
-    private static final int INPUT_STATE_BEFORE = 0;
+    private static final int INPUT_COUNT = 0;
 
     private static final int SUCCESSOR_COUNT = 0;
 
@@ -135,7 +134,7 @@
             ArrayList<BlockBegin> excBlocks = new ArrayList<BlockBegin>();
             while (inst != null) {
                 if (inst instanceof ExceptionEdgeInstruction) {
-                    excBlocks.add(((ExceptionEdgeInstruction) inst).exceptionEdge());
+                    excBlocks.add((BlockBegin) ((ExceptionEdgeInstruction) inst).exceptionEdge());
                 }
                 inst = inst.next();
             }
@@ -360,7 +359,7 @@
         }
         for (Instruction x = next(); x != null; x = x.next()) {
             if (x instanceof ExceptionEdgeInstruction && ((ExceptionEdgeInstruction) x).exceptionEdge() != null) {
-                closure.apply(((ExceptionEdgeInstruction) x).exceptionEdge());
+                closure.apply((BlockBegin) ((ExceptionEdgeInstruction) x).exceptionEdge());
             }
         }
     }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/BlockEnd.java	Tue May 24 13:55:56 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/BlockEnd.java	Tue May 24 15:31:52 2011 +0200
@@ -59,7 +59,7 @@
 
     public Instruction setBlockSuccessor(int index, Instruction n) {
         assert index >= 0 && index < blockSuccessorCount;
-        assert n == null || n instanceof BlockBegin : "only BlockBegins, for now... " + n.getClass();
+//        assert n == null || n instanceof BlockBegin : "only BlockBegins, for now... " + n.getClass();
         return (BlockBegin) successors().set(super.successorCount() + SUCCESSOR_COUNT + index, n);
     }
 
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/ExceptionEdgeInstruction.java	Tue May 24 13:55:56 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/ExceptionEdgeInstruction.java	Tue May 24 15:31:52 2011 +0200
@@ -24,5 +24,5 @@
 
 
 public interface ExceptionEdgeInstruction {
-   BlockBegin exceptionEdge();
+    StateSplit exceptionEdge();
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/Placeholder.java	Tue May 24 13:55:56 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Placeholder.java	Tue May 24 15:31:52 2011 +0200
@@ -24,14 +24,12 @@
 
 import com.oracle.graal.graph.*;
 import com.sun.c1x.debug.*;
-import com.sun.c1x.value.*;
 import com.sun.cri.ci.*;
 
 
-public class Placeholder extends Instruction {
+public class Placeholder extends StateSplit {
 
-    private static final int INPUT_COUNT = 1;
-    private static final int INPUT_STATE_BEFORE = 0;
+    private static final int INPUT_COUNT = 0;
 
     private static final int SUCCESSOR_COUNT = 0;
 
@@ -45,24 +43,6 @@
         return super.successorCount() + SUCCESSOR_COUNT;
     }
 
-    /**
-     * The state for this instruction.
-     */
-    public FrameState stateBefore() {
-        return (FrameState) inputs().get(super.inputCount() + INPUT_STATE_BEFORE);
-    }
-
-    public FrameState setStateBefore(FrameState n) {
-        FrameState oldState = stateBefore();
-        try {
-            return (FrameState) inputs().set(super.inputCount() + INPUT_STATE_BEFORE, n);
-        } finally {
-            if (oldState != n && oldState != null) {
-                oldState.delete();
-            }
-        }
-    }
-
     public Placeholder(Graph graph) {
         super(CiKind.Void, INPUT_COUNT, SUCCESSOR_COUNT, graph);
     }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/Throw.java	Tue May 24 13:55:56 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Throw.java	Tue May 24 15:31:52 2011 +0200
@@ -76,12 +76,12 @@
      * TODO ls: this needs more cleanup - throw should either unwind or jump to the exception dispatch chain
      */
     @Override
-    public BlockBegin exceptionEdge() {
-        return (BlockBegin) successors().get(super.successorCount() + SUCCESSOR_EXCEPTION_EDGE);
+    public StateSplit exceptionEdge() {
+        return (StateSplit) successors().get(super.successorCount() + SUCCESSOR_EXCEPTION_EDGE);
     }
 
-    public BlockBegin setExceptionEdge(BlockBegin n) {
-        return (BlockBegin) successors().set(super.successorCount() + SUCCESSOR_EXCEPTION_EDGE, n);
+    public Instruction setExceptionEdge(Instruction n) {
+        return (Instruction) successors().set(super.successorCount() + SUCCESSOR_EXCEPTION_EDGE, n);
     }
 
     /**
--- a/graal/GraalCompiler/src/com/sun/c1x/observer/CompilationEvent.java	Tue May 24 13:55:56 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/observer/CompilationEvent.java	Tue May 24 15:31:52 2011 +0200
@@ -43,7 +43,7 @@
 
     private final C1XCompilation compilation;
     private final String label;
-    private BlockBegin startBlock;
+    private Instruction startBlock;
 
     private BlockMap blockMap;
     private int codeSize = -1;
@@ -67,14 +67,14 @@
         this.compilation = compilation;
     }
 
-    public CompilationEvent(C1XCompilation compilation, String label, BlockBegin startBlock, boolean hirValid, boolean lirValid) {
+    public CompilationEvent(C1XCompilation compilation, String label, Instruction startBlock, boolean hirValid, boolean lirValid) {
         this(compilation, label);
         this.startBlock = startBlock;
         this.hirValid = hirValid;
         this.lirValid = lirValid;
     }
 
-    public CompilationEvent(C1XCompilation compilation, String label, BlockBegin startBlock, boolean hirValid, boolean lirValid, CiTargetMethod targetMethod) {
+    public CompilationEvent(C1XCompilation compilation, String label, Instruction startBlock, boolean hirValid, boolean lirValid, CiTargetMethod targetMethod) {
         this(compilation, label, startBlock, hirValid, lirValid);
         this.targetMethod = targetMethod;
     }
@@ -108,7 +108,7 @@
         return blockMap;
     }
 
-    public BlockBegin getStartBlock() {
+    public Instruction getStartBlock() {
         return startBlock;
     }
 
--- a/graal/GraalGraph/src/com/oracle/graal/graph/NodeArray.java	Tue May 24 13:55:56 2011 +0200
+++ b/graal/GraalGraph/src/com/oracle/graal/graph/NodeArray.java	Tue May 24 15:31:52 2011 +0200
@@ -130,4 +130,18 @@
     public int size() {
         return nodes.length;
     }
+
+    public void replace(Node node, Node with) {
+        for (int i = 0; i < nodes.length; i++) {
+            if (get(i) == node) {
+                set(i, with);
+            }
+        }
+    }
+
+    public void clearAll() {
+        for (int i = 0; i < nodes.length; i++) {
+            set(i, Node.Null);
+        }
+    }
 }