# HG changeset patch # User Doug Simon # Date 1355848364 -3600 # Node ID 9c06e8bd8769b492c9ad4e7a7d06cf79046d5966 # Parent 5b969d6f46064181fff4ba0fd7ce25622b44b779 added phase to remove unnecessary frame states from substitution snippets fixed debug scope used for snippet installation to capture all phases of installing a specific snippet with a filter (i.e. -G:MethodFilter) set for that snippet diff -r 5b969d6f4606 -r 9c06e8bd8769 graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/WordTest.java --- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/WordTest.java Tue Dec 18 15:28:15 2012 +0100 +++ b/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/WordTest.java Tue Dec 18 17:32:44 2012 +0100 @@ -53,7 +53,7 @@ @Override protected StructuredGraph parse(Method m) { ResolvedJavaMethod resolvedMethod = runtime.lookupJavaMethod(m); - return installer.makeGraph(resolvedMethod, inliningPolicy.get()); + return installer.makeGraph(resolvedMethod, inliningPolicy.get(), false); } @Test diff -r 5b969d6f4606 -r 9c06e8bd8769 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetFrameStateCleanupPhase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetFrameStateCleanupPhase.java Tue Dec 18 17:32:44 2012 +0100 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.snippets; + +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.util.*; +import com.oracle.graal.phases.*; + +/** + * Removes frame states from {@linkplain StateSplit#hasSideEffect() non-side-effecting} nodes in a snippet. + */ +public class SnippetFrameStateCleanupPhase extends Phase { + + @Override + protected void run(StructuredGraph graph) { + for (Node node : graph.getNodes().filterInterface(StateSplit.class)) { + StateSplit stateSplit = (StateSplit) node; + FrameState frameState = stateSplit.stateAfter(); + if (!stateSplit.hasSideEffect()) { + if (frameState != null) { + stateSplit.setStateAfter(null); + if (frameState.usages().isEmpty()) { + GraphUtil.killWithUnusedFloatingInputs(frameState); + } + } + } + } + } +} diff -r 5b969d6f4606 -r 9c06e8bd8769 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java Tue Dec 18 15:28:15 2012 +0100 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java Tue Dec 18 17:32:44 2012 +0100 @@ -93,7 +93,7 @@ } ResolvedJavaMethod snippet = runtime.lookupJavaMethod(method); assert snippet.getCompilerStorage().get(Graph.class) == null : method; - StructuredGraph graph = makeGraph(snippet, inliningPolicy(snippet)); + StructuredGraph graph = makeGraph(snippet, inliningPolicy(snippet), false); //System.out.println("snippet: " + graph); snippet.getCompilerStorage().put(Graph.class, graph); } @@ -131,7 +131,7 @@ throw new RuntimeException("Snippet must not be abstract or native"); } ResolvedJavaMethod snippet = runtime.lookupJavaMethod(method); - StructuredGraph graph = makeGraph(snippet, inliningPolicy(snippet)); + StructuredGraph graph = makeGraph(snippet, inliningPolicy(snippet), true); //System.out.println("snippet: " + graph); runtime.lookupJavaMethod(originalMethod).getCompilerStorage().put(Graph.class, graph); } catch (NoSuchMethodException e) { @@ -156,14 +156,26 @@ } } - public StructuredGraph makeGraph(final ResolvedJavaMethod method, final SnippetInliningPolicy policy) { - StructuredGraph graph = parseGraph(method, policy); + public StructuredGraph makeGraph(final ResolvedJavaMethod method, final SnippetInliningPolicy policy, final boolean isSubstitutionSnippet) { + return Debug.scope("BuildSnippetGraph", new Object[] {method}, new Callable() { + @Override + public StructuredGraph call() throws Exception { + StructuredGraph graph = parseGraph(method, policy); + + new SnippetIntrinsificationPhase(runtime, pool, SnippetTemplate.hasConstantParameter(method)).apply(graph); - new SnippetIntrinsificationPhase(runtime, pool, SnippetTemplate.hasConstantParameter(method)).apply(graph); + if (isSubstitutionSnippet) { + new SnippetFrameStateCleanupPhase().apply(graph); + new DeadCodeEliminationPhase().apply(graph); + } - Debug.dump(graph, "%s: Final", method.getName()); + new InsertStateAfterPlaceholderPhase().apply(graph); + + Debug.dump(graph, "%s: Final", method.getName()); - return graph; + return graph; + } + }); } private StructuredGraph parseGraph(final ResolvedJavaMethod method, final SnippetInliningPolicy policy) { @@ -178,54 +190,47 @@ private StructuredGraph buildGraph(final ResolvedJavaMethod method, final SnippetInliningPolicy policy) { final StructuredGraph graph = new StructuredGraph(method); - return Debug.scope("BuildSnippetGraph", new Object[] {method, graph}, new Callable() { - @Override - public StructuredGraph call() throws Exception { - GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault(); - GraphBuilderPhase graphBuilder = new GraphBuilderPhase(runtime, config, OptimisticOptimizations.NONE); - graphBuilder.apply(graph); + GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault(); + GraphBuilderPhase graphBuilder = new GraphBuilderPhase(runtime, config, OptimisticOptimizations.NONE); + graphBuilder.apply(graph); - Debug.dump(graph, "%s: %s", method.getName(), GraphBuilderPhase.class.getSimpleName()); + Debug.dump(graph, "%s: %s", method.getName(), GraphBuilderPhase.class.getSimpleName()); - new SnippetVerificationPhase(runtime).apply(graph); + new SnippetVerificationPhase(runtime).apply(graph); - new SnippetIntrinsificationPhase(runtime, pool, true).apply(graph); + new SnippetIntrinsificationPhase(runtime, pool, true).apply(graph); - for (Invoke invoke : graph.getInvokes()) { - MethodCallTargetNode callTarget = invoke.methodCallTarget(); - ResolvedJavaMethod callee = callTarget.targetMethod(); - if (policy.shouldInline(callee, method)) { - StructuredGraph targetGraph = parseGraph(callee, policy); - InliningUtil.inline(invoke, targetGraph, true); - Debug.dump(graph, "after inlining %s", callee); - if (GraalOptions.OptCanonicalizer) { - new WordTypeRewriterPhase(target.wordKind).apply(graph); - new CanonicalizerPhase(target, runtime, assumptions).apply(graph); - } - } - } - - new SnippetIntrinsificationPhase(runtime, pool, true).apply(graph); - - new WordTypeRewriterPhase(target.wordKind).apply(graph); - - new DeadCodeEliminationPhase().apply(graph); + for (Invoke invoke : graph.getInvokes()) { + MethodCallTargetNode callTarget = invoke.methodCallTarget(); + ResolvedJavaMethod callee = callTarget.targetMethod(); + if (policy.shouldInline(callee, method)) { + StructuredGraph targetGraph = parseGraph(callee, policy); + InliningUtil.inline(invoke, targetGraph, true); + Debug.dump(graph, "after inlining %s", callee); if (GraalOptions.OptCanonicalizer) { + new WordTypeRewriterPhase(target.wordKind).apply(graph); new CanonicalizerPhase(target, runtime, assumptions).apply(graph); } + } + } - for (LoopEndNode end : graph.getNodes(LoopEndNode.class)) { - end.disableSafepoint(); - } + new SnippetIntrinsificationPhase(runtime, pool, true).apply(graph); - new InsertStateAfterPlaceholderPhase().apply(graph); + new WordTypeRewriterPhase(target.wordKind).apply(graph); - if (GraalOptions.ProbabilityAnalysis) { - new DeadCodeEliminationPhase().apply(graph); - new ComputeProbabilityPhase().apply(graph); - } - return graph; - } - }); + new DeadCodeEliminationPhase().apply(graph); + if (GraalOptions.OptCanonicalizer) { + new CanonicalizerPhase(target, runtime, assumptions).apply(graph); + } + + for (LoopEndNode end : graph.getNodes(LoopEndNode.class)) { + end.disableSafepoint(); + } + + if (GraalOptions.ProbabilityAnalysis) { + new DeadCodeEliminationPhase().apply(graph); + new ComputeProbabilityPhase().apply(graph); + } + return graph; } } diff -r 5b969d6f4606 -r 9c06e8bd8769 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 Tue Dec 18 15:28:15 2012 +0100 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java Tue Dec 18 17:32:44 2012 +0100 @@ -208,7 +208,9 @@ throw new GraalInternalError(e); } } -} + } + + private static final Object UNUSED_PARAMETER = "DEAD PARAMETER"; /** * Determines if any parameter of a given method is annotated with {@link ConstantParameter}. @@ -315,8 +317,12 @@ Parameter p = parameterAnnotations[i]; if (p != null) { LocalNode local = snippetCopy.getLocal(i); - assert local != null; - parameters.put(p.value(), local); + if (local == null) { + // Parameter value was eliminated + parameters.put(p.value(), UNUSED_PARAMETER); + } else { + parameters.put(p.value(), local); + } } } } @@ -431,7 +437,9 @@ /** * The named parameters of this template that must be bound to values during instantiation. - * Each value in this map is either a {@link LocalNode} instance or a {@link LocalNode} array. + * For a parameter that is still live after specialization, the value in this map is either + * a {@link LocalNode} instance or a {@link LocalNode} array. For an eliminated parameter, + * the value is identical to the key. */ private final Map parameters; @@ -477,8 +485,7 @@ Constant constant = Constant.forBoxed(kind, argument); replacements.put((LocalNode) parameter, ConstantNode.forConstant(constant, runtime, replaceeGraph)); } - } else { - assert parameter instanceof LocalNode[]; + } else if (parameter instanceof LocalNode[]) { LocalNode[] locals = (LocalNode[]) parameter; Object array = argument; assert array != null && array.getClass().isArray(); @@ -496,6 +503,8 @@ replacements.put(local, element); } } + } else { + assert parameter == UNUSED_PARAMETER : "unexpected entry for parameter: " + name + " -> " + parameter; } } return replacements; @@ -673,7 +682,9 @@ Object value = e.getValue(); buf.append(sep); sep = ", "; - if (value instanceof LocalNode) { + if (value == UNUSED_PARAMETER) { + buf.append(" ").append(name); + } else if (value instanceof LocalNode) { LocalNode local = (LocalNode) value; buf.append(local.kind().getJavaName()).append(' ').append(name); } else {