# HG changeset patch # User Gilles Duboscq # Date 1333724733 -7200 # Node ID dfe925845cad2a907d21c62f428e3fd1837ab5ae # Parent 0a53ed842cb8c317b40925ad7789f97aebbf2c72 Improve exacuation of anchored values, use it to fix if and merge simplifications diff -r 0a53ed842cb8 -r dfe925845cad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginNode.java Fri Apr 06 16:03:51 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginNode.java Fri Apr 06 17:05:33 2012 +0200 @@ -73,17 +73,27 @@ } } - public void evacuateGuards() { + public void evacuateGuards(FixedNode evacuateFrom) { if (!usages().isEmpty()) { - Node prevBegin = predecessor(); + Node prevBegin = evacuateFrom; assert prevBegin != null; while (!(prevBegin instanceof BeginNode)) { prevBegin = prevBegin.predecessor(); } - replaceAtUsages(prevBegin); + for (Node anchored : anchored().snapshot()) { + anchored.replaceFirstInput(this, prevBegin); + } } } + public void prepareDelete() { + prepareDelete((FixedNode) predecessor()); + } + + public void prepareDelete(FixedNode evacuateFrom) { + evacuateGuards(evacuateFrom); + } + @Override public boolean verify() { assertTrue(predecessor() != null || this == ((StructuredGraph) graph()).start() || this instanceof MergeNode, "begin nodes must be connected"); @@ -98,4 +108,8 @@ public NodeIterable guards() { return usages().filter(GuardNode.class); } + + public NodeIterable anchored() { + return usages(); + } } diff -r 0a53ed842cb8 -r dfe925845cad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Fri Apr 06 16:03:51 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Fri Apr 06 17:05:33 2012 +0200 @@ -161,14 +161,16 @@ EndNode falseEnd = (EndNode) falseSuccessor.next(); assert trueEnd.merge() == falseEnd.merge(); + FixedWithNextNode pred = (FixedWithNextNode) predecessor(); MergeNode merge = trueEnd.merge(); + merge.prepareDelete(pred); assert merge.usages().isEmpty(); FixedNode next = merge.next(); merge.setNext(null); setTrueSuccessor(null); setFalseSuccessor(null); - ((FixedWithNextNode) predecessor()).setNext(next); + pred.setNext(next); safeDelete(); trueSuccessor.safeDelete(); falseSuccessor.safeDelete(); diff -r 0a53ed842cb8 -r dfe925845cad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java Fri Apr 06 16:03:51 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java Fri Apr 06 17:05:33 2012 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes; +import static com.oracle.graal.graph.iterators.NodePredicates.*; + import java.util.*; import com.oracle.graal.graph.*; @@ -49,8 +51,13 @@ return usages().filter(LoopEndNode.class); } + @Override + public NodeIterable anchored() { + return super.anchored().filter(isNotA(LoopEndNode.class)); + } + public List orderedLoopEnds() { - List snapshot = usages().filter(LoopEndNode.class).snapshot(); + List snapshot = loopEnds().snapshot(); Collections.sort(snapshot, new Comparator() { @Override public int compare(LoopEndNode o1, LoopEndNode o2) { diff -r 0a53ed842cb8 -r dfe925845cad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java Fri Apr 06 16:03:51 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java Fri Apr 06 17:05:33 2012 +0200 @@ -28,6 +28,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.iterators.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.util.*; /** * Denotes the merging of multiple control-flow paths. @@ -115,12 +116,22 @@ } public NodeIterable phis() { - return this.usages().filter(new NodePredicate() { + return this.usages().filter(PhiNode.class).filter(new NodePredicate() { @Override public boolean apply(Node n) { - return n instanceof PhiNode && ((PhiNode) n).merge() == MergeNode.this; + return ((PhiNode) n).merge() == MergeNode.this; } - }).filter(PhiNode.class); + }); + } + + @Override + public NodeIterable anchored() { + return super.anchored().filter(isNotA(PhiNode.class).or(new NodePredicate() { + @Override + public boolean apply(Node n) { + return ((PhiNode) n).merge() != MergeNode.this; + } + })); } @Override @@ -136,7 +147,9 @@ } } } - Debug.log("Split %s into loop ends for %s", this, begin); + FixedNode evacuateAnchoredTo = new ComputeImmediateDominator(this).compute(); + Debug.log("Split %s into loop ends for %s. Evacuate to %s", this, begin, evacuateAnchoredTo); + this.prepareDelete(evacuateAnchoredTo); int numEnds = this.forwardEndCount(); StructuredGraph graph = (StructuredGraph) graph(); for (int i = 0; i < numEnds - 1; i++) { diff -r 0a53ed842cb8 -r dfe925845cad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Fri Apr 06 16:03:51 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Fri Apr 06 17:05:33 2012 +0200 @@ -168,6 +168,9 @@ public void removeFixed(FixedWithNextNode node) { assert node != null; + if (node instanceof BeginNode) { + ((BeginNode) node).prepareDelete(); + } assert node.usages().isEmpty() : node + " " + node.usages(); FixedNode next = node.next(); node.setNext(null); @@ -208,15 +211,11 @@ assert node.usages().isEmpty(); assert survivingSuccessor >= 0 && survivingSuccessor < node.blockSuccessorCount() : "invalid surviving successor " + survivingSuccessor + " for " + node; BeginNode begin = node.blockSuccessor(survivingSuccessor); - begin.evacuateGuards(); - FixedNode next = begin.next(); - begin.setNext(null); for (int i = 0; i < node.blockSuccessorCount(); i++) { node.setBlockSuccessor(i, null); } - node.replaceAtPredecessors(next); + node.replaceAtPredecessors(begin); node.safeDelete(); - begin.safeDelete(); } public void removeSplitPropagate(ControlSplitNode node, int survivingSuccessor) { @@ -224,9 +223,6 @@ assert node.usages().isEmpty(); assert survivingSuccessor >= 0 && survivingSuccessor < node.blockSuccessorCount() : "invalid surviving successor " + survivingSuccessor + " for " + node; BeginNode begin = node.blockSuccessor(survivingSuccessor); - begin.evacuateGuards(); - FixedNode next = begin.next(); - begin.setNext(null); for (int i = 0; i < node.blockSuccessorCount(); i++) { BeginNode successor = node.blockSuccessor(i); node.setBlockSuccessor(i, null); @@ -234,10 +230,9 @@ GraphUtil.killCFG(successor); } } - if (next.isAlive()) { - node.replaceAtPredecessors(next); + if (begin.isAlive()) { + node.replaceAtPredecessors(begin); node.safeDelete(); - begin.safeDelete(); } else { assert node.isDeleted(); } @@ -257,31 +252,23 @@ assert node != null && replacement != null && node.isAlive() && replacement.isAlive() : "cannot replace " + node + " with " + replacement; assert survivingSuccessor >= 0 && survivingSuccessor < node.blockSuccessorCount() : "invalid surviving successor " + survivingSuccessor + " for " + node; BeginNode begin = node.blockSuccessor(survivingSuccessor); - begin.evacuateGuards(); - FixedNode next = begin.next(); - begin.setNext(null); for (int i = 0; i < node.blockSuccessorCount(); i++) { node.setBlockSuccessor(i, null); } - replacement.setNext(next); + replacement.setNext(begin); node.replaceAndDelete(replacement); - begin.safeDelete(); } public void replaceSplitWithFloating(ControlSplitNode node, FloatingNode replacement, int survivingSuccessor) { assert node != null && replacement != null && node.isAlive() && replacement.isAlive() : "cannot replace " + node + " with " + replacement; assert survivingSuccessor >= 0 && survivingSuccessor < node.blockSuccessorCount() : "invalid surviving successor " + survivingSuccessor + " for " + node; BeginNode begin = node.blockSuccessor(survivingSuccessor); - begin.evacuateGuards(); - FixedNode next = begin.next(); - begin.setNext(null); for (int i = 0; i < node.blockSuccessorCount(); i++) { node.setBlockSuccessor(i, null); } - node.replaceAtPredecessors(next); + node.replaceAtPredecessors(begin); node.replaceAtUsages(replacement); node.safeDelete(); - begin.safeDelete(); } public void addAfterFixed(FixedWithNextNode node, FixedWithNextNode newNode) { @@ -326,13 +313,7 @@ FixedNode sux = merge.next(); FrameState stateAfter = merge.stateAfter(); // evacuateGuards - Node prevBegin = singleEnd.predecessor(); - assert prevBegin != null; - while (!(prevBegin instanceof BeginNode)) { - prevBegin = prevBegin.predecessor(); - } - merge.replaceAtUsages(prevBegin); - + merge.prepareDelete((FixedNode) singleEnd.predecessor()); merge.safeDelete(); if (stateAfter != null && stateAfter.usages().isEmpty()) { stateAfter.safeDelete();