# HG changeset patch # User Thomas Wuerthinger # Date 1423074093 -3600 # Node ID 8fe322db4b6d4902fb01d0f494527765500e23aa # Parent 04a07ceab00db304f3e4ec33b683a00350b283f8 Prototype for configuring inlining during parsing via a closure in the GraphBuilderConfiguration object. diff -r 04a07ceab00d -r 8fe322db4b6d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java --- 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 createGraphBuilderSuite() { PhaseSuite 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; } diff -r 04a07ceab00d -r 8fe322db4b6d graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java --- 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; + } } diff -r 04a07ceab00d -r 8fe322db4b6d graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- 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); } diff -r 04a07ceab00d -r 8fe322db4b6d graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugins.java --- 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. */ diff -r 04a07ceab00d -r 8fe322db4b6d graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java --- 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 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"); }