# HG changeset patch # User Christian Wimmer # Date 1428556070 25200 # Node ID a4aa2116cfe028d964a48fe6f677ef47139eec5f # Parent 854b0b6854f41d1f1d7bf51019aab8a715acecb3 Support node canonicalization when not all usages of a node are known yet diff -r 854b0b6854f4 -r a4aa2116cfe0 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/CanonicalizerTool.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/CanonicalizerTool.java Wed Apr 08 22:05:40 2015 -0700 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/CanonicalizerTool.java Wed Apr 08 22:07:50 2015 -0700 @@ -23,6 +23,7 @@ package com.oracle.graal.graph.spi; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; public interface CanonicalizerTool { @@ -31,4 +32,11 @@ ConstantReflectionProvider getConstantReflection(); boolean canonicalizeReads(); + + /** + * If this method returns false, not all {@link Node#usages() usages of a node} are yet + * available. So a node must not be canonicalized base on, e.g., information returned from + * {@link Node#hasNoUsages()}. + */ + boolean allUsagesAvailable(); } diff -r 854b0b6854f4 -r a4aa2116cfe0 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SnippetAnchorNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SnippetAnchorNode.java Wed Apr 08 22:05:40 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SnippetAnchorNode.java Wed Apr 08 22:07:50 2015 -0700 @@ -42,7 +42,7 @@ AbstractBeginNode prevBegin = AbstractBeginNode.prevBegin(this); replaceAtUsages(InputType.Anchor, prevBegin); replaceAtUsages(InputType.Guard, prevBegin); - if (hasNoUsages()) { + if (tool.allUsagesAvailable() && hasNoUsages()) { graph().removeFixed(this); } } diff -r 854b0b6854f4 -r a4aa2116cfe0 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassGetHubNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassGetHubNode.java Wed Apr 08 22:05:40 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassGetHubNode.java Wed Apr 08 22:07:50 2015 -0700 @@ -57,7 +57,7 @@ @Override public Node canonical(CanonicalizerTool tool) { - if (hasNoUsages()) { + if (tool.allUsagesAvailable() && hasNoUsages()) { return null; } else { if (clazz.isConstant()) { diff -r 854b0b6854f4 -r a4aa2116cfe0 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HubGetClassNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HubGetClassNode.java Wed Apr 08 22:05:40 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HubGetClassNode.java Wed Apr 08 22:07:50 2015 -0700 @@ -53,7 +53,7 @@ @Override public Node canonical(CanonicalizerTool tool) { - if (hasNoUsages()) { + if (tool.allUsagesAvailable() && hasNoUsages()) { return null; } else { MetaAccessProvider metaAccess = tool.getMetaAccess(); diff -r 854b0b6854f4 -r a4aa2116cfe0 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/KlassLayoutHelperNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/KlassLayoutHelperNode.java Wed Apr 08 22:05:40 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/KlassLayoutHelperNode.java Wed Apr 08 22:07:50 2015 -0700 @@ -80,7 +80,7 @@ @Override public Node canonical(CanonicalizerTool tool) { - if (hasNoUsages()) { + if (tool.allUsagesAvailable() && hasNoUsages()) { return null; } else { if (klass.isConstant()) { diff -r 854b0b6854f4 -r a4aa2116cfe0 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractMergeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractMergeNode.java Wed Apr 08 22:05:40 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractMergeNode.java Wed Apr 08 22:07:50 2015 -0700 @@ -227,7 +227,7 @@ end.safeDelete(); } for (PhiNode phi : phis) { - if (phi.isAlive() && phi.hasNoUsages()) { + if (tool.allUsagesAvailable() && phi.isAlive() && phi.hasNoUsages()) { GraphUtil.killWithUnusedFloatingInputs(phi); } } diff -r 854b0b6854f4 -r a4aa2116cfe0 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConditionAnchorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConditionAnchorNode.java Wed Apr 08 22:05:40 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConditionAnchorNode.java Wed Apr 08 22:07:50 2015 -0700 @@ -76,7 +76,7 @@ return new ValueAnchorNode(null); } } - if (this.hasNoUsages()) { + if (tool.allUsagesAvailable() && this.hasNoUsages()) { return null; } return this; diff -r 854b0b6854f4 -r a4aa2116cfe0 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 Wed Apr 08 22:05:40 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Wed Apr 08 22:07:50 2015 -0700 @@ -178,7 +178,7 @@ } return; } - if (trueSuccessor().hasNoUsages() && falseSuccessor().hasNoUsages()) { + if (tool.allUsagesAvailable() && trueSuccessor().hasNoUsages() && falseSuccessor().hasNoUsages()) { pushNodesThroughIf(tool); diff -r 854b0b6854f4 -r a4aa2116cfe0 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopExitNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopExitNode.java Wed Apr 08 22:05:40 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopExitNode.java Wed Apr 08 22:07:50 2015 -0700 @@ -45,7 +45,7 @@ @Override public void simplify(SimplifierTool tool) { Node prev = this.predecessor(); - while (prev instanceof BeginNode && prev.hasNoUsages()) { + while (tool.allUsagesAvailable() && prev instanceof BeginNode && prev.hasNoUsages()) { AbstractBeginNode begin = (AbstractBeginNode) prev; prev = prev.predecessor(); graph().removeFixed(begin); diff -r 854b0b6854f4 -r a4aa2116cfe0 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java Wed Apr 08 22:05:40 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java Wed Apr 08 22:07:50 2015 -0700 @@ -98,6 +98,15 @@ gen.emitSwitch(this); } + public AbstractBeginNode successorAtKey(int key) { + for (int i = 0; i < keyCount(); i++) { + if (keys[i] == key) { + return blockSuccessor(keySuccessorIndex(i)); + } + } + return blockSuccessor(keySuccessorIndex(keyCount())); + } + @Override public void simplify(SimplifierTool tool) { if (blockSuccessorCount() == 1) { @@ -105,20 +114,15 @@ graph().removeSplitPropagate(this, defaultSuccessor()); } else if (value() instanceof ConstantNode) { int constant = value().asJavaConstant().asInt(); - - int survivingEdge = keySuccessorIndex(keyCount()); - for (int i = 0; i < keyCount(); i++) { - if (keys[i] == constant) { - survivingEdge = keySuccessorIndex(i); + AbstractBeginNode survivingSuccessor = successorAtKey(constant); + for (Node successor : successors()) { + if (successor != survivingSuccessor) { + tool.deleteBranch(successor); } } - for (int i = 0; i < blockSuccessorCount(); i++) { - if (i != survivingEdge) { - tool.deleteBranch(blockSuccessor(i)); - } - } - tool.addToWorkList(blockSuccessor(survivingEdge)); - graph().removeSplit(this, blockSuccessor(survivingEdge)); + tool.addToWorkList(survivingSuccessor); + graph().removeSplit(this, survivingSuccessor); + } else if (value().stamp() instanceof IntegerStamp) { IntegerStamp integerStamp = (IntegerStamp) value().stamp(); if (!integerStamp.isUnrestricted()) { diff -r 854b0b6854f4 -r a4aa2116cfe0 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryAnchorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryAnchorNode.java Wed Apr 08 22:05:40 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryAnchorNode.java Wed Apr 08 22:07:50 2015 -0700 @@ -45,7 +45,7 @@ @Override public Node canonical(CanonicalizerTool tool) { - return hasNoUsages() ? null : this; + return tool.allUsagesAvailable() && hasNoUsages() ? null : this; } @NodeIntrinsic diff -r 854b0b6854f4 -r a4aa2116cfe0 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Wed Apr 08 22:05:40 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Wed Apr 08 22:07:50 2015 -0700 @@ -71,7 +71,7 @@ @Override public Node canonical(CanonicalizerTool tool) { - if (hasNoUsages()) { + if (tool.allUsagesAvailable() && hasNoUsages()) { if (getGuard() != null && !(getGuard() instanceof FixedNode)) { // The guard is necessary even if the read goes away. return new ValueAnchorNode((ValueNode) getGuard()); diff -r 854b0b6854f4 -r a4aa2116cfe0 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java Wed Apr 08 22:05:40 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java Wed Apr 08 22:07:50 2015 -0700 @@ -79,7 +79,7 @@ @Override public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { - if (hasNoUsages() && StampTool.isPointerNonNull(forValue)) { + if (tool.allUsagesAvailable() && hasNoUsages() && StampTool.isPointerNonNull(forValue)) { return null; } ValueNode synonym = findSynonym(tool.getMetaAccess(), tool.getConstantReflection(), forValue, boxingKind); diff -r 854b0b6854f4 -r a4aa2116cfe0 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java Wed Apr 08 22:05:40 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java Wed Apr 08 22:07:50 2015 -0700 @@ -67,7 +67,7 @@ break; } } - if (hasNoUsages() && next() instanceof FixedAccessNode) { + if (tool.allUsagesAvailable() && hasNoUsages() && next() instanceof FixedAccessNode) { FixedAccessNode currentNext = (FixedAccessNode) next(); if (currentNext.getGuard() == anchored) { GraphUtil.removeFixedWithUnusedInputs(this); diff -r 854b0b6854f4 -r a4aa2116cfe0 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java Wed Apr 08 22:05:40 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java Wed Apr 08 22:07:50 2015 -0700 @@ -80,7 +80,7 @@ if (result != null) { return result; } - Assumptions assumptions = graph().getAssumptions(); + Assumptions assumptions = graph() == null ? null : graph().getAssumptions(); if (assumptions != null) { AssumptionResult leafConcreteSubtype = stampType.findLeafConcreteSubtype(); if (leafConcreteSubtype != null) { diff -r 854b0b6854f4 -r a4aa2116cfe0 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java Wed Apr 08 22:05:40 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java Wed Apr 08 22:07:50 2015 -0700 @@ -60,7 +60,7 @@ } public ValueNode canonical(CanonicalizerTool tool, ValueNode forObject) { - if (hasNoUsages() && !isVolatile() && (isStatic() || StampTool.isPointerNonNull(forObject.stamp()))) { + if (tool.allUsagesAvailable() && hasNoUsages() && !isVolatile() && (isStatic() || StampTool.isPointerNonNull(forObject.stamp()))) { return null; } MetaAccessProvider metaAccess = tool.getMetaAccess(); diff -r 854b0b6854f4 -r a4aa2116cfe0 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Wed Apr 08 22:05:40 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Wed Apr 08 22:07:50 2015 -0700 @@ -521,6 +521,11 @@ return canonicalizeReads; } + @Override + public boolean allUsagesAvailable() { + return true; + } + public void deleteBranch(Node branch) { branch.predecessor().replaceFirstSuccessor(branch, null); GraphUtil.killCFG(branch, this); diff -r 854b0b6854f4 -r a4aa2116cfe0 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Wed Apr 08 22:05:40 2015 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Wed Apr 08 22:07:50 2015 -0700 @@ -416,6 +416,11 @@ public boolean canonicalizeReads() { return canonicalizeReads; } + + @Override + public boolean allUsagesAvailable() { + return true; + } } } diff -r 854b0b6854f4 -r a4aa2116cfe0 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java Wed Apr 08 22:05:40 2015 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java Wed Apr 08 22:07:50 2015 -0700 @@ -63,7 +63,7 @@ @Override public Node canonical(CanonicalizerTool tool) { - if (hasNoUsages()) { + if (tool.allUsagesAvailable() && hasNoUsages()) { return null; } if (GraphUtil.unproxify(array1) == GraphUtil.unproxify(array2)) { diff -r 854b0b6854f4 -r a4aa2116cfe0 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/PureFunctionMacroNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/PureFunctionMacroNode.java Wed Apr 08 22:05:40 2015 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/PureFunctionMacroNode.java Wed Apr 08 22:07:50 2015 -0700 @@ -50,7 +50,7 @@ @Override public Node canonical(CanonicalizerTool tool) { - if (hasNoUsages()) { + if (tool.allUsagesAvailable() && hasNoUsages()) { return null; } else { ValueNode param = arguments.get(0); diff -r 854b0b6854f4 -r a4aa2116cfe0 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java Wed Apr 08 22:05:40 2015 -0700 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java Wed Apr 08 22:07:50 2015 -0700 @@ -236,7 +236,7 @@ @Override public Node canonical(CanonicalizerTool tool) { - if (hasNoUsages()) { + if (tool.allUsagesAvailable() && hasNoUsages()) { return null; } else { return this; diff -r 854b0b6854f4 -r a4aa2116cfe0 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java Wed Apr 08 22:05:40 2015 -0700 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java Wed Apr 08 22:07:50 2015 -0700 @@ -200,4 +200,9 @@ public boolean canonicalizeReads() { return false; } + + @Override + public boolean allUsagesAvailable() { + return true; + } }