changeset 17140:f95ddcd3e08a

Allow customization by subclasses
author Christian Wimmer <christian.wimmer@oracle.com>
date Tue, 16 Sep 2014 18:56:10 -0700
parents 21fdd914bb8f
children 2d01369ee234
files graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java
diffstat 3 files changed, 63 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java	Tue Sep 16 18:55:03 2014 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java	Tue Sep 16 18:56:10 2014 -0700
@@ -208,7 +208,7 @@
         return result;
     }
 
-    private Node createNodeInstance(StructuredGraph graph, ResolvedJavaType nodeClass, ResolvedJavaType[] parameterTypes, Stamp invokeStamp, boolean setStampFromReturnType,
+    protected Node createNodeInstance(StructuredGraph graph, ResolvedJavaType nodeClass, ResolvedJavaType[] parameterTypes, Stamp invokeStamp, boolean setStampFromReturnType,
                     Constant[] nodeFactoryArguments) {
         ResolvedJavaMethod factory = null;
         Constant[] arguments = null;
@@ -233,7 +233,7 @@
         }
 
         try {
-            ValueNode intrinsicNode = (ValueNode) snippetReflection.asObject(factory.invoke(null, arguments));
+            ValueNode intrinsicNode = (ValueNode) snippetReflection.asObject(invokeFactory(factory, arguments));
 
             if (setStampFromReturnType) {
                 intrinsicNode.setStamp(invokeStamp);
@@ -244,6 +244,10 @@
         }
     }
 
+    protected Constant invokeFactory(ResolvedJavaMethod factory, Constant[] arguments) {
+        return factory.invoke(null, arguments);
+    }
+
     private static String sigString(ResolvedJavaType[] types) {
         StringBuilder sb = new StringBuilder("(");
         for (int i = 0; i < types.length; i++) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Tue Sep 16 18:55:03 2014 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Tue Sep 16 18:56:10 2014 -0700
@@ -75,9 +75,9 @@
      * Encapsulates method and macro substitutions for a single class.
      */
     protected class ClassReplacements {
-        protected final Map<ResolvedJavaMethod, ResolvedJavaMethod> methodSubstitutions = new HashMap<>();
-        private final Map<ResolvedJavaMethod, Class<? extends FixedWithNextNode>> macroSubstitutions = new HashMap<>();
-        private final Set<ResolvedJavaMethod> forcedSubstitutions = new HashSet<>();
+        public final Map<ResolvedJavaMethod, ResolvedJavaMethod> methodSubstitutions = new HashMap<>();
+        public final Map<ResolvedJavaMethod, Class<? extends FixedWithNextNode>> macroSubstitutions = new HashMap<>();
+        public final Set<ResolvedJavaMethod> forcedSubstitutions = new HashSet<>();
 
         public ClassReplacements(Class<?>[] substitutionClasses, AtomicReference<ClassReplacements> ref) {
             for (Class<?> substitutionClass : substitutionClasses) {
@@ -266,11 +266,15 @@
 
         // Do deferred intrinsification of node intrinsics
 
-        new NodeIntrinsificationPhase(providers, snippetReflection).apply(specializedSnippet);
+        createNodeIntrinsificationPhase().apply(specializedSnippet);
         new CanonicalizerPhase(true).apply(specializedSnippet, new PhaseContext(providers, assumptions));
         NodeIntrinsificationVerificationPhase.verify(specializedSnippet);
     }
 
+    protected NodeIntrinsificationPhase createNodeIntrinsificationPhase() {
+        return new NodeIntrinsificationPhase(providers, snippetReflection);
+    }
+
     @Override
     public StructuredGraph getMethodSubstitution(ResolvedJavaMethod original) {
         ClassReplacements cr = getClassReplacements(original.getDeclaringClass().getName());
@@ -491,7 +495,7 @@
          * Does final processing of a snippet graph.
          */
         protected void finalizeGraph(StructuredGraph graph) {
-            new NodeIntrinsificationPhase(providers, snippetReflection).apply(graph);
+            createNodeIntrinsificationPhase().apply(graph);
             if (!SnippetTemplate.hasConstantParameter(method)) {
                 NodeIntrinsificationVerificationPhase.verify(graph);
             }
@@ -576,6 +580,7 @@
                 } else {
                     createGraphBuilder(metaAccess, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(graph);
                 }
+                afterParsing(graph);
                 new WordTypeVerificationPhase(metaAccess, snippetReflection, target.wordKind).apply(graph);
                 new WordTypeRewriterPhase(metaAccess, snippetReflection, target.wordKind).apply(graph);
 
@@ -592,6 +597,9 @@
             return new GraphBuilderPhase.Instance(metaAccess, graphBuilderConfig, optimisticOpts);
         }
 
+        protected void afterParsing(@SuppressWarnings("unused") StructuredGraph graph) {
+        }
+
         protected Object beforeInline(@SuppressWarnings("unused") MethodCallTargetNode callTarget, @SuppressWarnings("unused") StructuredGraph callee) {
             return null;
         }
@@ -613,7 +621,7 @@
          * Called after all inlining for a given graph is complete.
          */
         protected void afterInlining(StructuredGraph graph) {
-            new NodeIntrinsificationPhase(providers, snippetReflection).apply(graph);
+            createNodeIntrinsificationPhase().apply(graph);
             new DeadCodeEliminationPhase(Optional).apply(graph);
             if (OptCanonicalizer.getValue()) {
                 new CanonicalizerPhase(true).apply(graph, new PhaseContext(providers, assumptions));
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Tue Sep 16 18:55:03 2014 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Tue Sep 16 18:56:10 2014 -0700
@@ -74,12 +74,14 @@
  */
 public class SnippetTemplate {
 
+    public static boolean LAZY_SNIPPETS = true;
+
     /**
      * Holds the {@link ResolvedJavaMethod} of the snippet, together with some information about the
      * method that needs to be computed only once. The {@link SnippetInfo} should be created once
      * per snippet and then cached.
      */
-    public static class SnippetInfo {
+    public abstract static class SnippetInfo {
 
         protected final ResolvedJavaMethod method;
 
@@ -126,8 +128,6 @@
 
         }
 
-        protected final AtomicReference<Lazy> lazy = new AtomicReference<>(null);
-
         /**
          * Times instantiations of all templates derived form this snippet.
          *
@@ -142,12 +142,7 @@
          */
         private final DebugMetric instantiationCounter;
 
-        private Lazy lazy() {
-            if (lazy.get() == null) {
-                lazy.compareAndSet(null, new Lazy(method));
-            }
-            return lazy.get();
-        }
+        protected abstract Lazy lazy();
 
         protected SnippetInfo(ResolvedJavaMethod method) {
             this.method = method;
@@ -192,6 +187,36 @@
         }
     }
 
+    protected static class LazySnippetInfo extends SnippetInfo {
+        protected final AtomicReference<Lazy> lazy = new AtomicReference<>(null);
+
+        protected LazySnippetInfo(ResolvedJavaMethod method) {
+            super(method);
+        }
+
+        @Override
+        protected Lazy lazy() {
+            if (lazy.get() == null) {
+                lazy.compareAndSet(null, new Lazy(method));
+            }
+            return lazy.get();
+        }
+    }
+
+    protected static class EagerSnippetInfo extends SnippetInfo {
+        protected final Lazy lazy;
+
+        protected EagerSnippetInfo(ResolvedJavaMethod method) {
+            super(method);
+            lazy = new Lazy(method);
+        }
+
+        @Override
+        protected Lazy lazy() {
+            return lazy;
+        }
+    }
+
     /**
      * Values that are bound to the snippet method parameters. The methods {@link #add},
      * {@link #addConst}, and {@link #addVarargs} must be called in the same order as in the
@@ -473,7 +498,11 @@
             assert findMethod(declaringClass, methodName, method) == null : "found more than one method named " + methodName + " in " + declaringClass;
             ResolvedJavaMethod javaMethod = providers.getMetaAccess().lookupJavaMethod(method);
             providers.getReplacements().registerSnippet(javaMethod);
-            return new SnippetInfo(javaMethod);
+            if (LAZY_SNIPPETS) {
+                return new LazySnippetInfo(javaMethod);
+            } else {
+                return new EagerSnippetInfo(javaMethod);
+            }
         }
 
         /**
@@ -957,6 +986,10 @@
             // no floating reads yet, ignore locations created while lowering
             return true;
         }
+        if (returnNode == null) {
+            // The snippet terminates control flow
+            return true;
+        }
         MemoryMapNode memoryMap = returnNode.getMemoryMap();
         if (memoryMap == null || memoryMap.isEmpty()) {
             // there are no kills in the snippet graph