# HG changeset patch # User Christian Wimmer # Date 1410918970 25200 # Node ID f95ddcd3e08a80b9c402f968eea3b3844ecc6dc4 # Parent 21fdd914bb8f193dc826ccbf4e6b2a17ae4c3ed7 Allow customization by subclasses diff -r 21fdd914bb8f -r f95ddcd3e08a graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java --- 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++) { diff -r 21fdd914bb8f -r f95ddcd3e08a graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java --- 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 methodSubstitutions = new HashMap<>(); - private final Map> macroSubstitutions = new HashMap<>(); - private final Set forcedSubstitutions = new HashSet<>(); + public final Map methodSubstitutions = new HashMap<>(); + public final Map> macroSubstitutions = new HashMap<>(); + public final Set forcedSubstitutions = new HashSet<>(); public ClassReplacements(Class[] substitutionClasses, AtomicReference 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)); diff -r 21fdd914bb8f -r f95ddcd3e08a graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java --- 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 = 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 = 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