changeset 9861:2d5c0f7ce7a1

Add a PiNode for the null-checked receiver during inlining
author Gilles Duboscq <duboscq@ssw.jku.at>
date Tue, 04 Jun 2013 17:30:19 +0200
parents 6a0da51dfba4
children 49fb2675c665
files graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java
diffstat 2 files changed, 23 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Tue Jun 04 17:23:39 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Tue Jun 04 17:30:19 2013 +0200
@@ -1269,6 +1269,10 @@
 
         FrameState stateAfter = invoke.stateAfter();
         assert stateAfter == null || stateAfter.isAlive();
+        GuardingNode receiverNullCheckNode = null;
+        if (receiverNullCheck) {
+            receiverNullCheckNode = receiverNullCheck(invoke);
+        }
 
         IdentityHashMap<Node, Node> replacements = new IdentityHashMap<>();
         ArrayList<Node> nodes = new ArrayList<>();
@@ -1280,7 +1284,18 @@
             if (node == entryPointNode || node == entryPointNode.stateAfter()) {
                 // Do nothing.
             } else if (node instanceof LocalNode) {
-                replacements.put(node, parameters.get(((LocalNode) node).index()));
+                int localIndex = ((LocalNode) node).index();
+                ValueNode parameter = parameters.get(localIndex);
+                if (receiverNullCheckNode != null && localIndex == 0) {
+                    Stamp piStamp = parameter.stamp();
+                    if (piStamp instanceof ObjectStamp) {
+                        piStamp = piStamp.join(StampFactory.objectNonNull());
+                    }
+                    PiNode piReceiver = graph.add(new PiNode(parameter, piStamp));
+                    piReceiver.setGuard(receiverNullCheckNode);
+                    parameter = piReceiver;
+                }
+                replacements.put(node, parameter);
             } else {
                 nodes.add(node);
                 if (node instanceof ReturnNode) {
@@ -1300,9 +1315,6 @@
 
         Map<Node, Node> duplicates = graph.addDuplicates(nodes, replacements);
         FixedNode firstCFGNodeDuplicate = (FixedNode) duplicates.get(firstCFGNode);
-        if (receiverNullCheck) {
-            receiverNullCheck(invoke);
-        }
         invoke.asNode().replaceAtPredecessor(firstCFGNodeDuplicate);
 
         FrameState stateAtExceptionEdge = null;
@@ -1408,15 +1420,17 @@
         return true;
     }
 
-    public static void receiverNullCheck(Invoke invoke) {
+    public static GuardingNode receiverNullCheck(Invoke invoke) {
         MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget();
         StructuredGraph graph = callTarget.graph();
         NodeInputList<ValueNode> parameters = callTarget.arguments();
         ValueNode firstParam = parameters.size() <= 0 ? null : parameters.get(0);
         if (!callTarget.isStatic() && firstParam.kind() == Kind.Object && !firstParam.objectStamp().nonNull()) {
-            graph.addBeforeFixed(invoke.asNode(),
-                            graph.add(new FixedGuardNode(graph.unique(new IsNullNode(firstParam)), DeoptimizationReason.NullCheckException, DeoptimizationAction.InvalidateReprofile, true)));
+            FixedGuardNode guard = graph.add(new FixedGuardNode(graph.unique(new IsNullNode(firstParam)), DeoptimizationReason.NullCheckException, DeoptimizationAction.InvalidateReprofile, true));
+            graph.addBeforeFixed(invoke.asNode(), guard);
+            return guard;
         }
+        return null;
     }
 
     public static boolean canIntrinsify(Replacements replacements, ResolvedJavaMethod target) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java	Tue Jun 04 17:23:39 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java	Tue Jun 04 17:30:19 2013 +0200
@@ -326,11 +326,11 @@
             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()) {
+            for (Node proxyUsage : usage.usages().snapshot()) {
                 checkCheckCastUsage(graph, newProxy, proxy, proxyUsage);
             }
         } else if (usage instanceof PiNode) {
-            for (Node piUsage : usage.usages()) {
+            for (Node piUsage : usage.usages().snapshot()) {
                 checkCheckCastUsage(graph, intrinsifiedNode, usage, piUsage);
             }
         } else {