# HG changeset patch # User Gilles Duboscq # Date 1370359419 -7200 # Node ID 6a0da51dfba4c9e445511806dbf4f948a78fa3ee # Parent 30cab249529e58ae455148bec45778fb2b6c1e95 Handle Proxies and pi nodes better in the NodeIntrinsificationPhase diff -r 30cab249529e -r 6a0da51dfba4 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 Tue Jun 04 16:53:23 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java Tue Jun 04 17:23:39 2013 +0200 @@ -61,6 +61,10 @@ } } + public void removeAnchoredNode(ValueNode value) { + this.anchored.remove(value); + } + @Override public ValueNode canonical(CanonicalizerTool tool) { if (permanent) { diff -r 30cab249529e -r 6a0da51dfba4 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Tue Jun 04 16:53:23 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Tue Jun 04 17:23:39 2013 +0200 @@ -33,6 +33,7 @@ import com.oracle.graal.graph.Node.ConstantNodeParameter; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; @@ -284,34 +285,8 @@ if (newInstance instanceof ValueNode && (((ValueNode) newInstance).kind() != Kind.Object || ((ValueNode) newInstance).stamp() == StampFactory.forNodeIntrinsic())) { StructuredGraph graph = (StructuredGraph) newInstance.graph(); for (CheckCastNode checkCastNode : newInstance.usages().filter(CheckCastNode.class).snapshot()) { - for (ProxyNode vpn : checkCastNode.usages().filter(ProxyNode.class).snapshot()) { - graph.replaceFloating(vpn, checkCastNode); - } for (Node checkCastUsage : checkCastNode.usages().snapshot()) { - if (checkCastUsage instanceof ValueAnchorNode) { - ValueAnchorNode valueAnchorNode = (ValueAnchorNode) checkCastUsage; - graph.removeFixed(valueAnchorNode); - } else if (checkCastUsage instanceof UnboxNode) { - UnboxNode unbox = (UnboxNode) checkCastUsage; - unbox.replaceAtUsages(newInstance); - graph.removeFixed(unbox); - } else if (checkCastUsage instanceof MethodCallTargetNode) { - MethodCallTargetNode checkCastCallTarget = (MethodCallTargetNode) checkCastUsage; - assert checkCastCallTarget.targetMethod().getAnnotation(NodeIntrinsic.class) != null : "checkcast at " + sourceLocation(checkCastNode) + - " not used by an unboxing method or node intrinsic, but by a call at " + sourceLocation(checkCastCallTarget.usages().first()) + " to " + - checkCastCallTarget.targetMethod(); - checkCastUsage.replaceFirstInput(checkCastNode, checkCastNode.object()); - } else if (checkCastUsage instanceof FrameState) { - checkCastUsage.replaceFirstInput(checkCastNode, null); - } else if (checkCastUsage instanceof ReturnNode && checkCastNode.object().stamp() == StampFactory.forNodeIntrinsic()) { - checkCastUsage.replaceFirstInput(checkCastNode, checkCastNode.object()); - } else if (checkCastUsage instanceof IsNullNode) { - assert checkCastUsage.usages().count() == 1 && checkCastUsage.usages().first().predecessor() == checkCastNode; - graph.replaceFloating((FloatingNode) checkCastUsage, LogicConstantNode.contradiction(graph)); - } else { - Debug.dump(graph, "exception"); - assert false : sourceLocation(checkCastUsage) + " has unexpected usage " + checkCastUsage + " of checkcast at " + sourceLocation(checkCastNode); - } + checkCheckCastUsage(graph, newInstance, checkCastNode, checkCastUsage); } FixedNode next = checkCastNode.next(); checkCastNode.setNext(null); @@ -320,4 +295,47 @@ } } } + + private static void checkCheckCastUsage(StructuredGraph graph, Node intrinsifiedNode, Node input, Node usage) { + if (usage instanceof ValueAnchorNode) { + ValueAnchorNode valueAnchorNode = (ValueAnchorNode) usage; + valueAnchorNode.removeAnchoredNode((ValueNode) input); + Debug.log("%s: Removed a ValueAnchor input", Debug.contextSnapshot(JavaMethod.class)); + } else if (usage instanceof UnboxNode) { + UnboxNode unbox = (UnboxNode) usage; + unbox.replaceAtUsages(intrinsifiedNode); + graph.removeFixed(unbox); + Debug.log("%s: Removed an UnboxNode", Debug.contextSnapshot(JavaMethod.class)); + } else if (usage instanceof MethodCallTargetNode) { + MethodCallTargetNode checkCastCallTarget = (MethodCallTargetNode) usage; + assert checkCastCallTarget.targetMethod().getAnnotation(NodeIntrinsic.class) != null : "checkcast at " + sourceLocation(input) + + " not used by an unboxing method or node intrinsic, but by a call at " + sourceLocation(checkCastCallTarget.usages().first()) + " to " + checkCastCallTarget.targetMethod(); + usage.replaceFirstInput(input, intrinsifiedNode); + Debug.log("%s: Checkcast used in an other node intrinsic", Debug.contextSnapshot(JavaMethod.class)); + } else if (usage instanceof FrameState) { + usage.replaceFirstInput(input, null); + Debug.log("%s: Checkcast used in a FS", Debug.contextSnapshot(JavaMethod.class)); + } else if (usage instanceof ReturnNode && ((ValueNode) intrinsifiedNode).stamp() == StampFactory.forNodeIntrinsic()) { + usage.replaceFirstInput(input, intrinsifiedNode); + Debug.log("%s: Checkcast used in a return with forNodeIntrinsic stamp", Debug.contextSnapshot(JavaMethod.class)); + } else if (usage instanceof IsNullNode) { + assert usage.usages().count() == 1 && usage.usages().first().predecessor() == input; + graph.replaceFloating((FloatingNode) usage, LogicConstantNode.contradiction(graph)); + Debug.log("%s: Replaced IsNull with false", Debug.contextSnapshot(JavaMethod.class)); + } else if (usage instanceof ProxyNode) { + ProxyNode proxy = (ProxyNode) usage; + assert proxy.type() == PhiType.Value; + ProxyNode newProxy = graph.unique(new ProxyNode((ValueNode) intrinsifiedNode, proxy.proxyPoint(), PhiType.Value, proxy.getIdentity())); + for (Node proxyUsage : usage.usages()) { + checkCheckCastUsage(graph, newProxy, proxy, proxyUsage); + } + } else if (usage instanceof PiNode) { + for (Node piUsage : usage.usages()) { + checkCheckCastUsage(graph, intrinsifiedNode, usage, piUsage); + } + } else { + Debug.dump(graph, "exception"); + assert false : sourceLocation(usage) + " has unexpected usage " + usage + " of checkcast at " + sourceLocation(input); + } + } }