# HG changeset patch # User Lukas Stadler # Date 1326895759 -3600 # Node ID 72d099e5be617739e43285bd07575c93f71064ca # Parent 4a609a685fa48c1792d5793919c05908381feae6 more CanonicalizerPhase simplifications, added Simplifiable interface diff -r 4a609a685fa4 -r 72d099e5be61 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/CanonicalizerPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/CanonicalizerPhase.java Tue Jan 17 19:45:39 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/CanonicalizerPhase.java Wed Jan 18 15:09:19 2012 +0100 @@ -26,7 +26,6 @@ import com.oracle.max.cri.ri.*; import com.oracle.max.criutils.*; import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.util.*; import com.oracle.max.graal.graph.*; import com.oracle.max.graal.nodes.*; import com.oracle.max.graal.nodes.calc.*; @@ -73,50 +72,45 @@ // cases: original node: // |Floating|Fixed-unconnected|Fixed-connected| // -------------------------------------------- -// null| 1 | X | 1 | +// null| 1 | X | 3 | // -------------------------------------------- // Floating| 2 | X | 4 | // canonical node: -------------------------------------------- -// Fixed-unconnected| X | X | 3 | +// Fixed-unconnected| X | X | 5 | // -------------------------------------------- -// Fixed-connected| 2 | X | 4 | +// Fixed-connected| 2 | X | 6 | // -------------------------------------------- // X: must not happen (checked with assertions) - if (canonical == null) { - // case 1 - node.replaceAtUsages(null); - if (Util.isFixed(node)) { - graph.removeFixed((FixedWithNextNode) node); + if (canonical != node) { + if (node instanceof FloatingNode) { + if (canonical == null) { + // case 1 + graph.removeFloating((FloatingNode) node); + } else { + // case 2 + assert canonical instanceof FloatingNode || (canonical instanceof FixedNode && canonical.predecessor() != null) : node + " -> " + canonical + + " : replacement should be floating or fixed and connected"; + graph.replaceFloating((FloatingNode) node, canonical); + } } else { - graph.removeFloating((FloatingNode) node); - } - } else if (canonical != node) { - if (node instanceof FloatingNode) { - // case 2 - assert Util.isFloating(canonical) || (Util.isFixed(canonical) && canonical.predecessor() != null) : canonical; - graph.replaceFloating((FloatingNode) node, canonical); - } else { - assert Util.isFixed(node) && node.predecessor() != null : node + " -> " + canonical + " : node should be fixed & connected (" + node.predecessor() + ")"; - if (Util.isFixed(canonical) && canonical.predecessor() == null) { + assert node instanceof FixedWithNextNode && node.predecessor() != null : node + " -> " + canonical + " : node should be fixed & connected (" + node.predecessor() + ")"; + if (canonical == null) { // case 3 - graph.replaceFixedWithFixed((FixedWithNextNode) node, (FixedWithNextNode) canonical); - } else { + graph.removeFixed((FixedWithNextNode) node); + } else if (canonical instanceof FloatingNode) { // case 4 - node.replaceAtUsages(canonical); - if (node instanceof FixedWithNextNode) { + graph.replaceFixedWithFloating((FixedWithNextNode) node, (FloatingNode) canonical); + } else { + assert canonical instanceof FixedNode; + if (canonical.predecessor() == null) { + assert !canonical.cfgSuccessors().iterator().hasNext() : "replacement " + canonical + " shouldn't have successors"; + // case 5 + graph.replaceFixedWithFixed((FixedWithNextNode) node, (FixedWithNextNode) canonical); + } else { + assert canonical.cfgSuccessors().iterator().hasNext() : "replacement " + canonical + " should have successors"; + // case 6 + node.replaceAtUsages(canonical); graph.removeFixed((FixedWithNextNode) node); - } else if (node instanceof ControlSplitNode) { - // FIX(ls) is this logic really used? the semantics might be hard to understand... - ControlSplitNode split = (ControlSplitNode) node; - int survivingSuccessor = -1; - for (int i = 0; i < split.blockSuccessorCount(); i++) { - if (survivingSuccessor == -1 && split.blockSuccessor(i) != null) { - survivingSuccessor = i; - } else { - assert split.blockSuccessor(i) == null; - } - } - graph.removeSplit(split, survivingSuccessor); } } } @@ -128,6 +122,8 @@ nodeWorkList.replaced(canonical, node, false); } } + } else if (node instanceof Simplifiable) { + ((Simplifiable) node).simplify(tool); } } @@ -148,7 +144,7 @@ } } - private static final class Tool implements CanonicalizerTool { + private static final class Tool implements SimplifierTool { private final NodeWorkList nodeWorkList; private final RiRuntime runtime; @@ -222,8 +218,10 @@ FixedNode next = merge.next(); merge.setNext(null); pred.replaceFirstSuccessor(replacedSux, next); - if (merge.stateAfter().usages().size() == 1) { - merge.stateAfter().delete(); + FrameState stateAfter = merge.stateAfter(); + merge.setStateAfter(null); + if (stateAfter.usages().isEmpty()) { + stateAfter.safeDelete(); } merge.safeDelete(); replacedSux.safeDelete(); @@ -268,5 +266,10 @@ public RiRuntime runtime() { return runtime; } + + @Override + public void addToWorkList(Node node) { + nodeWorkList.add(node); + } } } diff -r 4a609a685fa4 -r 72d099e5be61 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/SnippetIntrinsificationPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/SnippetIntrinsificationPhase.java Tue Jan 17 19:45:39 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/SnippetIntrinsificationPhase.java Wed Jan 18 15:09:19 2012 +0100 @@ -124,15 +124,21 @@ Invoke invokeNode = (Invoke) node; MethodCallTargetNode callTarget = invokeNode.callTarget(); if (pool.isBoxingMethod(callTarget.targetMethod())) { + FrameState stateAfter = invokeNode.stateAfter(); + assert stateAfter.usages().size() == 1; + invokeNode.node().replaceAtUsages(null); + ValueNode result = callTarget.arguments().get(0); + StructuredGraph graph = (StructuredGraph) node.graph(); if (invokeNode instanceof InvokeWithExceptionNode) { // Destroy exception edge & clear stateAfter. InvokeWithExceptionNode invokeWithExceptionNode = (InvokeWithExceptionNode) invokeNode; + invokeWithExceptionNode.killExceptionEdge(); + graph.removeSplit(invokeWithExceptionNode, InvokeWithExceptionNode.NORMAL_EDGE); + } else { + graph.removeFixed((InvokeNode) invokeNode); } - assert invokeNode.stateAfter().usages().size() == 1; - invokeNode.stateAfter().delete(); - invokeNode.node().replaceAndDelete(invokeNode.next()); - ValueNode result = callTarget.arguments().get(0); + stateAfter.safeDelete(); GraphUtil.propagateKill(callTarget); return result; } diff -r 4a609a685fa4 -r 72d099e5be61 graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Node.java --- a/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Node.java Tue Jan 17 19:45:39 2012 +0100 +++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Node.java Wed Jan 18 15:09:19 2012 +0100 @@ -311,7 +311,7 @@ delete(); } - public void delete() { + private void delete() { clearInputs(); clearSuccessors(); graph.unregister(this); diff -r 4a609a685fa4 -r 72d099e5be61 graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderPhase.java Tue Jan 17 19:45:39 2012 +0100 +++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderPhase.java Wed Jan 18 15:09:19 2012 +0100 @@ -1330,8 +1330,8 @@ EndNode loopEntryEnd = begin.forwardEdge(); FixedNode beginSucc = begin.next(); FrameState stateAfter = begin.stateAfter(); - stateAfter.delete(); begin.safeDelete(); + stateAfter.safeDelete(); loopEntryEnd.replaceAndDelete(beginSucc); } } diff -r 4a609a685fa4 -r 72d099e5be61 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/AnchorNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/AnchorNode.java Tue Jan 17 19:45:39 2012 +0100 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/AnchorNode.java Wed Jan 18 15:09:19 2012 +0100 @@ -44,7 +44,7 @@ @Override public ValueNode canonical(CanonicalizerTool tool) { if (this.usages().size() == 0 && guards.size() == 0) { - return next(); + return null; } return this; } diff -r 4a609a685fa4 -r 72d099e5be61 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/BeginNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/BeginNode.java Tue Jan 17 19:45:39 2012 +0100 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/BeginNode.java Wed Jan 18 15:09:19 2012 +0100 @@ -28,7 +28,7 @@ import com.oracle.max.graal.nodes.spi.*; import com.oracle.max.graal.nodes.type.*; -public class BeginNode extends AbstractStateSplit implements LIRLowerable, Canonicalizable { +public class BeginNode extends AbstractStateSplit implements LIRLowerable, Simplifiable { public BeginNode() { super(StampFactory.illegal()); } @@ -50,22 +50,23 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public void simplify(SimplifierTool tool) { FixedNode prev = (FixedNode) this.predecessor(); if (prev == null) { // This is the start node. - return this; } else if (prev instanceof ControlSplitNode) { // This begin node is necessary. - return this; } else { // This begin node can be removed and all guards moved up to the preceding begin node. Node prevBegin = prev; while (!(prevBegin instanceof BeginNode)) { prevBegin = prevBegin.predecessor(); } - this.replaceAtUsages(prevBegin); - return next(); + for (Node usage : usages()) { + tool.addToWorkList(usage); + } + replaceAtUsages(prevBegin); + ((StructuredGraph) graph()).removeFixed(this); } } diff -r 4a609a685fa4 -r 72d099e5be61 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/FixedGuardNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/FixedGuardNode.java Tue Jan 17 19:45:39 2012 +0100 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/FixedGuardNode.java Wed Jan 18 15:09:19 2012 +0100 @@ -28,7 +28,7 @@ import com.oracle.max.graal.nodes.spi.*; import com.oracle.max.graal.nodes.type.*; -public final class FixedGuardNode extends FixedWithNextNode implements Canonicalizable, Lowerable, LIRLowerable { +public final class FixedGuardNode extends FixedWithNextNode implements Simplifiable, Lowerable, LIRLowerable { @Input private final NodeInputList conditions; @@ -53,7 +53,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public void simplify(SimplifierTool tool) { for (BooleanNode n : conditions.snapshot()) { if (n instanceof ConstantNode) { ConstantNode c = (ConstantNode) n; @@ -61,18 +61,17 @@ conditions.remove(n); } else { FixedNode next = this.next(); + setNext(graph().add(new DeoptimizeNode(DeoptAction.InvalidateRecompile))); if (next != null) { tool.deleteBranch(next); } - return graph().add(new DeoptimizeNode(DeoptAction.InvalidateRecompile)); + return; } } } - if (conditions.isEmpty()) { - return next(); + ((StructuredGraph) graph()).removeFixed(this); } - return this; } @Override diff -r 4a609a685fa4 -r 72d099e5be61 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/FrameState.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/FrameState.java Tue Jan 17 19:45:39 2012 +0100 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/FrameState.java Wed Jan 18 15:09:19 2012 +0100 @@ -476,7 +476,7 @@ if (!phiNode.isDeleted()) { Collection phiUsages = phiNode.usages().filter(PhiNode.class).snapshot(); phiNode.replaceAtUsages(null); - phiNode.delete(); + phiNode.safeDelete(); for (Node n : phiUsages) { deleteInvalidPhi((PhiNode) n); } diff -r 4a609a685fa4 -r 72d099e5be61 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/IfNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/IfNode.java Tue Jan 17 19:45:39 2012 +0100 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/IfNode.java Wed Jan 18 15:09:19 2012 +0100 @@ -22,6 +22,9 @@ */ package com.oracle.max.graal.nodes; +import java.util.*; + +import com.oracle.max.cri.ci.*; import com.oracle.max.graal.nodes.spi.*; import com.oracle.max.graal.nodes.type.*; @@ -29,7 +32,9 @@ * The {@code IfNode} represents a branch that can go one of two directions depending on the outcome of a * comparison. */ -public final class IfNode extends ControlSplitNode implements Canonicalizable, LIRLowerable { +public final class IfNode extends ControlSplitNode implements Simplifiable, LIRLowerable { + public static final int TRUE_EDGE = 0; + public static final int FALSE_EDGE = 1; private static final BeginNode[] EMPTY_IF_SUCCESSORS = new BeginNode[] {null, null}; @@ -99,35 +104,76 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public void simplify(SimplifierTool tool) { if (compare() instanceof ConstantNode) { ConstantNode c = (ConstantNode) compare(); if (c.asConstant().asBoolean()) { tool.deleteBranch(falseSuccessor()); - return trueSuccessor(); + tool.addToWorkList(trueSuccessor()); + ((StructuredGraph) graph()).removeSplit(this, TRUE_EDGE); } else { tool.deleteBranch(trueSuccessor()); - return falseSuccessor(); + tool.addToWorkList(falseSuccessor()); + ((StructuredGraph) graph()).removeSplit(this, FALSE_EDGE); + } + } else { + if (trueSuccessor().next() instanceof EndNode && falseSuccessor().next() instanceof EndNode) { + EndNode trueEnd = (EndNode) trueSuccessor().next(); + EndNode falseEnd = (EndNode) falseSuccessor().next(); + MergeNode merge = trueEnd.merge(); + if (merge == falseEnd.merge() && merge.endCount() == 2) { + Iterator phis = merge.phis().iterator(); + if (!phis.hasNext()) { + // empty if construct with no phis: remove it + removeEmptyIf(tool); + } else { + PhiNode singlePhi = phis.next(); + if (!phis.hasNext()) { + // one phi at the merge of an otherwise empty if construct: try to convert into a MaterializeNode + boolean inverted = trueEnd == merge.endAt(FALSE_EDGE); + ValueNode trueValue = singlePhi.valueAt(inverted ? 1 : 0); + ValueNode falseValue = singlePhi.valueAt(inverted ? 0 : 1); + if (trueValue.kind() != falseValue.kind()) { + return; + } + if (trueValue.kind() != CiKind.Int && trueValue.kind() != CiKind.Long) { + return; + } + if (trueValue.isConstant() && falseValue.isConstant()) { + MaterializeNode materialize = MaterializeNode.create(compare(), graph(), (ConstantNode) trueValue, (ConstantNode) falseValue); + ((StructuredGraph) graph()).replaceFloating(singlePhi, materialize); + removeEmptyIf(tool); + } + } + } + } } } - if (trueSuccessor().next() instanceof EndNode && falseSuccessor().next() instanceof EndNode) { - EndNode trueEnd = (EndNode) trueSuccessor().next(); - EndNode falseEnd = (EndNode) falseSuccessor().next(); - MergeNode merge = trueEnd.merge(); - if (merge == falseEnd.merge() && !merge.phis().iterator().hasNext() && merge.endCount() == 2) { - FixedNode next = merge.next(); - merge.safeDelete(); - BeginNode falseSuccessor = this.falseSuccessor(); - BeginNode trueSuccessor = this.trueSuccessor(); - this.setTrueSuccessor(null); - this.setFalseSuccessor(null); - trueSuccessor.safeDelete(); - falseSuccessor.safeDelete(); - trueEnd.safeDelete(); - falseEnd.safeDelete(); - return next; - } - } - return this; + } + + private void removeEmptyIf(SimplifierTool tool) { + BeginNode trueSuccessor = trueSuccessor(); + BeginNode falseSuccessor = falseSuccessor(); + assert trueSuccessor.next() instanceof EndNode && falseSuccessor.next() instanceof EndNode; + + EndNode trueEnd = (EndNode) trueSuccessor.next(); + EndNode falseEnd = (EndNode) falseSuccessor.next(); + assert trueEnd.merge() == falseEnd.merge(); + + MergeNode merge = trueEnd.merge(); + assert merge.usages().isEmpty(); + + FixedNode next = merge.next(); + merge.setNext(null); + setTrueSuccessor(null); + setFalseSuccessor(null); + ((FixedWithNextNode) predecessor()).setNext(next); + safeDelete(); + trueSuccessor.safeDelete(); + falseSuccessor.safeDelete(); + merge.safeDelete(); + trueEnd.safeDelete(); + falseEnd.safeDelete(); + tool.addToWorkList(next); } } diff -r 4a609a685fa4 -r 72d099e5be61 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/InvokeNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/InvokeNode.java Tue Jan 17 19:45:39 2012 +0100 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/InvokeNode.java Wed Jan 18 15:09:19 2012 +0100 @@ -96,14 +96,11 @@ @Override public void intrinsify(Node node) { - this.callTarget.delete(); + MethodCallTargetNode call = callTarget; + FrameState stateAfter = stateAfter(); if (node instanceof StateSplit) { StateSplit stateSplit = (StateSplit) node; - stateSplit.setStateAfter(stateAfter()); - } else { - if (stateAfter().usages().size() == 1) { - stateAfter().delete(); - } + stateSplit.setStateAfter(stateAfter); } if (node == null) { assert kind() == CiKind.Void && usages().isEmpty(); @@ -111,5 +108,9 @@ } else { ((StructuredGraph) graph()).replaceFixed(this, node); } + call.safeDelete(); + if (stateAfter.usages().isEmpty()) { + stateAfter.safeDelete(); + } } } diff -r 4a609a685fa4 -r 72d099e5be61 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/InvokeWithExceptionNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/InvokeWithExceptionNode.java Tue Jan 17 19:45:39 2012 +0100 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/InvokeWithExceptionNode.java Wed Jan 18 15:09:19 2012 +0100 @@ -140,15 +140,12 @@ @Override public void intrinsify(Node node) { - this.callTarget.delete(); + MethodCallTargetNode call = callTarget; + FrameState state = stateAfter(); killExceptionEdge(); if (node instanceof StateSplit) { StateSplit stateSplit = (StateSplit) node; - stateSplit.setStateAfter(stateAfter()); - } else { - if (stateAfter().usages().size() == 1) { - stateAfter().delete(); - } + stateSplit.setStateAfter(state); } if (node == null) { assert kind() == CiKind.Void && usages().isEmpty(); @@ -156,5 +153,9 @@ } else { ((StructuredGraph) graph()).replaceSplit(this, node, NORMAL_EDGE); } + call.safeDelete(); + if (state.usages().isEmpty()) { + state.safeDelete(); + } } } diff -r 4a609a685fa4 -r 72d099e5be61 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/PhiNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/PhiNode.java Tue Jan 17 19:45:39 2012 +0100 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/PhiNode.java Wed Jan 18 15:09:19 2012 +0100 @@ -167,66 +167,7 @@ return singleValue; } - return canonicalizeMaterializationPhi(); - } - - private ValueNode canonicalizeMaterializationPhi() { - if (merge().endCount() != 2 || merge() instanceof LoopBeginNode) { - return this; - } - if (merge().usages().size() > 1) { // TODO(gd) disable canonicalization of multiple conditional while we are not able to fuse them and the potentially leftover If in the backend - return this; - } - - Node end0 = merge().endAt(0); - Node end1 = merge().endAt(1); - Node endPred0 = end0.predecessor(); - Node endPred1 = end1.predecessor(); - if (!(endPred0 instanceof BeginNode) || !(endPred1 instanceof BeginNode)) { - return this; - } - if (endPred0.predecessor() != endPred1.predecessor() || !(endPred0.predecessor() instanceof IfNode)) { - return this; - } - - // Get true/false value. - IfNode ifNode = (IfNode) endPred0.predecessor(); - boolean inverted = ifNode.trueSuccessor() == endPred1; - ValueNode trueValue = valueAt(inverted ? 1 : 0); - ValueNode falseValue = valueAt(inverted ? 0 : 1); - if (trueValue.kind() != falseValue.kind()) { - return this; - } - - // Only allow int constants. - if (trueValue.kind() != CiKind.Int || !trueValue.isConstant() || !falseValue.isConstant()) { - return this; - } - - ConstantNode trueConstantNode = (ConstantNode) trueValue; - ConstantNode falseConstantNode = (ConstantNode) falseValue; - BooleanNode compare = ifNode.compare(); - removeIfNode(ifNode); - return MaterializeNode.create(compare, ifNode.graph(), trueConstantNode, falseConstantNode); - } - - private void removeIfNode(IfNode ifNode) { - FixedNode next = merge().next(); - EndNode end1 = this.merge.endAt(0); - EndNode end2 = this.merge.endAt(1); - BeginNode trueSuccessor = ifNode.trueSuccessor(); - BeginNode falseSuccessor = ifNode.falseSuccessor(); - merge().setNext(null); - ifNode.setTrueSuccessor(null); - ifNode.setFalseSuccessor(null); - ifNode.replaceAndDelete(next); - updateUsages(this.merge, null); - this.merge.safeDelete(); - this.merge = null; - trueSuccessor.safeDelete(); - falseSuccessor.safeDelete(); - end1.safeDelete(); - end2.safeDelete(); + return this; } public ValueNode firstValue() { diff -r 4a609a685fa4 -r 72d099e5be61 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/StructuredGraph.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/StructuredGraph.java Tue Jan 17 19:45:39 2012 +0100 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/StructuredGraph.java Wed Jan 18 15:09:19 2012 +0100 @@ -153,7 +153,7 @@ public void removeFixed(FixedWithNextNode node) { assert node != null; - assert node.usages().isEmpty(); + assert node.usages().isEmpty() : node + " " + node.usages(); FixedNode next = node.next(); node.setNext(null); node.replaceAtPredecessors(next); diff -r 4a609a685fa4 -r 72d099e5be61 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/ValueAnchorNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/ValueAnchorNode.java Tue Jan 17 19:45:39 2012 +0100 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/ValueAnchorNode.java Wed Jan 18 15:09:19 2012 +0100 @@ -54,17 +54,17 @@ @Override public ValueNode canonical(CanonicalizerTool tool) { if (object == null) { - return next(); + return null; } if (object instanceof ConstantNode) { - return next(); + return null; } if (object instanceof IntegerDivNode || object instanceof IntegerRemNode) { if (((ArithmeticNode) object).y().isConstant()) { CiConstant constant = ((ArithmeticNode) object).y().asConstant(); assert constant.kind == object.kind() : constant.kind + " != " + object.kind(); if (constant.asLong() != 0) { - return next(); + return null; } } } diff -r 4a609a685fa4 -r 72d099e5be61 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/NewArrayNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/NewArrayNode.java Tue Jan 17 19:45:39 2012 +0100 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/NewArrayNode.java Wed Jan 18 15:09:19 2012 +0100 @@ -111,7 +111,7 @@ if (usage instanceof ArrayLengthNode) { ArrayLengthNode x = (ArrayLengthNode) usage; StructuredGraph graph = (StructuredGraph) node.graph(); - node.replaceAtUsages(((NewArrayNode) node).dimension(0)); + x.replaceAtUsages(((NewArrayNode) node).dimension(0)); graph.removeFixed(x); } else { super.beforeUpdate(node, usage); diff -r 4a609a685fa4 -r 72d099e5be61 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/RegisterFinalizerNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/RegisterFinalizerNode.java Tue Jan 17 19:45:39 2012 +0100 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/RegisterFinalizerNode.java Wed Jan 18 15:09:19 2012 +0100 @@ -71,7 +71,7 @@ } if (!needsCheck) { - return next(); + return null; } return this; diff -r 4a609a685fa4 -r 72d099e5be61 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/CanonicalizerTool.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/CanonicalizerTool.java Tue Jan 17 19:45:39 2012 +0100 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/CanonicalizerTool.java Wed Jan 18 15:09:19 2012 +0100 @@ -24,11 +24,9 @@ import com.oracle.max.cri.ci.*; import com.oracle.max.cri.ri.*; -import com.oracle.max.graal.nodes.*; public interface CanonicalizerTool { - void deleteBranch(FixedNode branch); CiTarget target(); CiAssumptions assumptions(); RiRuntime runtime(); diff -r 4a609a685fa4 -r 72d099e5be61 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/Simplifiable.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/Simplifiable.java Wed Jan 18 15:09:19 2012 +0100 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.max.graal.nodes.spi; + +/** + * This interface allows nodes to perform more complicated simplifications, in contrast to {@link Canonicalizable}, + * which supports only replacing the current node. + * + * Implementors of this interface need to be aware that they need to call {@link SimplifierTool#addToWorkList(com.oracle.max.graal.graph.Node)} for each node that might + * be influenced (in terms of simplification and canonicalization) by the actions performed in simplify. + */ +public interface Simplifiable { + + void simplify(SimplifierTool tool); +} diff -r 4a609a685fa4 -r 72d099e5be61 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/SimplifierTool.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/SimplifierTool.java Wed Jan 18 15:09:19 2012 +0100 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.max.graal.nodes.spi; + +import com.oracle.max.graal.graph.*; +import com.oracle.max.graal.nodes.*; + + +public interface SimplifierTool extends CanonicalizerTool { + void deleteBranch(FixedNode branch); + void addToWorkList(Node node); +}