changeset 6568:d8408e5563e5

added indirection for the replacement of a snippet-lowered node with the snippet's return value
author Doug Simon <doug.simon@oracle.com>
date Mon, 22 Oct 2012 18:10:04 +0200
parents 3bc7183309e0
children dcad13b2f6e8
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CheckCastSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/InstanceOfSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/MonitorSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java
diffstat 5 files changed, 53 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CheckCastSnippets.java	Mon Oct 22 10:23:50 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CheckCastSnippets.java	Mon Oct 22 18:10:04 2012 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.hotspot.snippets;
 import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
 import static com.oracle.graal.snippets.Snippet.Varargs.*;
+import static com.oracle.graal.snippets.SnippetTemplate.*;
 import static com.oracle.graal.snippets.SnippetTemplate.Arguments.*;
 
 import com.oracle.graal.api.code.*;
@@ -279,7 +280,7 @@
 
             SnippetTemplate template = cache.get(key);
             Debug.log("Lowering checkcast in %s: node=%s, template=%s, arguments=%s", graph, checkcast, template, arguments);
-            template.instantiate(runtime, checkcast, arguments);
+            template.instantiate(runtime, checkcast, DEFAULT_REPLACER, arguments);
         }
 
         static HotSpotKlassOop[] createHints(TypeCheckHints hints) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/InstanceOfSnippets.java	Mon Oct 22 10:23:50 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/InstanceOfSnippets.java	Mon Oct 22 18:10:04 2012 +0200
@@ -25,6 +25,7 @@
 import static com.oracle.graal.hotspot.snippets.CheckCastSnippets.Templates.*;
 import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
 import static com.oracle.graal.snippets.Snippet.Varargs.*;
+import static com.oracle.graal.snippets.SnippetTemplate.*;
 import static com.oracle.graal.snippets.SnippetTemplate.Arguments.*;
 import static com.oracle.graal.snippets.nodes.JumpNode.*;
 
@@ -360,7 +361,7 @@
                     }
 
                     SnippetTemplate template = cache.get(key);
-                    template.instantiate(runtime, duplicate, tool.lastFixedNode(), arguments);
+                    template.instantiate(runtime, duplicate, DEFAULT_REPLACER, tool.lastFixedNode(), arguments);
                 } else {
                     throw new GraalInternalError("Unexpected usage of %s: %s", instanceOf, usage);
                 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/MonitorSnippets.java	Mon Oct 22 10:23:50 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/MonitorSnippets.java	Mon Oct 22 18:10:04 2012 +0200
@@ -27,6 +27,7 @@
 import static com.oracle.graal.hotspot.nodes.EndLockScopeNode.*;
 import static com.oracle.graal.hotspot.nodes.VMErrorNode.*;
 import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
+import static com.oracle.graal.snippets.SnippetTemplate.*;
 import static com.oracle.graal.snippets.nodes.DirectObjectStoreNode.*;
 
 import java.util.*;
@@ -431,7 +432,7 @@
                 arguments.add("object", monitorenterNode.object());
             }
             SnippetTemplate template = cache.get(key);
-            Map<Node, Node> nodes = template.instantiate(runtime, monitorenterNode, arguments);
+            Map<Node, Node> nodes = template.instantiate(runtime, monitorenterNode, DEFAULT_REPLACER, arguments);
             for (Node n : nodes.values()) {
                 if (n instanceof BeginLockScopeNode) {
                     BeginLockScopeNode begin = (BeginLockScopeNode) n;
@@ -456,7 +457,7 @@
                 arguments.add("object", monitorexitNode.object());
             }
             SnippetTemplate template = cache.get(key);
-            Map<Node, Node> nodes = template.instantiate(runtime, monitorexitNode, arguments);
+            Map<Node, Node> nodes = template.instantiate(runtime, monitorexitNode, DEFAULT_REPLACER, arguments);
             for (Node n : nodes.values()) {
                 if (n instanceof EndLockScopeNode) {
                     EndLockScopeNode end = (EndLockScopeNode) n;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java	Mon Oct 22 10:23:50 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java	Mon Oct 22 18:10:04 2012 +0200
@@ -25,6 +25,7 @@
 import static com.oracle.graal.api.code.UnsignedMath.*;
 import static com.oracle.graal.hotspot.nodes.CastFromHub.*;
 import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
+import static com.oracle.graal.snippets.SnippetTemplate.*;
 import static com.oracle.graal.snippets.SnippetTemplate.Arguments.*;
 import static com.oracle.graal.snippets.nodes.DirectObjectStoreNode.*;
 import static com.oracle.graal.snippets.nodes.ExplodeLoopNode.*;
@@ -319,7 +320,7 @@
                 Arguments arguments = new Arguments().add("length", lengthNode);
                 SnippetTemplate template = cache.get(key);
                 Debug.log("Lowering allocateArrayAndInitialize in %s: node=%s, template=%s, arguments=%s", graph, newArrayNode, template, arguments);
-                template.instantiate(runtime, newArrayNode, arguments);
+                template.instantiate(runtime, newArrayNode, DEFAULT_REPLACER, arguments);
             }
         }
 
@@ -331,7 +332,7 @@
             Arguments arguments = arguments("size", size);
             SnippetTemplate template = cache.get(key);
             Debug.log("Lowering fastAllocate in %s: node=%s, template=%s, arguments=%s", graph, tlabAllocateNode, template, arguments);
-            template.instantiate(runtime, tlabAllocateNode, arguments);
+            template.instantiate(runtime, tlabAllocateNode, DEFAULT_REPLACER, arguments);
         }
 
         @SuppressWarnings("unused")
@@ -348,7 +349,7 @@
             Arguments arguments = arguments("memory", memory).add("hub", hub).add("prototypeMarkWord", type.prototypeMarkWord());
             SnippetTemplate template = cache.get(key);
             Debug.log("Lowering initializeObject in %s: node=%s, template=%s, arguments=%s", graph, initializeNode, template, arguments);
-            template.instantiate(runtime, initializeNode, arguments);
+            template.instantiate(runtime, initializeNode, DEFAULT_REPLACER, arguments);
         }
 
         @SuppressWarnings("unused")
@@ -365,7 +366,7 @@
             Arguments arguments = arguments("memory", memory).add("hub", hub).add("prototypeMarkWord", type.prototypeMarkWord()).add("size", initializeNode.size()).add("length", initializeNode.length());
             SnippetTemplate template = cache.get(key);
             Debug.log("Lowering initializeObjectArray in %s: node=%s, template=%s, arguments=%s", graph, initializeNode, template, arguments);
-            template.instantiate(runtime, initializeNode, arguments);
+            template.instantiate(runtime, initializeNode, DEFAULT_REPLACER, arguments);
         }
 
         @SuppressWarnings("unused")
@@ -381,7 +382,7 @@
             Key key = new Key(newmultiarray).add("dimensions", Varargs.vargargs(int.class, rank)).add("rank", rank);
             Arguments arguments = arguments("dimensions", dims).add("hub", hub);
             SnippetTemplate template = cache.get(key);
-            template.instantiate(runtime, newmultiarrayNode, arguments);
+            template.instantiate(runtime, newmultiarrayNode, DEFAULT_REPLACER, arguments);
         }
     }
 
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java	Mon Oct 22 10:23:50 2012 +0200
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java	Mon Oct 22 18:10:04 2012 +0200
@@ -54,7 +54,7 @@
 
     /**
      * A snippet template key encapsulates the method from which a snippet was built
-     * and the arguments used to specialized the snippet.
+     * and the arguments used to specialize the snippet.
      *
      * @see Cache
      */
@@ -512,15 +512,43 @@
     }
 
     /**
+     * Logic for replacing a snippet-lowered node at its usages with the return value
+     * of the snippet. An alternative to the
+     * {@linkplain SnippetTemplate#DEFAULT_REPLACER default} replacement logic can be used to
+     * handle mismatches between the stamp of the node being lowered and the
+     * stamp of the snippet's return value.
+     */
+    public interface UsageReplacer {
+        /**
+         * Replaces all usages of {@code oldNode} with direct or indirect usages of {@code newNode}.
+         */
+        void replace(ValueNode oldNode, ValueNode newNode);
+    }
+
+    /**
+     * Represents the default {@link UsageReplacer usage replacer} logic which
+     * simply delegates to {@link Node#replaceAtUsages(Node)}.
+     */
+    public static final UsageReplacer DEFAULT_REPLACER = new UsageReplacer() {
+        @Override
+        public void replace(ValueNode oldNode, ValueNode newNode) {
+            oldNode.replaceAtUsages(newNode);
+        }
+    };
+
+    /**
      * Replaces a given fixed node with this specialized snippet.
      *
      * @param runtime
      * @param replacee the node that will be replaced
+     * @param replacer object that replaces the usages of {@code replacee}
      * @param args the arguments to be bound to the flattened positional parameters of the snippet
      * @return the map of duplicated nodes (original -> duplicate)
      */
     public Map<Node, Node> instantiate(MetaAccessProvider runtime,
-                    FixedWithNextNode replacee, SnippetTemplate.Arguments args) {
+                    FixedWithNextNode replacee,
+                    UsageReplacer replacer,
+                    SnippetTemplate.Arguments args) {
 
         // Inline the snippet nodes, replacing parameters with the given args in the process
         String name = snippet.name == null ? "{copy}" : snippet.name + "{copy}";
@@ -549,15 +577,15 @@
         }
 
         // Replace all usages of the replacee with the value returned by the snippet
-        Node returnValue = null;
+        ValueNode returnValue = null;
         if (returnNode != null) {
             if (returnNode.result() instanceof LocalNode) {
-                returnValue = replacements.get(returnNode.result());
+                returnValue = (ValueNode) replacements.get(returnNode.result());
             } else {
-                returnValue = duplicates.get(returnNode.result());
+                returnValue = (ValueNode) duplicates.get(returnNode.result());
             }
             assert returnValue != null || replacee.usages().isEmpty();
-            replacee.replaceAtUsages(returnValue);
+            replacer.replace(replacee, returnValue);
 
             Node returnDuplicate = duplicates.get(returnNode);
             returnDuplicate.clearInputs();
@@ -578,11 +606,13 @@
      *
      * @param runtime
      * @param replacee the node that will be replaced
+     * @param replacer object that replaces the usages of {@code replacee}
      * @param lastFixedNode the CFG of the snippet is inserted after this node
      * @param args the arguments to be bound to the flattened positional parameters of the snippet
      */
     public void instantiate(MetaAccessProvider runtime,
                     FloatingNode replacee,
+                    UsageReplacer replacer,
                     FixedWithNextNode lastFixedNode, SnippetTemplate.Arguments args) {
 
         // Inline the snippet nodes, replacing parameters with the given args in the process
@@ -613,14 +643,14 @@
 
         // Replace all usages of the replacee with the value returned by the snippet
         assert returnNode != null : replaceeGraph;
-        Node returnValue = null;
+        ValueNode returnValue = null;
         if (returnNode.result() instanceof LocalNode) {
-            returnValue = replacements.get(returnNode.result());
+            returnValue = (ValueNode) replacements.get(returnNode.result());
         } else {
-            returnValue = duplicates.get(returnNode.result());
+            returnValue = (ValueNode) duplicates.get(returnNode.result());
         }
         assert returnValue != null || replacee.usages().isEmpty();
-        replacee.replaceAtUsages(returnValue);
+        replacer.replace(replacee, returnValue);
 
         Node returnDuplicate = duplicates.get(returnNode);
         returnDuplicate.clearInputs();