changeset 6408:e5768e936147

Allow snippets to inherit the stateAfter and stamp from the replacee
author Christian Wimmer <christian.wimmer@oracle.com>
date Fri, 14 Sep 2012 14:21:33 -0700
parents 46d426e79bed
children 823a2978e7ba
files graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java
diffstat 2 files changed, 48 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java	Fri Sep 14 14:14:01 2012 -0700
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java	Fri Sep 14 14:21:33 2012 -0700
@@ -33,6 +33,7 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.snippets.Snippet.Fold;
 
@@ -334,7 +335,7 @@
     }
 
     public void cleanUpReturnCheckCast(Node newInstance) {
-        if (newInstance instanceof ValueNode && ((ValueNode) newInstance).kind() != Kind.Object) {
+        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 (ValueProxyNode vpn : checkCastNode.usages().filter(ValueProxyNode.class).snapshot()) {
@@ -363,6 +364,8 @@
                         checkCastCallTarget.safeDelete();
                     } 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 {
                         assert false : sourceLocation(checkCastUsage) + " has unexpected usage " + checkCastUsage + " of checkcast at " + sourceLocation(checkCastNode);
                     }
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java	Fri Sep 14 14:14:01 2012 -0700
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java	Fri Sep 14 14:21:33 2012 -0700
@@ -33,7 +33,6 @@
 import com.oracle.graal.compiler.phases.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.Node.Verbosity;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
@@ -327,11 +326,20 @@
 
         // Remove all frame states from inlined snippet graph. Snippets must be atomic (i.e. free
         // of side-effects that prevent deoptimizing to a point before the snippet).
+        Node curSideEffectNode = null;
+        Node curStampNode = null;
         for (Node node : snippetCopy.getNodes()) {
+            if (node instanceof ValueNode && ((ValueNode) node).stamp() == StampFactory.forNodeIntrinsic()) {
+                assert curStampNode == null : "Currently limited to stamp node (but this can be converted to a List if necessary)";
+                curStampNode = node;
+            }
             if (node instanceof StateSplit) {
                 StateSplit stateSplit = (StateSplit) node;
                 FrameState frameState = stateSplit.stateAfter();
-                assert !stateSplit.hasSideEffect() : "snippets cannot contain side-effecting node " + node + "\n    " + frameState.toString(Verbosity.Debugger);
+                if (stateSplit.hasSideEffect()) {
+                    assert curSideEffectNode == null : "Currently limited to one side-effecting node (but this can be converted to a List if necessary)";
+                    curSideEffectNode = node;
+                }
                 if (frameState != null) {
                     stateSplit.setStateAfter(null);
                 }
@@ -386,6 +394,8 @@
             }
         }
 
+        this.sideEffectNode = curSideEffectNode;
+        this.stampNode = curStampNode;
         this.returnNode = retNode;
     }
 
@@ -436,6 +446,16 @@
     private final ReturnNode returnNode;
 
     /**
+     * Node that inherits the {@link StateSplit#stateAfter()} from the replacee during instantiation.
+     */
+    private final Node sideEffectNode;
+
+    /**
+     * Node that inherits the {@link ValueNode#stamp()} from the replacee during instantiation.
+     */
+    private final Node stampNode;
+
+    /**
      * The nodes to be inlined when this specialization is instantiated.
      */
     private final ArrayList<Node> nodes;
@@ -514,6 +534,16 @@
         FixedNode next = replacee.next();
         replacee.setNext(null);
 
+        if (sideEffectNode != null) {
+            assert ((StateSplit) replacee).hasSideEffect();
+            Node sideEffectDup = duplicates.get(sideEffectNode);
+            ((StateSplit) sideEffectDup).setStateAfter(((StateSplit) replacee).stateAfter());
+        }
+        if (stampNode != null) {
+            Node stampDup = duplicates.get(stampNode);
+            ((ValueNode) stampDup).setStamp(((ValueNode) replacee).stamp());
+        }
+
         // Replace all usages of the replacee with the value returned by the snippet
         Node returnValue = null;
         if (returnNode != null) {
@@ -567,6 +597,16 @@
         FixedNode firstCFGNodeDuplicate = (FixedNode) duplicates.get(firstCFGNode);
         replaceeGraph.addAfterFixed(lastFixedNode, firstCFGNodeDuplicate);
 
+        if (sideEffectNode != null) {
+            assert ((StateSplit) replacee).hasSideEffect();
+            Node sideEffectDup = duplicates.get(sideEffectNode);
+            ((StateSplit) sideEffectDup).setStateAfter(((StateSplit) replacee).stateAfter());
+        }
+        if (stampNode != null) {
+            Node stampDup = duplicates.get(stampNode);
+            ((ValueNode) stampDup).setStamp(((ValueNode) replacee).stamp());
+        }
+
         // Replace all usages of the replacee with the value returned by the snippet
         assert returnNode != null : replaceeGraph;
         Node returnValue = null;
@@ -618,6 +658,8 @@
         controlSplitNode.replaceAtPredecessor(firstCFGNodeDuplicate);
         controlSplitNode.replaceAtUsages(null);
 
+        assert sideEffectNode == null;
+        assert stampNode == null;
         assert returnNode == null : replaceeGraph;
         GraphUtil.killCFG(controlSplitNode);