# HG changeset patch # User Thomas Wuerthinger # Date 1306334908 -7200 # Node ID aeccd2af4e9e891331b2feb57b17c0b9de4402b7 # Parent df4c5254c5ccd9d6ac0460b833dd989327947aec Fixes around critical edge split and placeholder removal after goto removal. diff -r df4c5254c5cc -r aeccd2af4e9e graal/GraalCompiler/src/com/oracle/max/graal/schedule/Schedule.java --- 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 blockBeginNodes = new ArrayList(); - 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)); + } } /* diff -r df4c5254c5cc -r aeccd2af4e9e graal/GraalCompiler/src/com/sun/c1x/alloc/LinearScan.java --- 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"); } diff -r df4c5254c5cc -r aeccd2af4e9e graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java --- 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) { diff -r df4c5254c5cc -r aeccd2af4e9e graal/GraalCompiler/src/com/sun/c1x/graph/CriticalEdgeFinder.java --- 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> edges = C1XOptions.DetailedAsserts ? - new LinkedHashMap>() : - new HashMap>(); + private Map> edges = C1XOptions.DetailedAsserts ? + new LinkedHashMap>() : + new HashMap>(); public CriticalEdgeFinder(List 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()); + edges.put(block, new ArrayList()); } edges.get(block).add(succ); } public void splitCriticalEdges() { - for (Map.Entry> entry : edges.entrySet()) { + for (Map.Entry> 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; // } diff -r df4c5254c5cc -r aeccd2af4e9e graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java --- 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(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)); } diff -r df4c5254c5cc -r aeccd2af4e9e graal/GraalCompiler/src/com/sun/c1x/graph/IR.java --- 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(); diff -r df4c5254c5cc -r aeccd2af4e9e graal/GraalCompiler/src/com/sun/c1x/lir/LIRBlock.java --- 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; } } } diff -r df4c5254c5cc -r aeccd2af4e9e graal/GraalCompiler/src/com/sun/c1x/lir/LIRInstruction.java --- 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 diff -r df4c5254c5cc -r aeccd2af4e9e graal/GraalGraph/src/com/oracle/graal/graph/NodeArray.java --- 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 { @@ -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; } diff -r df4c5254c5cc -r aeccd2af4e9e graal/GraalRuntime/src/com/oracle/graal/runtime/HotSpotOptions.java --- 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;