changeset 19132:8fe322db4b6d

Prototype for configuring inlining during parsing via a closure in the GraphBuilderConfiguration object.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Wed, 04 Feb 2015 19:21:33 +0100
parents 04a07ceab00d
children ce6f3cfbc7e0
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugins.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java
diffstat 5 files changed, 94 insertions(+), 67 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java	Wed Feb 04 15:08:31 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java	Wed Feb 04 19:21:33 2015 +0100
@@ -26,11 +26,14 @@
 
 import java.util.function.*;
 
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.phases.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.java.GraphBuilderConfiguration.DebugInfoMode;
+import com.oracle.graal.java.GraphBuilderPlugins.InlineInvokePlugin;
 import com.oracle.graal.options.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.tiers.*;
@@ -84,7 +87,12 @@
     protected PhaseSuite<HighTierContext> createGraphBuilderSuite() {
         PhaseSuite<HighTierContext> suite = new PhaseSuite<>();
         GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault();
-        config = config.withInlineTrivial(true);
+        config.setInlineInvokePlugin(new InlineInvokePlugin() {
+            public boolean shouldInlineInvoke(ResolvedJavaMethod method, int depth) {
+                return GraalOptions.InlineDuringParsing.getValue() && method.getCode().length <= GraalOptions.TrivialInliningSize.getValue() &&
+                                depth < GraalOptions.InlineDuringParsingMaxDepth.getValue();
+            }
+        });
         suite.appendPhase(new GraphBuilderPhase(config));
         return suite;
     }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java	Wed Feb 04 15:08:31 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java	Wed Feb 04 19:21:33 2015 +0100
@@ -36,9 +36,9 @@
     private final ResolvedJavaType[] skippedExceptionTypes;
     private final DebugInfoMode debugInfoMode;
     private final boolean doLivenessAnalysis;
-    private final boolean inlineTrivial;
     private GraphBuilderPlugins.LoadFieldPlugin loadFieldPlugin;
     private GraphBuilderPlugins.ParameterPlugin parameterPlugin;
+    private GraphBuilderPlugins.InlineInvokePlugin inlineInvokePlugin;
 
     public static enum DebugInfoMode {
         SafePointsOnly,
@@ -64,41 +64,35 @@
         Full,
     }
 
-    protected GraphBuilderConfiguration(boolean eagerResolving, boolean omitAllExceptionEdges, DebugInfoMode debugInfoMode, ResolvedJavaType[] skippedExceptionTypes, boolean doLivenessAnalysis,
-                    boolean inlineTrivial) {
+    protected GraphBuilderConfiguration(boolean eagerResolving, boolean omitAllExceptionEdges, DebugInfoMode debugInfoMode, ResolvedJavaType[] skippedExceptionTypes, boolean doLivenessAnalysis) {
         this.eagerResolving = eagerResolving;
         this.omitAllExceptionEdges = omitAllExceptionEdges;
         this.debugInfoMode = debugInfoMode;
         this.skippedExceptionTypes = skippedExceptionTypes;
         this.doLivenessAnalysis = doLivenessAnalysis;
-        this.inlineTrivial = inlineTrivial;
     }
 
     public GraphBuilderConfiguration copy() {
-        GraphBuilderConfiguration result = new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, skippedExceptionTypes, doLivenessAnalysis, inlineTrivial);
+        GraphBuilderConfiguration result = new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, skippedExceptionTypes, doLivenessAnalysis);
         result.loadFieldPlugin = loadFieldPlugin;
         return result;
     }
 
     public GraphBuilderConfiguration withSkippedExceptionTypes(ResolvedJavaType[] newSkippedExceptionTypes) {
-        return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, newSkippedExceptionTypes, doLivenessAnalysis, inlineTrivial);
+        return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, newSkippedExceptionTypes, doLivenessAnalysis);
     }
 
     public GraphBuilderConfiguration withOmitAllExceptionEdges(boolean newOmitAllExceptionEdges) {
-        return new GraphBuilderConfiguration(eagerResolving, newOmitAllExceptionEdges, debugInfoMode, skippedExceptionTypes, doLivenessAnalysis, inlineTrivial);
+        return new GraphBuilderConfiguration(eagerResolving, newOmitAllExceptionEdges, debugInfoMode, skippedExceptionTypes, doLivenessAnalysis);
     }
 
     public GraphBuilderConfiguration withDebugInfoMode(DebugInfoMode newDebugInfoMode) {
         ResolvedJavaType[] newSkippedExceptionTypes = skippedExceptionTypes == EMPTY ? EMPTY : Arrays.copyOf(skippedExceptionTypes, skippedExceptionTypes.length);
-        return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, newDebugInfoMode, newSkippedExceptionTypes, doLivenessAnalysis, inlineTrivial);
+        return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, newDebugInfoMode, newSkippedExceptionTypes, doLivenessAnalysis);
     }
 
     public GraphBuilderConfiguration withDoLivenessAnalysis(boolean newLivenessAnalysis) {
-        return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, skippedExceptionTypes, newLivenessAnalysis, inlineTrivial);
-    }
-
-    public GraphBuilderConfiguration withInlineTrivial(boolean newInlineTrivial) {
-        return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, skippedExceptionTypes, doLivenessAnalysis, newInlineTrivial);
+        return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, skippedExceptionTypes, newLivenessAnalysis);
     }
 
     public GraphBuilderPlugins.LoadFieldPlugin getLoadFieldPlugin() {
@@ -134,19 +128,19 @@
     }
 
     public static GraphBuilderConfiguration getDefault() {
-        return new GraphBuilderConfiguration(false, false, DebugInfoMode.SafePointsOnly, EMPTY, GraalOptions.OptLivenessAnalysis.getValue(), false);
+        return new GraphBuilderConfiguration(false, false, DebugInfoMode.SafePointsOnly, EMPTY, GraalOptions.OptLivenessAnalysis.getValue());
     }
 
     public static GraphBuilderConfiguration getEagerDefault() {
-        return new GraphBuilderConfiguration(true, false, DebugInfoMode.SafePointsOnly, EMPTY, GraalOptions.OptLivenessAnalysis.getValue(), false);
+        return new GraphBuilderConfiguration(true, false, DebugInfoMode.SafePointsOnly, EMPTY, GraalOptions.OptLivenessAnalysis.getValue());
     }
 
     public static GraphBuilderConfiguration getSnippetDefault() {
-        return new GraphBuilderConfiguration(true, true, DebugInfoMode.SafePointsOnly, EMPTY, GraalOptions.OptLivenessAnalysis.getValue(), false);
+        return new GraphBuilderConfiguration(true, true, DebugInfoMode.SafePointsOnly, EMPTY, GraalOptions.OptLivenessAnalysis.getValue());
     }
 
     public static GraphBuilderConfiguration getFullDebugDefault() {
-        return new GraphBuilderConfiguration(true, false, DebugInfoMode.Full, EMPTY, GraalOptions.OptLivenessAnalysis.getValue(), false);
+        return new GraphBuilderConfiguration(true, false, DebugInfoMode.Full, EMPTY, GraalOptions.OptLivenessAnalysis.getValue());
     }
 
     /**
@@ -158,10 +152,6 @@
         return eagerResolving;
     }
 
-    public boolean shouldInlineTrivial() {
-        return inlineTrivial;
-    }
-
     public GraphBuilderPlugins.ParameterPlugin getParameterPlugin() {
         return parameterPlugin;
     }
@@ -169,4 +159,12 @@
     public void setParameterPlugin(GraphBuilderPlugins.ParameterPlugin parameterPlugin) {
         this.parameterPlugin = parameterPlugin;
     }
+
+    public GraphBuilderPlugins.InlineInvokePlugin getInlineInvokePlugin() {
+        return inlineInvokePlugin;
+    }
+
+    public void setInlineInvokePlugin(GraphBuilderPlugins.InlineInvokePlugin inlineInvokePlugin) {
+        this.inlineInvokePlugin = inlineInvokePlugin;
+    }
 }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Feb 04 15:08:31 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Feb 04 19:21:33 2015 +0100
@@ -42,7 +42,7 @@
 import com.oracle.graal.java.BciBlockMapping.BciBlock;
 import com.oracle.graal.java.BciBlockMapping.ExceptionDispatchBlock;
 import com.oracle.graal.java.BciBlockMapping.LocalLiveness;
-import com.oracle.graal.java.GraphBuilderPlugins.InvocationPlugin;
+import com.oracle.graal.java.GraphBuilderPlugins.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.CallTargetNode.InvokeKind;
 import com.oracle.graal.nodes.calc.*;
@@ -779,55 +779,26 @@
                         args[0] = TypeProfileProxyNode.proxify(args[0], profile);
                     }
                 }
-                if (GraalOptions.InlineDuringParsing.getValue() && invokeKind.isDirect()) {
 
-                    if (graphBuilderPlugins != null) {
-                        InvocationPlugin plugin = graphBuilderPlugins.lookupInvocation(targetMethod);
-                        if (plugin != null) {
-                            int beforeStackSize = frameState.stackSize;
-                            if (plugin.apply(this, args)) {
-                                assert beforeStackSize + resultType.getSlotCount() == frameState.stackSize;
-                                return;
-                            }
-                            assert beforeStackSize == frameState.stackSize;
-                        }
-                    }
-
-                    if (targetMethod.canBeInlined() && targetMethod.hasBytecodes()) {
-                        if (targetMethod.getCode().length <= GraalOptions.TrivialInliningSize.getValue() && currentDepth < GraalOptions.InlineDuringParsingMaxDepth.getValue() &&
-                                        graphBuilderConfig.shouldInlineTrivial()) {
-                            BytecodeParser parser = new BytecodeParser(metaAccess, targetMethod, graphBuilderConfig, optimisticOpts, StructuredGraph.INVOCATION_ENTRY_BCI);
-                            final FrameState[] lazyFrameState = new FrameState[1];
-                            HIRFrameStateBuilder startFrameState = new HIRFrameStateBuilder(targetMethod, currentGraph, () -> {
-                                if (lazyFrameState[0] == null) {
-                                    lazyFrameState[0] = frameState.create(bci());
-                                }
-                                return lazyFrameState[0];
-                            });
-                            startFrameState.initializeFromArgumentsArray(args);
-                            parser.build(currentDepth + 1, this.lastInstr, startFrameState);
-
-                            FixedWithNextNode calleeBeforeReturnNode = parser.getBeforeReturnNode();
-                            this.lastInstr = calleeBeforeReturnNode;
-                            if (calleeBeforeReturnNode != null) {
-                                ValueNode calleeReturnValue = parser.getReturnValue();
-                                if (calleeReturnValue != null) {
-                                    frameState.push(calleeReturnValue.getKind().getStackKind(), calleeReturnValue);
-                                }
-                            }
-
-                            FixedWithNextNode calleeBeforeUnwindNode = parser.getBeforeUnwindNode();
-                            if (calleeBeforeUnwindNode != null) {
-                                ValueNode calleeUnwindValue = parser.getUnwindValue();
-                                assert calleeUnwindValue != null;
-                                calleeBeforeUnwindNode.setNext(handleException(calleeUnwindValue, bci()));
-                            }
-
+                if (graphBuilderPlugins != null) {
+                    InvocationPlugin plugin = graphBuilderPlugins.lookupInvocation(targetMethod);
+                    if (plugin != null) {
+                        int beforeStackSize = frameState.stackSize;
+                        if (plugin.apply(this, args)) {
+                            assert beforeStackSize + resultType.getSlotCount() == frameState.stackSize;
                             return;
                         }
+                        assert beforeStackSize == frameState.stackSize;
                     }
                 }
 
+                InlineInvokePlugin inlineInvokePlugin = graphBuilderConfig.getInlineInvokePlugin();
+                if (inlineInvokePlugin != null && invokeKind.isDirect() && targetMethod.canBeInlined() && targetMethod.hasBytecodes() &&
+                                inlineInvokePlugin.shouldInlineInvoke(targetMethod, currentDepth)) {
+                    parseAndInlineCallee(targetMethod, args);
+                    return;
+                }
+
                 MethodCallTargetNode callTarget = currentGraph.add(createMethodCallTarget(invokeKind, targetMethod, args, returnType));
 
                 // be conservative if information was not recorded (could result in endless
@@ -842,6 +813,35 @@
                 }
             }
 
+            private void parseAndInlineCallee(ResolvedJavaMethod targetMethod, ValueNode[] args) {
+                BytecodeParser parser = new BytecodeParser(metaAccess, targetMethod, graphBuilderConfig, optimisticOpts, StructuredGraph.INVOCATION_ENTRY_BCI);
+                final FrameState[] lazyFrameState = new FrameState[1];
+                HIRFrameStateBuilder startFrameState = new HIRFrameStateBuilder(targetMethod, currentGraph, () -> {
+                    if (lazyFrameState[0] == null) {
+                        lazyFrameState[0] = frameState.create(bci());
+                    }
+                    return lazyFrameState[0];
+                });
+                startFrameState.initializeFromArgumentsArray(args);
+                parser.build(currentDepth + 1, this.lastInstr, startFrameState);
+
+                FixedWithNextNode calleeBeforeReturnNode = parser.getBeforeReturnNode();
+                this.lastInstr = calleeBeforeReturnNode;
+                if (calleeBeforeReturnNode != null) {
+                    ValueNode calleeReturnValue = parser.getReturnValue();
+                    if (calleeReturnValue != null) {
+                        frameState.push(calleeReturnValue.getKind().getStackKind(), calleeReturnValue);
+                    }
+                }
+
+                FixedWithNextNode calleeBeforeUnwindNode = parser.getBeforeUnwindNode();
+                if (calleeBeforeUnwindNode != null) {
+                    ValueNode calleeUnwindValue = parser.getUnwindValue();
+                    assert calleeUnwindValue != null;
+                    calleeBeforeUnwindNode.setNext(handleException(calleeUnwindValue, bci()));
+                }
+            }
+
             protected MethodCallTargetNode createMethodCallTarget(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] args, JavaType returnType) {
                 return new MethodCallTargetNode(invokeKind, targetMethod, args, returnType);
             }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugins.java	Wed Feb 04 15:08:31 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugins.java	Wed Feb 04 19:21:33 2015 +0100
@@ -45,6 +45,10 @@
         FloatingNode interceptParameter(int index);
     }
 
+    public interface InlineInvokePlugin extends GraphBuilderPlugin {
+        boolean shouldInlineInvoke(ResolvedJavaMethod method, int depth);
+    }
+
     /**
      * Plugin for handling a method invocation.
      */
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Wed Feb 04 15:08:31 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Wed Feb 04 19:21:33 2015 +0100
@@ -30,6 +30,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.debug.internal.*;
@@ -59,6 +60,7 @@
 import com.oracle.graal.truffle.phases.*;
 import com.oracle.graal.virtual.phases.ea.*;
 import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.nodes.*;
 
 /**
@@ -175,12 +177,27 @@
         }
     }
 
+    private class InlineInvokePlugin implements GraphBuilderPlugins.InlineInvokePlugin {
+
+        public boolean shouldInlineInvoke(ResolvedJavaMethod method, int depth) {
+            return method.getAnnotation(TruffleBoundary.class) != null;
+        }
+
+    }
+
     @SuppressWarnings("unused")
     private void fastPartialEvaluation(OptimizedCallTarget callTarget, Assumptions assumptions, StructuredGraph graph, PhaseContext baseContext, HighTierContext tierContext) {
         GraphBuilderConfiguration newConfig = configForRoot.copy();
         newConfig.setLoadFieldPlugin(new InterceptLoadFieldPlugin());
         newConfig.setParameterPlugin(new InterceptReceiverPlugin(callTarget));
-        new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), new Assumptions(false), providers.getConstantReflection(), newConfig, TruffleCompilerImpl.Optimizations).apply(graph);
+        newConfig.setInlineInvokePlugin(new InlineInvokePlugin());
+        DefaultGraphBuilderPlugins plugins = new DefaultGraphBuilderPlugins();
+        Iterable<GraphBuilderPluginsProvider> sl = Services.load(GraphBuilderPluginsProvider.class);
+        for (GraphBuilderPluginsProvider p : sl) {
+            p.registerPlugins(providers.getMetaAccess(), plugins);
+        }
+        new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), new Assumptions(false), providers.getConstantReflection(), newConfig, plugins,
+                        TruffleCompilerImpl.Optimizations).apply(graph);
         Debug.dump(graph, "After FastPE");
     }