# HG changeset patch # User Gilles Duboscq # Date 1310047461 -7200 # Node ID 4011431b4d85069df228ef135d03c910e582d367 # Parent 03aca60eb99fc08be356ff9856aeaf1e68afb9a4 Removed assertion in EdgeMoveOptimizer that is not valid anymore because of guards Made IdealGraph printing to network faster : use a buffered output stream Change in the scheduling of outer framestates : they would sometimes be pushed too high because of the inner framestate being attached to a merge Framestate now automatically delete their outerframestate if possible when the inner framestate is deleted Peeling : When coloring down, color the exception edges fix around framestates on 'dangling merges' allow some nodes to be white when splitting handle outerframestates properly when splitting diff -r 03aca60eb99f -r 4011431b4d85 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/EdgeMoveOptimizer.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/EdgeMoveOptimizer.java Tue Jul 05 11:42:28 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/EdgeMoveOptimizer.java Thu Jul 07 16:04:21 2011 +0200 @@ -221,11 +221,11 @@ // the instructions are inserted at the end of the block before these two branches int insertIdx = instructions.size() - 2; - if (GraalOptions.DetailedAsserts) { + if (GraalOptions.DetailedAsserts && false) { // not true anymore with guards for (int i = insertIdx - 1; i >= 0; i--) { LIRInstruction op = instructions.get(i); if ((op.code == LIROpcode.Branch || op.code == LIROpcode.CondFloatBranch) && ((LIRBranch) op).block() != null) { - throw new Error("block with two successors can have only two branch instructions"); + throw new Error("block with two successors can have only two branch instructions : error in " + block); } } } diff -r 03aca60eb99f -r 4011431b4d85 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java Tue Jul 05 11:42:28 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java Thu Jul 07 16:04:21 2011 +0200 @@ -229,14 +229,14 @@ if (block != null) { stream.printf("

%d

%n", block.blockID()); if (!(node instanceof Phi || node instanceof FrameState || node instanceof Local || node instanceof LoopCounter) && !block.getInstructions().contains(node)) { - stream.printf("

true

%n"); + stream.println("

true

"); } } else { - stream.printf("

noBlock

%n"); + stream.println("

noBlock

"); noBlockNodes.add(node); } if (loopExits.isMarked(node)) { - stream.printf("

true

%n"); + stream.println("

true

"); } StringBuilder sb = new StringBuilder(); if (loops != null) { @@ -264,7 +264,7 @@ Set nodeBits = bits.get(node); if (nodeBits != null) { for (String bit : nodeBits) { - stream.printf("

true

"); } @@ -310,14 +310,14 @@ private void printBlock(Graph graph, Block block, NodeMap nodeToBlock) { stream.printf(" %n", block.blockID()); - stream.printf(" %n"); + stream.println(" "); for (Block sux : block.getSuccessors()) { if (sux != null) { stream.printf(" %n", sux.blockID()); } } - stream.printf(" %n"); - stream.printf(" %n"); + stream.println(" "); + stream.println(" "); Set nodes = new HashSet(block.getInstructions()); @@ -360,7 +360,7 @@ } } } - stream.printf(" %n"); + stream.println(" "); stream.printf(" %n", block.blockID()); } diff -r 03aca60eb99f -r 4011431b4d85 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinterObserver.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinterObserver.java Tue Jul 05 11:42:28 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinterObserver.java Thu Jul 07 16:04:21 2011 +0200 @@ -101,7 +101,7 @@ try { socket = new Socket(host, port); if (socket.getInputStream().read() == 'y') { - stream = socket.getOutputStream(); + stream = new BufferedOutputStream(socket.getOutputStream(), 0x4000); } else { // server currently does not accept any input socket.close(); diff -r 03aca60eb99f -r 4011431b4d85 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Tue Jul 05 11:42:28 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Thu Jul 07 16:04:21 2011 +0200 @@ -1732,7 +1732,7 @@ } } // the value must be a constant or have a valid operand - assert operand.isLegal() : "this root has not been visited yet; instruction=" + instruction; + assert operand.isLegal() : "this root has not been visited yet; instruction=" + instruction + " currentBlock=" + currentBlock; return operand; } diff -r 03aca60eb99f -r 4011431b4d85 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoopPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoopPhase.java Tue Jul 05 11:42:28 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoopPhase.java Thu Jul 07 16:04:21 2011 +0200 @@ -43,7 +43,7 @@ if (GraalOptions.LoopPeeling) { peeling: for (Loop loop : loops) { - // System.out.println("Peel loop : " + loop.loopBegin()); + //System.out.println("Peel loop : " + loop.loopBegin()); for (Node exit : loop.exits()) { if (!(exit instanceof StateSplit) || ((StateSplit) exit).stateAfter() == null) { // TODO (gd) can not do loop peeling if an exit has no state. see LoopUtil.findNearestMergableExitPoint diff -r 03aca60eb99f -r 4011431b4d85 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java Tue Jul 05 11:42:28 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java Thu Jul 07 16:04:21 2011 +0200 @@ -276,6 +276,8 @@ block = getCommonDominator(block, mergeBlock.getPredecessors().get(i)); } } + } else if (usage instanceof FrameState && ((FrameState) usage).outerFrameState() == n) { + block = getCommonDominator(block, assignLatestPossibleBlockToNode(usage)); } else if (usage instanceof FrameState && ((FrameState) usage).block() != null) { Merge merge = ((FrameState) usage).block(); for (Node pred : merge.cfgPredecessors()) { @@ -411,7 +413,7 @@ int cnt = 0; while (!workList.isEmpty()) { - if (cnt++ > blocks.size() * 10) { + if (cnt++ > blocks.size() * 15) { throw new RuntimeException("(ls) endless loop in computeDominators?"); } Block b = workList.remove(); diff -r 03aca60eb99f -r 4011431b4d85 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/GraphUtil.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/GraphUtil.java Tue Jul 05 11:42:28 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/GraphUtil.java Thu Jul 07 16:04:21 2011 +0200 @@ -82,36 +82,6 @@ colors.set(merge, color); } } - - - /*List startingPoints = new LinkedList(); - for (Entry entry : colors.entries()) { - startingPoints.add(entry.getKey()); - } - NodeWorkList work = colors.graph().createNodeWorkList(); - for (Node startingPoint : startingPoints) { - if (startingPoint instanceof Merge) { - work.addAll(colorCFGDownToMerge(((Merge) startingPoint).next(), colors.get(startingPoint), colors)); - } else { - work.addAll(colorCFGDownToMerge(startingPoint, colors.get(startingPoint), colors)); - } - } - for (Node n : work) { - //System.out.println("Color : work on " + n); - Merge merge = (Merge) n; - ArrayList incomming = new ArrayList(2); - for (EndNode end : merge.cfgPredecessors()) { - incomming.add(colors.get(end)); - } - T color = lambda.color(incomming, merge); - if (color != null) { - colors.set(merge, color); - work.addAll(colorCFGDownToMerge(merge.next(), color, colors)); - } else { - System.out.println("Can not color " + merge); - work.addAgain(merge); - } - }*/ } private static Collection colorCFGDownToMerge(Node from, T color, NodeMap colors) { @@ -129,7 +99,7 @@ break; } colors.set(current, color); - if (current instanceof FixedNodeWithNext) { + if (current instanceof FixedNodeWithNext && !(current instanceof Invoke && ((Invoke) current).exceptionEdge() != null)) { current = ((FixedNodeWithNext) current).next(); } else if (current instanceof EndNode) { current = ((EndNode) current).merge(); @@ -138,6 +108,10 @@ for (Node sux : current.cfgSuccessors()) { work.add(sux); } + } else if (current instanceof Invoke && ((Invoke) current).exceptionEdge() != null) { + Invoke invoke = (Invoke) current; + work.add(invoke.next()); + work.add(invoke.exceptionEdge()); } current = null; } @@ -152,6 +126,8 @@ void fixNode(Node node, T color); Value fixPhiInput(Value input, T color); boolean explore(Node n); + List parentColors(T color); + Merge merge(T color); } // TODO (gd) rework that code around Phi handling : too complicated @@ -214,11 +190,14 @@ } else { T color = internalColoring.get(usage); if (color == null) { - //System.out.println("Split : color from " + usage + " is null"); - delay = true; - break; + //System.out.println("Split : color from " + usage + " is null : " + (lambda.explore(usage) ? "Should be colored" : "Should be white")); + if (lambda.explore(usage)) { + delay = true; + break; + } + } else { + colors.add(color); } - colors.add(color); } } if (delay) { @@ -235,19 +214,44 @@ internalColoring.put(node, color); lambda.fixNode(node, color); } else { - //System.out.println("Split : " + colors.size() + " colors, coloring, spliting, fixing"); - for (T color : colors) { - Node newNode = node.copy(); - for (int i = 0; i < node.inputs().size(); i++) { - Node input = node.inputs().get(i); - newNode.inputs().setOrExpand(i, input); + Map newNodes = new HashMap(); + Queue colorQueue = new LinkedList(colors); + while (!colorQueue.isEmpty()) { + T color = colorQueue.poll(); + List parentColors = lambda.parentColors(color); + Node newNode; + if (parentColors.size() > 1 && !(node instanceof FrameState) && colors.containsAll(parentColors)) { + boolean ready = true; + for (T parentColor : parentColors) { + if (newNodes.get(parentColor) == null) { + ready = false; + break; + } + } + if (!ready) { + colorQueue.offer(color); + continue; + } + Phi phi = new Phi(((Value) node).kind, lambda.merge(color), node.graph()); + for (T parentColor : parentColors) { + Node input = newNodes.get(parentColor); + phi.addInput(input); + } + newNode = phi; + } else { + newNode = node.copy(); + for (int i = 0; i < node.inputs().size(); i++) { + Node input = node.inputs().get(i); + newNode.inputs().setOrExpand(i, input); + } + for (int i = 0; i < node.successors().size(); i++) { + Node input = node.successors().get(i); + newNode.successors().setOrExpand(i, input); + } + internalColoring.put(newNode, color); + lambda.fixSplit(node, newNode, color); } - for (int i = 0; i < node.successors().size(); i++) { - Node input = node.successors().get(i); - newNode.successors().setOrExpand(i, input); - } - internalColoring.put(newNode, color); - lambda.fixSplit(node, newNode, color); + newNodes.put(color, newNode); LinkedList dataUsages = new LinkedList(); for (Node usage : node.dataUsages()) { dataUsages.add(usage); @@ -273,12 +277,15 @@ } } } + lambda.fixNode(node, null /*white*/); } if (node instanceof StateSplit) { FrameState stateAfter = ((StateSplit) node).stateAfter(); if (stateAfter != null && lambda.explore(stateAfter) && !work.isNew(stateAfter)) { //System.out.println("Split : Add framestate to work"); - work.add(stateAfter); + if (!(node instanceof Merge && coloring.get(((Merge) node).next()) == null)) { // not dangling colored merge + work.add(stateAfter); + } } } diff -r 03aca60eb99f -r 4011431b4d85 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/LoopUtil.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/LoopUtil.java Tue Jul 05 11:42:28 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/LoopUtil.java Thu Jul 07 16:04:21 2011 +0200 @@ -81,7 +81,8 @@ public final NodeMap phis; public final NodeMap phiInits; public final NodeMap dataOut; - public PeelingResult(FixedNode begin, FixedNode end, NodeMap exits, NodeMap phis, NodeMap phiInits, NodeMap dataOut, NodeBitMap unaffectedExits) { + public final NodeBitMap exitFrameStates; + public PeelingResult(FixedNode begin, FixedNode end, NodeMap exits, NodeMap phis, NodeMap phiInits, NodeMap dataOut, NodeBitMap unaffectedExits, NodeBitMap exitFrameStates) { this.begin = begin; this.end = end; this.exits = exits; @@ -89,6 +90,7 @@ this.phiInits = phiInits; this.dataOut = dataOut; this.unaffectedExits = unaffectedExits; + this.exitFrameStates = exitFrameStates; } } @@ -114,12 +116,7 @@ public static NodeBitMap computeLoopExits(LoopBegin loopBegin, NodeBitMap nodes) { Graph graph = loopBegin.graph(); NodeBitMap exits = graph.createNodeBitMap(); - NodeFlood workCFG = graph.createNodeFlood(); - workCFG.add(loopBegin.loopEnd()); - for (Node n : workCFG) { - if (n == loopBegin) { - continue; - } + for (Node n : markUpCFG(loopBegin, loopBegin.loopEnd())) { if (IdentifyBlocksPhase.trueSuccessorCount(n) > 1) { for (Node sux : n.cfgSuccessors()) { if (!nodes.isMarked(sux) && sux instanceof FixedNode) { @@ -127,9 +124,6 @@ } } } - for (Node pred : n.cfgPredecessors()) { - workCFG.add(pred); - } } return exits; } @@ -169,7 +163,8 @@ } NodeBitMap inOrBefore = loopBegin.graph().createNodeBitMap(); for (Node n : workData2) { - markWithState(n, inOrBefore); + //markWithState(n, inOrBefore); + inOrBefore.mark(n); if (n instanceof Phi) { // filter out data graph cycles Phi phi = (Phi) n; if (!phi.isDead()) { @@ -195,8 +190,14 @@ workData2.add(usage); } } + if (n instanceof StateSplit) { + FrameState stateAfter = ((StateSplit) n).stateAfter(); + if (stateAfter != null) { + workData2.add(stateAfter); + } + } } - if (!recurse) { + /*if (!recurse) { recurse = true; GraalCompilation compilation = GraalCompilation.compilation(); if (compilation.compiler.isObserved()) { @@ -207,7 +208,7 @@ compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "Compute loop nodes loop#" + loopBegin.id(), loopBegin.graph(), true, false, debug)); } recurse = false; - } + }*/ inOrAfter.setIntersect(inOrBefore); loopNodes.setUnion(inOrAfter); return loopNodes; @@ -276,9 +277,9 @@ System.out.println(" - " + entry.getKey() + " -> " + entry.getValue()); }*/ rewirePeeling(peeling, loop, loopEnd); - if (compilation.compiler.isObserved()) { + /*if (compilation.compiler.isObserved()) { compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After rewirePeeling", loopEnd.graph(), true, false)); - } + }*/ // update parents Loop parent = loop.parent(); while (parent != null) { @@ -317,7 +318,14 @@ for (Entry entry : peeling.phis.entries()) { Phi phi = (Phi) entry.getKey(); Placeholder p = entry.getValue(); - p.replaceAndDelete(phi.valueAt(phiInitIndex)); + Value init = phi.valueAt(phiInitIndex); + p.replaceAndDelete(init); + for (Entry dataEntry : peeling.dataOut.entries()) { + if (dataEntry.getValue() == p) { + dataEntry.setValue(init); + //System.out.println("Patch dataOut : " + dataEntry.getKey() + " -> " + dataEntry.getValue()); + } + } } for (Entry entry : peeling.phiInits.entries()) { Phi phi = (Phi) entry.getKey(); @@ -341,10 +349,10 @@ EndNode oEnd = new EndNode(graph); EndNode nEnd = new EndNode(graph); Merge merge = new Merge(graph); - FrameState newState = newExit.stateAfter(); + FrameState originalState = original.stateAfter(); merge.addEnd(nEnd); merge.addEnd(oEnd); - merge.setStateAfter(newState.duplicate(newState.bci)); + merge.setStateAfter(originalState.duplicate(originalState.bci, true)); merge.setNext(original.next()); original.setNext(oEnd); newExit.setNext(nEnd); @@ -357,40 +365,20 @@ EndNode oEnd = (EndNode) original.next(); Merge merge = oEnd.merge(); EndNode nEnd = merge.endAt(1 - merge.phiPredecessorIndex(oEnd)); - FrameState newState = merge.stateAfter(); - FrameState originalState = original.stateAfter(); - while (newState != null) { - assert originalState != null; - NodeArray oInputs = originalState.inputs(); - NodeArray nInputs = newState.inputs(); - int oSize = oInputs.size(); - for (int i = 1; i < oSize; i++) { // TODO (gd) start from 1 to avoid outer framestate, hacky.. - Node newValue = nInputs.get(i); - Node originalValue = oInputs.get(i); - if (newValue != originalValue) { - Node newExit = nEnd.singlePredecessor(); - NodeMap phiMap = newExitValues.get(originalValue); - if (phiMap == null) { - phiMap = graph.createNodeMap(); - newExitValues.set(originalValue, phiMap); - } - phiMap.set(original, (Value) originalValue); - phiMap.set(newExit, (Value) newValue); + Node newExit = nEnd.singlePredecessor(); + for (Entry dataEntry : peeling.dataOut.entries()) { + Node originalValue = dataEntry.getKey(); + Node newValue = dataEntry.getValue(); + NodeMap phiMap = newExitValues.get(originalValue); + if (phiMap == null) { + phiMap = graph.createNodeMap(); + newExitValues.set(originalValue, phiMap); + } + phiMap.set(original, (Value) originalValue); + phiMap.set(newExit, (Value) newValue); + } + } - phiMap = newExitValues.get(newValue); - if (phiMap == null) { - phiMap = graph.createNodeMap(); - newExitValues.set(newValue, phiMap); - } - phiMap.set(original, (Value) originalValue); - phiMap.set(nEnd, (Value) newValue); - } - } - newState = newState.outerFrameState(); - originalState = originalState.outerFrameState(); - } - assert originalState == null; - } for (Entry> entry : newExitValues.entries()) { Value original = (Value) entry.getKey(); NodeMap pointToValue = entry.getValue(); @@ -402,10 +390,10 @@ } } - replaceValuesAtLoopExits(newExitValues, loop, exitPoints); + replaceValuesAtLoopExits(newExitValues, loop, exitPoints, peeling.exitFrameStates); } - private static void replaceValuesAtLoopExits(final NodeMap> newExitValues, Loop loop, List exitPoints) { + private static void replaceValuesAtLoopExits(final NodeMap> newExitValues, Loop loop, List exitPoints, final NodeBitMap exitFrameStates) { Graph graph = loop.loopBegin().graph(); final NodeMap colors = graph.createNodeMap(); @@ -461,18 +449,20 @@ Map debug = new HashMap(); debug.put("loopExits", colors); debug.put("inOrBefore", inOrBefore); + debug.put("exitFrameStates", exitFrameStates); compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After coloring", graph, true, false, debug)); } GraphUtil.splitFromColoring(colors, new ColorSplitingLambda(){ @Override public void fixSplit(Node oldNode, Node newNode, Node color) { + assert color != null; this.fixNode(newNode, color); } private Value getValueAt(Node point, NodeMap valueMap, CiKind kind) { Value value = valueMap.get(point); if (value != null) { - //System.out.println("getValueAt(" + point + ", valueMap, kind) = " + value); + //System.out.println("getValueAt(" + point + ", valueMap, kind) = (cached) " + value); return value; } Merge merge = (Merge) point; @@ -494,31 +484,45 @@ for (EndNode end : merge.cfgPredecessors()) { phi.addInput(getValueAt(colors.get(end), valueMap, kind)); } - //System.out.println("getValueAt(" + point + ", valueMap, kind) = " + phi); + //System.out.println("getValueAt(" + point + ", valueMap, kind) = (new-phi) " + phi); return phi; } else { assert v != null; valueMap.set(point, v); - //System.out.println("getValueAt(" + point + ", valueMap, kind) = " + v); + //System.out.println("getValueAt(" + point + ", valueMap, kind) = (unique) " + v); return v; } } @Override public boolean explore(Node n) { - return !inOrBefore.isNew(n) && !inOrBefore.isMarked(n) && !(n instanceof Local) && !(n instanceof Constant); //TODO (gd) hum + return (!exitFrameStates.isNew(n) && exitFrameStates.isMarked(n)) + || (!inOrBefore.isNew(n) && !inOrBefore.isMarked(n) && !(n instanceof Local) && !danglingMergeFrameState(n)); //TODO (gd) hum + } + public boolean danglingMergeFrameState(Node n) { + if (!(n instanceof FrameState)) { + return false; + } + Merge block = ((FrameState) n).block(); + return block != null && colors.get(block.next()) == null; } @Override public void fixNode(Node node, Node color) { //System.out.println("fixNode(" + node + ", " + color + ")"); - for (int i = 0; i < node.inputs().size(); i++) { - Node input = node.inputs().get(i); - if (input == null || newExitValues.isNew(input)) { - continue; - } - NodeMap valueMap = newExitValues.get(input); - if (valueMap != null) { - Value replacement = getValueAt(color, valueMap, ((Value) input).kind); - node.inputs().set(i, replacement); + if (color == null) { + // 'white' it out : make non-explorable + exitFrameStates.clear(node); + inOrBefore.mark(node); + } else { + for (int i = 0; i < node.inputs().size(); i++) { + Node input = node.inputs().get(i); + if (input == null || newExitValues.isNew(input)) { + continue; + } + NodeMap valueMap = newExitValues.get(input); + if (valueMap != null) { + Value replacement = getValueAt(color, valueMap, ((Value) input).kind); + node.inputs().set(i, replacement); + } } } } @@ -532,11 +536,28 @@ return getValueAt(color, valueMap, input.kind); } return input; - }}); + } + @Override + public List parentColors(Node color) { + if (!(color instanceof Merge)) { + return Collections.emptyList(); + } + Merge merge = (Merge) color; + List parentColors = new ArrayList(merge.phiPredecessorCount()); + for (Node pred : merge.phiPredecessors()) { + parentColors.add(colors.get(pred)); + } + return parentColors; + } + @Override + public Merge merge(Node color) { + return (Merge) color; + } + }); - if (compilation.compiler.isObserved()) { + /*if (compilation.compiler.isObserved()) { compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After split from colors", graph, true, false)); - } + }*/ } private static PeelingResult preparePeeling(Loop loop, FixedNode from) { @@ -544,11 +565,11 @@ Graph graph = loopBegin.graph(); NodeBitMap marked = computeLoopNodesFrom(loopBegin, from); GraalCompilation compilation = GraalCompilation.compilation(); - if (compilation.compiler.isObserved()) { + /*if (compilation.compiler.isObserved()) { Map debug = new HashMap(); debug.put("marked", marked); compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After computeLoopNodesFrom", loopBegin.graph(), true, false, debug)); - } + }*/ if (from == loopBegin.loopEnd()) { clearWithState(from, marked); } @@ -558,16 +579,35 @@ NodeMap exits = graph.createNodeMap(); NodeBitMap unaffectedExits = graph.createNodeBitMap(); NodeBitMap clonedExits = graph.createNodeBitMap(); + NodeBitMap exitFrameStates = graph.createNodeBitMap(); for (Node exit : loop.exits()) { if (marked.isMarked(exit.singlePredecessor())) { StateSplit pExit = findNearestMergableExitPoint(exit, marked); markWithState(pExit, marked); clonedExits.mark(pExit); + FrameState stateAfter = pExit.stateAfter(); + while (stateAfter != null) { + exitFrameStates.mark(stateAfter); + stateAfter = stateAfter.outerFrameState(); + } } else { unaffectedExits.mark(exit); } } + NodeBitMap dataOut = graph.createNodeBitMap(); + for (Node n : marked) { + if (!(n instanceof FrameState)) { + for (Node usage : n.dataUsages()) { + if ((!marked.isMarked(usage) && !((usage instanceof Phi) && ((Phi) usage).merge() != loopBegin)) + || (marked.isMarked(usage) && exitFrameStates.isMarked(usage))) { + dataOut.mark(n); + break; + } + } + } + } + for (Node n : marked) { if (n instanceof Phi && ((Phi) n).merge() == loopBegin) { Placeholder p = new Placeholder(graph); @@ -591,37 +631,45 @@ Map duplicates = graph.addDuplicate(marked, replacements); + /*System.out.println("Dup mapping :"); + for (Entry entry : duplicates.entrySet()) { + System.out.println(" - " + entry.getKey().id() + " -> " + entry.getValue().id()); + }*/ + + NodeMap dataOutMapping = graph.createNodeMap(); + for (Node n : dataOut) { + Node newOut = duplicates.get(n); + if (newOut == null) { + newOut = replacements.get(n); + } + assert newOut != null; + dataOutMapping.set(n, newOut); + } + for (Node n : clonedExits) { exits.set(n, (StateSplit) duplicates.get(n)); } - NodeMap dataOut = graph.createNodeMap(); - for (Node n : marked) { - for (Node usage : n.dataUsages()) { - if (!marked.isMarked(usage) - && !loop.nodes().isNew(usage) && loop.nodes().isMarked(usage) - && !((usage instanceof Phi) && ((Phi) usage).merge() != loopBegin)) { - dataOut.set(n, duplicates.get(n)); - break; + NodeMap phiInits = graph.createNodeMap(); + if (from == loopBegin.loopEnd()) { + int backIndex = loopBegin.phiPredecessorIndex(loopBegin.loopEnd()); + int fowardIndex = loopBegin.phiPredecessorIndex(loopBegin.forwardEdge()); + for (Phi phi : loopBegin.phis()) { + Value backValue = phi.valueAt(backIndex); + if (marked.isMarked(backValue)) { + phiInits.set(phi, duplicates.get(backValue)); + } else if (backValue instanceof Phi && ((Phi) backValue).merge() == loopBegin) { + Phi backPhi = (Phi) backValue; + phiInits.set(phi, backPhi.valueAt(fowardIndex)); + } else { + phiInits.set(phi, backValue); } } } - NodeMap phiInits = graph.createNodeMap(); - int backIndex = loopBegin.phiPredecessorIndex(loopBegin.loopEnd()); - int fowardIndex = loopBegin.phiPredecessorIndex(loopBegin.forwardEdge()); - for (Phi phi : loopBegin.phis()) { - Value backValue = phi.valueAt(backIndex); - if (marked.isMarked(backValue)) { - phiInits.set(phi, duplicates.get(backValue)); - } else if (backValue instanceof Phi && ((Phi) backValue).merge() == loopBegin) { - Phi backPhi = (Phi) backValue; - phiInits.set(phi, backPhi.valueAt(fowardIndex)); - } - } FixedNode newBegin = (FixedNode) duplicates.get(loopBegin.next()); FixedNode newFrom = (FixedNode) duplicates.get(from == loopBegin.loopEnd() ? from.singlePredecessor() : from); - return new PeelingResult(newBegin, newFrom, exits, phis, phiInits, dataOut, unaffectedExits); + return new PeelingResult(newBegin, newFrom, exits, phis, phiInits, dataOutMapping, unaffectedExits, exitFrameStates); } private static StateSplit findNearestMergableExitPoint(Node exit, NodeBitMap marked) { diff -r 03aca60eb99f -r 4011431b4d85 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameState.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameState.java Tue Jul 05 11:42:28 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameState.java Thu Jul 07 16:04:21 2011 +0200 @@ -129,9 +129,17 @@ * Gets a copy of this frame state. */ public FrameState duplicate(int bci) { + return duplicate(bci, false); + } + + public FrameState duplicate(int bci, boolean duplicateOuter) { FrameState other = new FrameState(method, bci, localsSize, stackSize, locksSize, rethrowException, graph()); other.inputs().setAll(inputs()); - other.setOuterFrameState(outerFrameState()); + FrameState outerFrameState = outerFrameState(); + if (duplicateOuter && outerFrameState != null) { + outerFrameState = outerFrameState.duplicate(outerFrameState.bci, duplicateOuter); + } + other.setOuterFrameState(outerFrameState); return other; } @@ -567,6 +575,15 @@ } @Override + public void delete() { + FrameState outerFrameState = outerFrameState(); + super.delete(); + if (outerFrameState != null && outerFrameState.usages().isEmpty()) { + outerFrameState.delete(); + } + } + + @Override public Node copy(Graph into) { return new FrameState(method, bci, localsSize, stackSize, locksSize, rethrowException, into); }