# HG changeset patch # User Doug Simon # Date 1350922204 -7200 # Node ID d8408e5563e5c9c150ccd4f5bcd1f238ae233038 # Parent 3bc7183309e061edbefe19bdbcc5d3dfb3eca274 added indirection for the replacement of a snippet-lowered node with the snippet's return value diff -r 3bc7183309e0 -r d8408e5563e5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CheckCastSnippets.java --- 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) { diff -r 3bc7183309e0 -r d8408e5563e5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/InstanceOfSnippets.java --- 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); } diff -r 3bc7183309e0 -r d8408e5563e5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/MonitorSnippets.java --- 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 nodes = template.instantiate(runtime, monitorenterNode, arguments); + Map 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 nodes = template.instantiate(runtime, monitorexitNode, arguments); + Map nodes = template.instantiate(runtime, monitorexitNode, DEFAULT_REPLACER, arguments); for (Node n : nodes.values()) { if (n instanceof EndLockScopeNode) { EndLockScopeNode end = (EndLockScopeNode) n; diff -r 3bc7183309e0 -r d8408e5563e5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java --- 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); } } diff -r 3bc7183309e0 -r d8408e5563e5 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java --- 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 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();