diff --git a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/PartialEvaluator.java b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/PartialEvaluator.java index bd460e6e0896..d6afee31ee30 100644 --- a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/PartialEvaluator.java +++ b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/PartialEvaluator.java @@ -25,8 +25,6 @@ package org.graalvm.compiler.truffle.compiler; import static org.graalvm.compiler.truffle.options.PolyglotCompilerOptions.ExcludeAssertions; -import static org.graalvm.compiler.truffle.options.PolyglotCompilerOptions.InlineAcrossTruffleBoundary; -import static org.graalvm.compiler.truffle.options.PolyglotCompilerOptions.IterativePartialEscape; import static org.graalvm.compiler.truffle.options.PolyglotCompilerOptions.MaximumGraalNodeCount; import static org.graalvm.compiler.truffle.options.PolyglotCompilerOptions.NodeSourcePositions; import static org.graalvm.compiler.truffle.options.PolyglotCompilerOptions.PrintExpansionHistogram; @@ -35,19 +33,11 @@ import java.net.URI; import java.nio.Buffer; -import java.util.Objects; import org.graalvm.collections.EconomicMap; -import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; -import org.graalvm.compiler.core.common.CompilationIdentifier; import org.graalvm.compiler.core.common.type.StampPair; -import org.graalvm.compiler.debug.DebugCloseable; -import org.graalvm.compiler.debug.DebugContext; -import org.graalvm.compiler.debug.Indent; -import org.graalvm.compiler.debug.TimerKey; import org.graalvm.compiler.graph.SourceLanguagePosition; import org.graalvm.compiler.graph.SourceLanguagePositionProvider; -import org.graalvm.compiler.loop.phases.ConvertDeoptimizeToGuardPhase; import org.graalvm.compiler.nodes.ConstantNode; import org.graalvm.compiler.nodes.DeoptimizeNode; import org.graalvm.compiler.nodes.EncodedGraph; @@ -65,16 +55,6 @@ import org.graalvm.compiler.nodes.graphbuilderconf.LoopExplosionPlugin; import org.graalvm.compiler.nodes.graphbuilderconf.NodePlugin; import org.graalvm.compiler.nodes.graphbuilderconf.ParameterPlugin; -import org.graalvm.compiler.nodes.java.MethodCallTargetNode; -import org.graalvm.compiler.nodes.virtual.VirtualInstanceNode; -import org.graalvm.compiler.nodes.virtual.VirtualObjectNode; -import org.graalvm.compiler.phases.OptimisticOptimizations; -import org.graalvm.compiler.phases.PhaseSuite; -import org.graalvm.compiler.phases.common.CanonicalizerPhase; -import org.graalvm.compiler.phases.common.ConditionalEliminationPhase; -import org.graalvm.compiler.phases.common.inlining.InliningUtil; -import org.graalvm.compiler.phases.tiers.HighTierContext; -import org.graalvm.compiler.phases.util.GraphOrder; import org.graalvm.compiler.phases.util.Providers; import org.graalvm.compiler.replacements.CachingPEGraphDecoder; import org.graalvm.compiler.replacements.InlineDuringParsingPlugin; @@ -88,27 +68,15 @@ import org.graalvm.compiler.truffle.common.TruffleCompilerRuntime.InlineKind; import org.graalvm.compiler.truffle.common.TruffleInliningData; import org.graalvm.compiler.truffle.common.TruffleSourceLanguagePosition; -import org.graalvm.compiler.truffle.compiler.TruffleCompilerImpl.CancellableTruffleCompilationTask; -import org.graalvm.compiler.truffle.compiler.nodes.TruffleAssumption; -import org.graalvm.compiler.truffle.compiler.nodes.asserts.NeverPartOfCompilationNode; -import org.graalvm.compiler.truffle.compiler.nodes.frame.AllowMaterializeNode; import org.graalvm.compiler.truffle.compiler.phases.DeoptimizeOnExceptionPhase; -import org.graalvm.compiler.truffle.compiler.phases.FrameAccessVerificationPhase; -import org.graalvm.compiler.truffle.compiler.phases.InstrumentBranchesPhase; import org.graalvm.compiler.truffle.compiler.phases.InstrumentPhase; -import org.graalvm.compiler.truffle.compiler.phases.InstrumentTruffleBoundariesPhase; -import org.graalvm.compiler.truffle.compiler.phases.PhiTransformPhase; -import org.graalvm.compiler.truffle.compiler.phases.VerifyFrameDoesNotEscapePhase; -import org.graalvm.compiler.truffle.compiler.phases.inlining.AgnosticInliningPhase; import org.graalvm.compiler.truffle.compiler.substitutions.GraphBuilderInvocationPluginProvider; import org.graalvm.compiler.truffle.compiler.substitutions.KnownTruffleTypes; import org.graalvm.compiler.truffle.compiler.substitutions.TruffleGraphBuilderPlugins; -import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase; import org.graalvm.options.OptionValues; import com.oracle.truffle.api.TruffleOptions; -import jdk.vm.ci.code.Architecture; import jdk.vm.ci.code.BailoutException; import jdk.vm.ci.meta.DeoptimizationAction; import jdk.vm.ci.meta.DeoptimizationReason; @@ -116,7 +84,6 @@ import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; -import jdk.vm.ci.meta.SpeculationLog; import jdk.vm.ci.meta.SpeculationLog.SpeculationReason; /** @@ -124,57 +91,46 @@ */ public abstract class PartialEvaluator { - private static final TimerKey PartialEvaluationTimer = DebugContext.timer("PartialEvaluation-Decoding").doc("Time spent in the graph-decoding of partial evaluation."); - private static final TimerKey TruffleEscapeAnalysisTimer = DebugContext.timer("PartialEvaluation-EscapeAnalysis").doc("Time spent in the escape-analysis in Truffle tier."); - private static final TimerKey TruffleFrameVerifyFrameTimer = DebugContext.timer("PartialEvaluation-VerifyFrame").doc("Time spent in frame access verification in Truffle tier."); - private static final TimerKey TruffleTransformPhiTimer = DebugContext.timer("PartialEvaluation-TransformPhi").doc("Time spent in phi processing in Truffle tier."); - private static final TimerKey TruffleConditionalEliminationTimer = DebugContext.timer("PartialEvaluation-ConditionalElimination").doc("Time spent in conditional elimination in Truffle tier."); - private static final TimerKey TruffleCanonicalizerTimer = DebugContext.timer("PartialEvaluation-Canonicalizer").doc("Time spent in the canonicalizer in the Truffle tier."); - private static final TimerKey TruffleConvertDeoptimizeTimer = DebugContext.timer("PartialEvaluation-ConvertDeoptimizeToGuard").doc("Time spent in converting deoptimize to guard in Truffle tier."); - + // Configs protected final TruffleCompilerConfiguration config; - protected final Providers providers; - protected final Architecture architecture; - private final CanonicalizerPhase canonicalizer; - private final SnippetReflectionProvider snippetReflection; + // TODO GR-37097 Move to TruffleCompilerImpl + volatile GraphBuilderConfiguration configForParsing; + // Methods final ResolvedJavaMethod callDirectMethod; protected final ResolvedJavaMethod callInlined; final ResolvedJavaMethod callIndirectMethod; private final ResolvedJavaMethod profiledPERoot; + final ResolvedJavaMethod callBoundary; + // Plugins private final GraphBuilderConfiguration configPrototype; private final InvocationPlugins firstTierDecodingPlugins; private final InvocationPlugins lastTierDecodingPlugins; + protected final PELoopExplosionPlugin loopExplosionPlugin = new PELoopExplosionPlugin(); private final NodePlugin[] nodePlugins; + // Misc final KnownTruffleTypes knownTruffleTypes; - final ResolvedJavaMethod callBoundary; - private volatile GraphBuilderConfiguration configForParsing; - /** - * Holds instrumentation options initialized in - * {@link #initialize(org.graalvm.options.OptionValues)} method before the first compilation. - * These options are not engine aware. + * Holds instrumentation options initialized in {@link #initialize(OptionValues)} method before + * the first compilation. These options are not engine aware. */ - volatile InstrumentPhase.InstrumentationConfiguration instrumentationCfg; + // TODO GR-37097 Move to TruffleCompilerImpl + public volatile InstrumentPhase.InstrumentationConfiguration instrumentationCfg; /** * The instrumentation object is used by the Truffle instrumentation to count executions. The * value is lazily initialized the first time it is requested because it depends on the Truffle * options, and tests that need the instrumentation table need to override these options after * the TruffleRuntime object is created. */ + // TODO GR-37097 Move to TruffleCompilerImpl protected volatile InstrumentPhase.Instrumentation instrumentation; - protected final TruffleConstantFieldProvider compilationLocalConstantProvider; public PartialEvaluator(TruffleCompilerConfiguration config, GraphBuilderConfiguration configForRoot, KnownTruffleTypes knownFields) { this.config = config; - this.providers = config.lastTier().providers(); - this.architecture = config.architecture(); - this.canonicalizer = CanonicalizerPhase.create(); - this.snippetReflection = config.snippetReflection(); this.knownTruffleTypes = knownFields; TruffleCompilerRuntime runtime = TruffleCompilerRuntime.getRuntime(); - final MetaAccessProvider metaAccess = providers.getMetaAccess(); + final MetaAccessProvider metaAccess = this.config.lastTier().providers().getMetaAccess(); ResolvedJavaType type = runtime.resolveType(metaAccess, "org.graalvm.compiler.truffle.runtime.OptimizedCallTarget"); ResolvedJavaMethod[] methods = type.getDeclaredMethods(); this.callDirectMethod = findRequiredMethod(type, methods, "callDirect", "(Lcom/oracle/truffle/api/nodes/Node;[Ljava/lang/Object;)Ljava/lang/Object;"); @@ -187,7 +143,7 @@ public PartialEvaluator(TruffleCompilerConfiguration config, GraphBuilderConfigu this.firstTierDecodingPlugins = createDecodingInvocationPlugins(config.firstTier().partialEvaluator(), configForRoot.getPlugins(), config.firstTier().providers()); this.lastTierDecodingPlugins = createDecodingInvocationPlugins(config.lastTier().partialEvaluator(), configForRoot.getPlugins(), config.lastTier().providers()); this.nodePlugins = createNodePlugins(configForRoot.getPlugins()); - this.compilationLocalConstantProvider = new TruffleConstantFieldProvider(providers.getConstantFieldProvider(), providers.getMetaAccess()); + this.compilationLocalConstantProvider = new TruffleConstantFieldProvider(this.config.lastTier().providers().getConstantFieldProvider(), this.config.lastTier().providers().getMetaAccess()); } protected void initialize(OptionValues options) { @@ -209,7 +165,7 @@ public EconomicMap getOrCreateEncodedGraphCach * Gets the instrumentation manager associated with this compiler, creating it first if * necessary. Each compiler instance has its own instrumentation manager. */ - private InstrumentPhase.Instrumentation getInstrumentation() { + public InstrumentPhase.Instrumentation getInstrumentation() { if (instrumentation == null) { synchronized (this) { if (instrumentation == null) { @@ -251,7 +207,7 @@ public static InlineInvokePlugin.InlineInfo asInlineInfo(ResolvedJavaMethod meth } public Providers getProviders() { - return providers; + return config.lastTier().providers(); } /** @@ -298,129 +254,6 @@ public ResolvedJavaMethod getCallInlined() { return callInlined; } - public final class Request { - public final OptionValues options; - public final DebugContext debug; - public final CompilableTruffleAST compilable; - public final CompilationIdentifier compilationId; - public final SpeculationLog log; - public final CancellableTruffleCompilationTask task; - public final StructuredGraph graph; - final HighTierContext highTierContext; - - public Request(OptionValues options, DebugContext debug, CompilableTruffleAST compilable, ResolvedJavaMethod method, - CompilationIdentifier compilationId, SpeculationLog log, CancellableTruffleCompilationTask task) { - Objects.requireNonNull(options); - Objects.requireNonNull(debug); - Objects.requireNonNull(compilable); - Objects.requireNonNull(compilationId); - Objects.requireNonNull(task); - this.options = options; - this.debug = debug; - this.compilable = compilable; - this.compilationId = compilationId; - this.log = log; - this.task = task; - // @formatter:off - StructuredGraph.Builder builder = new StructuredGraph.Builder(this.debug.getOptions(), this.debug, AllowAssumptions.YES). - name(this.compilable.getName()). - method(method). - speculationLog(this.log). - compilationId(this.compilationId). - trackNodeSourcePosition(configForParsing.trackNodeSourcePosition()). - cancellable(this.task); - // @formatter:on - builder = customizeStructuredGraphBuilder(builder); - this.graph = builder.build(); - this.graph.getAssumptions().record(new TruffleAssumption(compilable.getValidRootAssumptionConstant())); - this.graph.getAssumptions().record(new TruffleAssumption(compilable.getNodeRewritingAssumptionConstant())); - highTierContext = new HighTierContext(providers, new PhaseSuite(), OptimisticOptimizations.NONE); - } - - public boolean isFirstTier() { - return task.isFirstTier(); - } - } - - @SuppressWarnings("try") - public final StructuredGraph evaluate(Request request) { - try (PerformanceInformationHandler handler = PerformanceInformationHandler.install(request.options)) { - try (DebugContext.Scope s = request.debug.scope("CreateGraph", request.graph); - Indent indent = request.debug.logAndIndent("evaluate %s", request.graph);) { - inliningGraphPE(request); - assert GraphOrder.assertSchedulableGraph(request.graph) : "PE result must be schedulable in order to apply subsequent phases"; - applyInstrumentationPhases(request); - handler.reportPerformanceWarnings(request.compilable, request.graph); - if (request.task.isCancelled()) { - return null; - } - new VerifyFrameDoesNotEscapePhase().apply(request.graph, false); - NeverPartOfCompilationNode.verifyNotFoundIn(request.graph); - materializeFrames(request.graph); - TruffleCompilerRuntime rt = TruffleCompilerRuntime.getRuntime(); - setIdentityForValueTypes(request, rt); - handleInliningAcrossTruffleBoundary(request, rt); - } catch (Throwable e) { - throw request.debug.handle(e); - } - return request.graph; - } - } - - private static void handleInliningAcrossTruffleBoundary(Request request, TruffleCompilerRuntime rt) { - if (!request.options.get(InlineAcrossTruffleBoundary)) { - // Do not inline across Truffle boundaries. - for (MethodCallTargetNode mct : request.graph.getNodes(MethodCallTargetNode.TYPE)) { - InlineKind inlineKind = rt.getInlineKind(mct.targetMethod(), false); - if (!inlineKind.allowsInlining()) { - mct.invoke().setUseForInlining(false); - } - } - } - } - - private static void setIdentityForValueTypes(Request request, TruffleCompilerRuntime rt) { - for (VirtualObjectNode virtualObjectNode : request.graph.getNodes(VirtualObjectNode.TYPE)) { - if (virtualObjectNode instanceof VirtualInstanceNode) { - VirtualInstanceNode virtualInstanceNode = (VirtualInstanceNode) virtualObjectNode; - ResolvedJavaType type = virtualInstanceNode.type(); - if (rt.isValueType(type)) { - virtualInstanceNode.setIdentity(false); - } - } - } - } - - private static void materializeFrames(StructuredGraph graph) { - for (AllowMaterializeNode materializeNode : graph.getNodes(AllowMaterializeNode.TYPE).snapshot()) { - materializeNode.replaceAtUsages(materializeNode.getFrame()); - graph.removeFixed(materializeNode); - } - } - - @SuppressWarnings({"unused", "try"}) - private void partialEscape(Request request) { - try (DebugContext.Scope pe = request.debug.scope("TrufflePartialEscape", request.graph)) { - new PartialEscapePhase(request.options.get(IterativePartialEscape), canonicalizer, request.graph.getOptions()).apply(request.graph, request.highTierContext); - } catch (Throwable t) { - request.debug.handle(t); - } - } - - private void inlineReplacements(Request request) { - for (MethodCallTargetNode methodCallTargetNode : request.graph.getNodes(MethodCallTargetNode.TYPE)) { - if (!methodCallTargetNode.invokeKind().isDirect()) { - continue; - } - StructuredGraph inlineGraph = providers.getReplacements().getInlineSubstitution(methodCallTargetNode.targetMethod(), methodCallTargetNode.invoke().bci(), - methodCallTargetNode.invoke().getInlineControl(), request.graph.trackNodeSourcePosition(), methodCallTargetNode.asNode().getNodeSourcePosition(), - request.graph.allowAssumptions(), request.debug.getOptions()); - if (inlineGraph != null) { - InliningUtil.inline(methodCallTargetNode.invoke(), inlineGraph, true, methodCallTargetNode.targetMethod()); - } - } - } - /** * Hook for subclasses: customize the StructuredGraph. */ @@ -459,7 +292,7 @@ private class InterceptReceiverPlugin implements ParameterPlugin { public FloatingNode interceptParameter(GraphBuilderTool b, int index, StampPair stamp) { if (index == 0) { JavaConstant c = compilable.asJavaConstant(); - return ConstantNode.forConstant(c, providers.getMetaAccess()); + return ConstantNode.forConstant(c, config.lastTier().providers().getMetaAccess()); } return null; } @@ -480,7 +313,7 @@ public SourceLanguagePosition getPosition(JavaConstant node) { } } - private class PELoopExplosionPlugin implements LoopExplosionPlugin { + private static final class PELoopExplosionPlugin implements LoopExplosionPlugin { @Override public LoopExplosionKind loopExplosionKind(ResolvedJavaMethod method) { @@ -506,71 +339,45 @@ public LoopExplosionKind loopExplosionKind(ResolvedJavaMethod method) { } @SuppressWarnings("unused") - protected PEGraphDecoder createGraphDecoder(Request request, LoopExplosionPlugin loopExplosionPlugin, - InvocationPlugins invocationPlugins, - InlineInvokePlugin[] inlineInvokePlugins, ParameterPlugin parameterPlugin, NodePlugin[] nodePluginList, - SourceLanguagePositionProvider sourceLanguagePositionProvider, EconomicMap graphCache) { + protected PEGraphDecoder createGraphDecoder(TruffleTierContext context, InvocationPlugins invocationPlugins, InlineInvokePlugin[] inlineInvokePlugins, ParameterPlugin parameterPlugin, + NodePlugin[] nodePluginList, SourceLanguagePositionProvider sourceLanguagePositionProvider, EconomicMap graphCache) { final GraphBuilderConfiguration newConfig = configForParsing.copy(); InvocationPlugins parsingInvocationPlugins = newConfig.getPlugins().getInvocationPlugins(); Plugins plugins = newConfig.getPlugins(); - ReplacementsImpl replacements = (ReplacementsImpl) providers.getReplacements(); + ReplacementsImpl replacements = (ReplacementsImpl) config.lastTier().providers().getReplacements(); plugins.clearInlineInvokePlugins(); plugins.appendInlineInvokePlugin(replacements); plugins.appendInlineInvokePlugin(new ParsingInlineInvokePlugin(this, replacements, parsingInvocationPlugins, loopExplosionPlugin)); - if (!request.options.get(PrintExpansionHistogram)) { + if (!context.options.get(PrintExpansionHistogram)) { plugins.appendInlineInvokePlugin(new InlineDuringParsingPlugin()); } - InvocationPlugins decodingPlugins = request.isFirstTier() ? firstTierDecodingPlugins : lastTierDecodingPlugins; + InvocationPlugins decodingPlugins = context.isFirstTier() ? firstTierDecodingPlugins : lastTierDecodingPlugins; DeoptimizeOnExceptionPhase postParsingPhase = new DeoptimizeOnExceptionPhase( method -> TruffleCompilerRuntime.getRuntime().getInlineKind(method, true) == InlineKind.DO_NOT_INLINE_WITH_SPECULATIVE_EXCEPTION); - Providers compilationUnitProviders = providers.copyWith(compilationLocalConstantProvider); - return new CachingPEGraphDecoder(architecture, request.graph, compilationUnitProviders, newConfig, TruffleCompilerImpl.Optimizations, - AllowAssumptions.ifNonNull(request.graph.getAssumptions()), + Providers compilationUnitProviders = config.lastTier().providers().copyWith(compilationLocalConstantProvider); + return new CachingPEGraphDecoder(config.architecture(), context.graph, compilationUnitProviders, newConfig, TruffleCompilerImpl.Optimizations, + AllowAssumptions.ifNonNull(context.graph.getAssumptions()), loopExplosionPlugin, decodingPlugins, inlineInvokePlugins, parameterPlugin, nodePluginList, callInlined, sourceLanguagePositionProvider, postParsingPhase, graphCache, false); } - public void doGraphPE(Request request, InlineInvokePlugin inlineInvokePlugin, EconomicMap graphCache) { + public void doGraphPE(TruffleTierContext context, InlineInvokePlugin inlineInvokePlugin, EconomicMap graphCache) { InlineInvokePlugin[] inlineInvokePlugins = new InlineInvokePlugin[]{ - (ReplacementsImpl) providers.getReplacements(), - new NodeLimitControlPlugin(request.options.get(MaximumGraalNodeCount)), + (ReplacementsImpl) config.lastTier().providers().getReplacements(), + new NodeLimitControlPlugin(context.options.get(MaximumGraalNodeCount)), inlineInvokePlugin }; - PEGraphDecoder decoder = createGraphDecoder(request, - new PELoopExplosionPlugin(), - request.isFirstTier() ? firstTierDecodingPlugins : lastTierDecodingPlugins, + PEGraphDecoder decoder = createGraphDecoder(context, + context.isFirstTier() ? firstTierDecodingPlugins : lastTierDecodingPlugins, inlineInvokePlugins, - new InterceptReceiverPlugin(request.compilable), + new InterceptReceiverPlugin(context.compilable), nodePlugins, - new TruffleSourceLanguagePositionProvider(request.task.inliningData()), + new TruffleSourceLanguagePositionProvider(context.task.inliningData()), graphCache); - decoder.decode(request.graph.method(), request.graph.isSubstitution(), request.graph.trackNodeSourcePosition()); - } - - @SuppressWarnings("try") - public void truffleTier(Request request) { - try (DebugCloseable a = TruffleConvertDeoptimizeTimer.start(request.debug)) { - new ConvertDeoptimizeToGuardPhase().apply(request.graph, request.highTierContext); - } - inlineReplacements(request); - try (DebugCloseable a = TruffleConditionalEliminationTimer.start(request.debug)) { - new ConditionalEliminationPhase(false).apply(request.graph, request.highTierContext); - } - try (DebugCloseable a = TruffleCanonicalizerTimer.start(request.debug)) { - canonicalizer.apply(request.graph, request.highTierContext); - } - try (DebugCloseable a = TruffleFrameVerifyFrameTimer.start(request.debug)) { - new FrameAccessVerificationPhase(request.compilable).apply(request.graph, request.highTierContext); - } - try (DebugCloseable a = TruffleEscapeAnalysisTimer.start(request.debug)) { - partialEscape(request); - } - try (DebugCloseable a = TruffleTransformPhiTimer.start(request.debug)) { - new PhiTransformPhase(canonicalizer).apply(request.graph, request.highTierContext); - } + decoder.decode(context.graph.method(), context.graph.isSubstitution(), context.graph.trackNodeSourcePosition()); } /** @@ -578,7 +385,7 @@ public void truffleTier(Request request) { * because the encoded graphs for the partial evaluator are shared between these compilation * tiers. */ - protected GraphBuilderConfiguration createGraphBuilderConfig(GraphBuilderConfiguration graphBuilderConfig, boolean canDelayIntrinsification) { + private GraphBuilderConfiguration createGraphBuilderConfig(GraphBuilderConfiguration graphBuilderConfig, boolean canDelayIntrinsification) { GraphBuilderConfiguration newConfig = graphBuilderConfig.copy(); InvocationPlugins invocationPlugins = newConfig.getPlugins().getInvocationPlugins(); registerGraphBuilderInvocationPlugins(invocationPlugins, canDelayIntrinsification); @@ -588,7 +395,7 @@ protected GraphBuilderConfiguration createGraphBuilderConfig(GraphBuilderConfigu protected void appendParsingNodePlugins(Plugins plugins) { if (JavaVersionUtil.JAVA_SPEC >= 16) { - ResolvedJavaType memorySegmentProxyType = TruffleCompilerRuntime.getRuntime().resolveType(providers.getMetaAccess(), "jdk.internal.access.foreign.MemorySegmentProxy"); + ResolvedJavaType memorySegmentProxyType = TruffleCompilerRuntime.getRuntime().resolveType(config.lastTier().providers().getMetaAccess(), "jdk.internal.access.foreign.MemorySegmentProxy"); for (ResolvedJavaMethod m : memorySegmentProxyType.getDeclaredMethods()) { if (m.getName().equals("scope")) { appendMemorySegmentProxyScopePlugin(plugins, m); @@ -622,9 +429,9 @@ protected NodePlugin[] createNodePlugins(Plugins plugins) { } protected void registerGraphBuilderInvocationPlugins(InvocationPlugins invocationPlugins, boolean canDelayIntrinsification) { - TruffleGraphBuilderPlugins.registerInvocationPlugins(invocationPlugins, canDelayIntrinsification, providers, knownTruffleTypes); + TruffleGraphBuilderPlugins.registerInvocationPlugins(invocationPlugins, canDelayIntrinsification, config.lastTier().providers(), knownTruffleTypes); for (GraphBuilderInvocationPluginProvider p : GraalServices.load(GraphBuilderInvocationPluginProvider.class)) { - p.registerInvocationPlugins(providers, architecture, invocationPlugins, canDelayIntrinsification); + p.registerInvocationPlugins(config.lastTier().providers(), config.architecture(), invocationPlugins, canDelayIntrinsification); } } @@ -641,34 +448,6 @@ protected InvocationPlugins createDecodingInvocationPlugins(PartialEvaluatorConf return decodingInvocationPlugins; } - @SuppressWarnings({"unused", "try"}) - private void inliningGraphPE(Request request) { - boolean inlined; - try (DebugCloseable a = PartialEvaluationTimer.start(request.debug)) { - AgnosticInliningPhase inliningPhase = new AgnosticInliningPhase(this, request); - inliningPhase.apply(request.graph, providers); - if (!inliningPhase.rootIsLeaf()) { - // If we've seen a truffle call in the graph, even if we have not inlined any call - // target, we need to run the truffle tier phases again after the PE inlining phase - // has finalized the graph. - // On the other hand, if there are no calls (root is a leaf) we can skip the truffle - // tier because there are no finalization points. - truffleTier(request); - } - } - request.graph.maybeCompress(); - } - - protected void applyInstrumentationPhases(Request request) { - InstrumentPhase.InstrumentationConfiguration cfg = instrumentationCfg; - if (cfg.instrumentBranches) { - new InstrumentBranchesPhase(request.options, snippetReflection, getInstrumentation(), cfg.instrumentBranchesPerInlineSite).apply(request.graph, request.highTierContext); - } - if (cfg.instrumentBoundaries) { - new InstrumentTruffleBoundariesPhase(request.options, snippetReflection, getInstrumentation(), cfg.instrumentBoundariesPerInlineSite).apply(request.graph, request.highTierContext); - } - } - private static final SpeculationReasonGroup TRUFFLE_BOUNDARY_EXCEPTION_SPECULATIONS = new SpeculationReasonGroup("TruffleBoundaryWithoutException", ResolvedJavaMethod.class); public static SpeculationReason createTruffleBoundaryExceptionSpeculation(ResolvedJavaMethod targetMethod) { diff --git a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/PerformanceInformationHandler.java b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/PerformanceInformationHandler.java index 2483fd4ebe32..0ecd84251b78 100644 --- a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/PerformanceInformationHandler.java +++ b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/PerformanceInformationHandler.java @@ -80,7 +80,7 @@ public void close() { instance.remove(); } - static PerformanceInformationHandler install(OptionValues options) { + public static PerformanceInformationHandler install(OptionValues options) { assert instance.get() == null : "PerformanceInformationHandler already installed"; PerformanceInformationHandler handler = new PerformanceInformationHandler(options); instance.set(handler); @@ -158,7 +158,7 @@ private String getPerformanceStackTrace(List locations) { } @SuppressWarnings("try") - void reportPerformanceWarnings(CompilableTruffleAST target, StructuredGraph graph) { + public void reportPerformanceWarnings(CompilableTruffleAST target, StructuredGraph graph) { DebugContext debug = graph.getDebug(); ArrayList warnings = new ArrayList<>(); if (isWarningEnabled(PolyglotCompilerOptions.PerformanceWarningKind.VIRTUAL_RUNTIME_CALL)) { diff --git a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/PostPartialEvaluationSuite.java b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/PostPartialEvaluationSuite.java new file mode 100644 index 000000000000..cc02dc3d3a37 --- /dev/null +++ b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/PostPartialEvaluationSuite.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013, 2022, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 org.graalvm.compiler.truffle.compiler; + +import org.graalvm.compiler.loop.phases.ConvertDeoptimizeToGuardPhase; +import org.graalvm.compiler.nodes.StructuredGraph; +import org.graalvm.compiler.nodes.java.MethodCallTargetNode; +import org.graalvm.compiler.phases.BasePhase; +import org.graalvm.compiler.phases.PhaseSuite; +import org.graalvm.compiler.phases.common.CanonicalizerPhase; +import org.graalvm.compiler.phases.common.ConditionalEliminationPhase; +import org.graalvm.compiler.phases.common.inlining.InliningUtil; +import org.graalvm.compiler.truffle.common.TruffleCompilerRuntime; +import org.graalvm.compiler.truffle.compiler.phases.FrameAccessVerificationPhase; +import org.graalvm.compiler.truffle.compiler.phases.PhiTransformPhase; +import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase; + +public class PostPartialEvaluationSuite extends PhaseSuite { + public PostPartialEvaluationSuite(boolean iterativePartialEscape) { + appendPhase(new ConvertDeoptimizeToGuardPhase()); + appendPhase(new InlineReplacementsPhase()); + appendPhase(new ConditionalEliminationPhase(false)); + CanonicalizerPhase canonicalizerPhase = CanonicalizerPhase.create(); + appendPhase(canonicalizerPhase); + appendPhase(new FrameAccessVerificationPhase()); + appendPhase(new PartialEscapePhase(iterativePartialEscape, canonicalizerPhase, + // Unsure about this part + TruffleCompilerRuntime.getRuntime().getGraalOptions(org.graalvm.compiler.options.OptionValues.class))); + appendPhase(new PhiTransformPhase(canonicalizerPhase)); + } + + public static class InlineReplacementsPhase extends BasePhase { + + @Override + protected void run(StructuredGraph graph, TruffleTierContext context) { + for (MethodCallTargetNode methodCallTargetNode : graph.getNodes(MethodCallTargetNode.TYPE)) { + if (!methodCallTargetNode.invokeKind().isDirect()) { + continue; + } + StructuredGraph inlineGraph = context.getProviders().getReplacements().getInlineSubstitution(methodCallTargetNode.targetMethod(), methodCallTargetNode.invoke().bci(), + methodCallTargetNode.invoke().getInlineControl(), graph.trackNodeSourcePosition(), methodCallTargetNode.asNode().getNodeSourcePosition(), + graph.allowAssumptions(), context.debug.getOptions()); + if (inlineGraph != null) { + InliningUtil.inline(methodCallTargetNode.invoke(), inlineGraph, true, methodCallTargetNode.targetMethod()); + } + } + } + } +} diff --git a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/TruffleCompilerBase.java b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/TruffleCompilerBase.java index 883971bee25e..ac997bdf67db 100644 --- a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/TruffleCompilerBase.java +++ b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/TruffleCompilerBase.java @@ -26,6 +26,7 @@ import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; import org.graalvm.compiler.truffle.common.TruffleCompiler; +import org.graalvm.compiler.truffle.compiler.phases.TruffleTier; /** * This interface declares additional methods from {@link TruffleCompilerImpl} which are not @@ -40,4 +41,6 @@ public interface TruffleCompilerBase extends TruffleCompiler { PartialEvaluator getPartialEvaluator(); SnippetReflectionProvider getSnippetReflection(); + + TruffleTier getTruffleTier(); } diff --git a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/TruffleCompilerImpl.java b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/TruffleCompilerImpl.java index e0a06e084367..da59c8af6a5a 100644 --- a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/TruffleCompilerImpl.java +++ b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/TruffleCompilerImpl.java @@ -36,6 +36,7 @@ import static org.graalvm.compiler.truffle.options.PolyglotCompilerOptions.CompilationFailureAction; import static org.graalvm.compiler.truffle.options.PolyglotCompilerOptions.ExcludeAssertions; import static org.graalvm.compiler.truffle.options.PolyglotCompilerOptions.FirstTierUseEconomy; +import static org.graalvm.compiler.truffle.options.PolyglotCompilerOptions.IterativePartialEscape; import static org.graalvm.compiler.truffle.options.PolyglotCompilerOptions.PerformanceWarningsAreFatal; import java.io.PrintStream; @@ -43,6 +44,7 @@ import java.nio.BufferUnderflowException; import java.nio.ReadOnlyBufferException; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; @@ -68,6 +70,7 @@ import org.graalvm.compiler.debug.DebugContext.Scope; import org.graalvm.compiler.debug.DiagnosticsOutputDirectory; import org.graalvm.compiler.debug.GraalError; +import org.graalvm.compiler.debug.Indent; import org.graalvm.compiler.debug.LogStream; import org.graalvm.compiler.debug.MemUseTrackerKey; import org.graalvm.compiler.debug.TTY; @@ -98,6 +101,8 @@ import org.graalvm.compiler.truffle.common.TruffleInliningData; import org.graalvm.compiler.truffle.compiler.nodes.TruffleAssumption; import org.graalvm.compiler.truffle.compiler.phases.InstrumentPhase; +import org.graalvm.compiler.truffle.compiler.phases.InstrumentationSuite; +import org.graalvm.compiler.truffle.compiler.phases.TruffleTier; import org.graalvm.compiler.truffle.options.OptionValuesImpl; import org.graalvm.compiler.truffle.options.PolyglotCompilerOptions; import org.graalvm.options.OptionDescriptor; @@ -111,7 +116,6 @@ import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.ResolvedJavaType; -import jdk.vm.ci.meta.SpeculationLog; /** * Coordinates partial evaluation of a Truffle AST and subsequent compilation via Graal. @@ -125,6 +129,8 @@ public abstract class TruffleCompilerImpl implements TruffleCompilerBase { private volatile ExpansionStatistics expansionStatistics; private volatile boolean expansionStatisticsInitialized; private volatile boolean initialized; + // Effectivelly final, but initialized in #initialize + private TruffleTier truffleTier; public static final OptimisticOptimizations Optimizations = ALL.remove( UseExceptionProbability, @@ -306,6 +312,7 @@ public void initialize(Map optionsMap, CompilableTruffleAST comp try (TTY.Filter ttyFilter = new TTY.Filter(new LogStream(new TTYToPolyglotLoggerBridge(compilable)))) { final org.graalvm.options.OptionValues options = getOptionsForCompiler(optionsMap); partialEvaluator.initialize(options); + truffleTier = newTruffleTier(options); initialized = true; if (!FirstTierUseEconomy.getValue(options)) { @@ -317,6 +324,13 @@ public void initialize(Map optionsMap, CompilableTruffleAST comp } } + // Hook for SVM + protected TruffleTier newTruffleTier(org.graalvm.options.OptionValues options) { + return new TruffleTier(options, partialEvaluator, + new InstrumentationSuite(partialEvaluator.instrumentationCfg, config.snippetReflection(), partialEvaluator.getInstrumentation()), + new PostPartialEvaluationSuite(options.get(IterativePartialEscape))); + } + private void actuallyCompile(org.graalvm.options.OptionValues options, TruffleCompilationTask task, TruffleCompilerListener listener, TruffleCompilationIdentifier compilationId, CompilableTruffleAST compilable, DebugContext graalDebug) { @@ -471,64 +485,38 @@ final ExpansionStatistics getExpansionHistogram(org.graalvm.options.OptionValues return local; } - /** - * Compiles a Truffle AST. If compilation succeeds, the AST will have compiled code associated - * with it that can be executed instead of interpreting the AST. - * - * @param options the values of {@link PolyglotCompilerOptions}. - * @param compilable representation of the AST to be compiled - * @param compilationId identifier to be used for the compilation - * @param task an object that holds information about the compilation process itself (e.g. which - * tier, was the compilation canceled) - * @param listener - */ - @SuppressWarnings("try") + // Used for tests and should be removed public void compileAST(org.graalvm.options.OptionValues options, DebugContext debug, final CompilableTruffleAST compilable, CompilationIdentifier compilationId, CancellableTruffleCompilationTask task, TruffleCompilerListener listener) { - final CompilationPrinter printer = CompilationPrinter.begin(debug.getOptions(), compilationId, new TruffleDebugJavaMethod(compilable), INVOCATION_ENTRY_BCI); - StructuredGraph graph = null; + compileAST(new TruffleCompilationWrapper(options, getDebugOutputDirectory(), Collections.emptyMap(), compilable, task, compilationId, listener), debug); + } + /** + * Compiles a Truffle AST. If compilation succeeds, the AST will have compiled code associated + * with it that can be executed instead of interpreting the AST. + */ + @SuppressWarnings("try") + private void compileAST(TruffleCompilationWrapper wrapper, DebugContext debug) { + final CompilationPrinter printer = CompilationPrinter.begin(debug.getOptions(), wrapper.compilationId, new TruffleDebugJavaMethod(wrapper.compilable), INVOCATION_ENTRY_BCI); + StructuredGraph graph = null; try (CompilationAlarm alarm = CompilationAlarm.trackCompilationPeriod(debug.getOptions())) { - PhaseSuite graphBuilderSuite = createGraphBuilderSuite(task.isFirstTier() ? config.firstTier() : config.lastTier()); - - ExpansionStatistics statistics = getExpansionHistogram(options); - SpeculationLog speculationLog = compilable.getCompilationSpeculationLog(); - if (speculationLog != null) { - speculationLog.collectFailedSpeculations(); - } - - try (DebugCloseable a = PartialEvaluationTime.start(debug); DebugCloseable c = PartialEvaluationMemUse.start(debug)) { - PartialEvaluator.Request request = partialEvaluator.new Request(options, debug, compilable, partialEvaluator.rootForCallTarget(compilable), - compilationId, speculationLog, task); - graph = partialEvaluator.evaluate(request); - if (statistics != null) { - statistics.afterPartialEvaluation(request.compilable, request.graph); - } - } - - // Check if the task has been cancelled - if (task.isCancelled()) { - return; - } - if (statistics != null) { - statistics.afterTruffleTier(compilable, graph); - } - if (listener != null) { - listener.onTruffleTierFinished(compilable, task.inliningData(), new GraphInfoImpl(graph)); - } + graph = truffleTier(wrapper, debug); + graph.checkCancellation(); // The Truffle compiler owns the last 2 characters of the compilation name, and uses // them to encode the compilation tier, so escaping the target name is not necessary. - String compilationName = compilable.toString() + (task.isFirstTier() ? TruffleCompiler.FIRST_TIER_COMPILATION_SUFFIX : TruffleCompiler.SECOND_TIER_COMPILATION_SUFFIX); - CompilationResult compilationResult = compilePEGraph(graph, compilationName, graphBuilderSuite, compilable, asCompilationRequest(compilationId), listener, task); - if (statistics != null) { - statistics.afterLowTier(compilable, graph); + String compilationName = wrapper.compilable.toString() + (wrapper.task.isFirstTier() ? TruffleCompiler.FIRST_TIER_COMPILATION_SUFFIX : TruffleCompiler.SECOND_TIER_COMPILATION_SUFFIX); + PhaseSuite graphBuilderSuite = createGraphBuilderSuite(wrapper.task.isFirstTier() ? config.firstTier() : config.lastTier()); + CompilationResult compilationResult = compilePEGraph(graph, compilationName, graphBuilderSuite, wrapper.compilable, asCompilationRequest(wrapper.compilationId), wrapper.listener, + wrapper.task); + if (wrapper.statistics != null) { + wrapper.statistics.afterLowTier(wrapper.compilable, graph); } - if (listener != null) { - listener.onSuccess(compilable, task.inliningData(), new GraphInfoImpl(graph), new CompilationResultInfoImpl(compilationResult), task.tier()); + if (wrapper.listener != null) { + wrapper.listener.onSuccess(wrapper.compilable, wrapper.task.inliningData(), new GraphInfoImpl(graph), new CompilationResultInfoImpl(compilationResult), wrapper.task.tier()); } // Partial evaluation and installation are included in @@ -540,15 +528,43 @@ public void compileAST(org.graalvm.options.OptionValues options, } // Note: If the compiler cancels the compilation with a bailout exception, then the // graph is null - if (listener != null) { + if (wrapper.listener != null) { BailoutException bailout = t instanceof BailoutException ? (BailoutException) t : null; boolean permanentBailout = bailout != null ? bailout.isPermanent() : false; - listener.onFailure(compilable, t.toString(), bailout != null, permanentBailout, task.tier()); + wrapper.listener.onFailure(wrapper.compilable, t.toString(), bailout != null, permanentBailout, wrapper.task.tier()); } throw t; } } + @SuppressWarnings("try") + private StructuredGraph truffleTier(TruffleCompilationWrapper wrapper, DebugContext debug) { + StructuredGraph graph; + try (DebugCloseable a = PartialEvaluationTime.start(debug); + DebugCloseable c = PartialEvaluationMemUse.start(debug); + PerformanceInformationHandler handler = PerformanceInformationHandler.install(wrapper.options)) { + /* + * TODO GR-37097 Merge TruffleTierConfiguration and TruffleCompilationWrapper so that + * there is one place where compilation data lives + */ + TruffleTierContext context = new TruffleTierContext(partialEvaluator, wrapper, debug, handler); + try (Scope s = context.debug.scope("CreateGraph", context.graph); + Indent indent = context.debug.logAndIndent("evaluate %s", context.graph);) { + truffleTier.apply(context.graph, context); + graph = context.graph; + } catch (Throwable e) { + throw context.debug.handle(e); + } + } + if (wrapper.statistics != null) { + wrapper.statistics.afterTruffleTier(wrapper.compilable, graph); + } + if (wrapper.listener != null) { + wrapper.listener.onTruffleTierFinished(wrapper.compilable, wrapper.task.inliningData(), new GraphInfoImpl(graph)); + } + return graph; + } + /** * Hook for processing bailout exceptions. * @@ -561,7 +577,8 @@ protected void handleBailout(DebugContext debug, StructuredGraph graph, BailoutE } /** - * Compiles a graph produced by {@link PartialEvaluator#evaluate partial evaluation}. + * Compiles a graph produced by {@link TruffleTier}, i.e. + * {@link #truffleTier(TruffleCompilationWrapper, DebugContext)}. * * @param graph a graph resulting from partial evaluation * @param name the name to be used for the returned {@link CompilationResult#getName() result} @@ -646,6 +663,11 @@ public PartialEvaluator getPartialEvaluator() { return partialEvaluator; } + @Override + public TruffleTier getTruffleTier() { + return truffleTier; + } + public CompilableTruffleAST asCompilableTruffleAST(JavaConstant constant) { return config.snippetReflection().asObject(CompilableTruffleAST.class, constant); } @@ -653,13 +675,14 @@ public CompilableTruffleAST asCompilableTruffleAST(JavaConstant constant) { /** * Wrapper for performing a Truffle compilation that can retry upon failure. */ - private final class TruffleCompilationWrapper extends CompilationWrapper { - private final CompilableTruffleAST compilable; - private final CancellableTruffleCompilationTask task; - private final TruffleCompilerListener listener; - private final CompilationIdentifier compilationId; - private final org.graalvm.options.OptionValues options; - private boolean silent; + final class TruffleCompilationWrapper extends CompilationWrapper { + final CompilableTruffleAST compilable; + final CancellableTruffleCompilationTask task; + final TruffleCompilerListener listener; + final CompilationIdentifier compilationId; + final org.graalvm.options.OptionValues options; + final ExpansionStatistics statistics; + boolean silent; private TruffleCompilationWrapper( org.graalvm.options.OptionValues options, @@ -675,6 +698,7 @@ private TruffleCompilationWrapper( this.task = task; this.listener = listener; this.compilationId = compilationId; + this.statistics = getExpansionHistogram(options); } @Override @@ -715,7 +739,7 @@ protected Void handleException(Throwable t) { @Override protected Void performCompilation(DebugContext debug) { - compileAST(options, debug, compilable, compilationId, task, listener); + compileAST(this, debug); return null; } diff --git a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/TruffleTierContext.java b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/TruffleTierContext.java new file mode 100644 index 000000000000..04e2ad389e18 --- /dev/null +++ b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/TruffleTierContext.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013, 2022, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 org.graalvm.compiler.truffle.compiler; + +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.SpeculationLog; +import org.graalvm.compiler.core.common.CompilationIdentifier; +import org.graalvm.compiler.debug.DebugContext; +import org.graalvm.compiler.nodes.StructuredGraph; +import org.graalvm.compiler.phases.OptimisticOptimizations; +import org.graalvm.compiler.phases.PhaseSuite; +import org.graalvm.compiler.phases.tiers.HighTierContext; +import org.graalvm.compiler.truffle.common.CompilableTruffleAST; +import org.graalvm.compiler.truffle.compiler.nodes.TruffleAssumption; +import org.graalvm.options.OptionValues; + +import java.util.Objects; + +public final class TruffleTierContext extends HighTierContext { + public final OptionValues options; + public final DebugContext debug; + public final CompilableTruffleAST compilable; + public final CompilationIdentifier compilationId; + public final SpeculationLog log; + public final TruffleCompilerImpl.CancellableTruffleCompilationTask task; + public final StructuredGraph graph; + public final PerformanceInformationHandler handler; + + public TruffleTierContext(PartialEvaluator partialEvaluator, OptionValues options, DebugContext debug, CompilableTruffleAST compilable, ResolvedJavaMethod method, + CompilationIdentifier compilationId, SpeculationLog log, TruffleCompilerImpl.CancellableTruffleCompilationTask task, PerformanceInformationHandler handler) { + super(partialEvaluator.getProviders(), new PhaseSuite<>(), OptimisticOptimizations.NONE); + Objects.requireNonNull(options); + Objects.requireNonNull(debug); + Objects.requireNonNull(compilable); + Objects.requireNonNull(compilationId); + Objects.requireNonNull(task); + this.options = options; + this.debug = debug; + this.compilable = compilable; + this.compilationId = compilationId; + this.log = log; + this.task = task; + // @formatter:off + StructuredGraph.Builder builder = new StructuredGraph.Builder(this.debug.getOptions(), this.debug, StructuredGraph.AllowAssumptions.YES). + name(this.compilable.getName()). + method(method). + speculationLog(this.log). + compilationId(this.compilationId). + trackNodeSourcePosition(partialEvaluator.configForParsing.trackNodeSourcePosition()). + cancellable(this.task); + // @formatter:on + builder = partialEvaluator.customizeStructuredGraphBuilder(builder); + this.graph = builder.build(); + this.graph.getAssumptions().record(new TruffleAssumption(compilable.getValidRootAssumptionConstant())); + this.graph.getAssumptions().record(new TruffleAssumption(compilable.getNodeRewritingAssumptionConstant())); + this.handler = handler; + } + + public TruffleTierContext(PartialEvaluator partialEvaluator, TruffleCompilerImpl.TruffleCompilationWrapper wrapper, DebugContext debug, PerformanceInformationHandler handler) { + this(partialEvaluator, wrapper.options, debug, wrapper.compilable, partialEvaluator.rootForCallTarget(wrapper.compilable), wrapper.compilationId, getSpeculationLog(wrapper), wrapper.task, + handler); + } + + public boolean isFirstTier() { + return task.isFirstTier(); + } + + private static SpeculationLog getSpeculationLog(TruffleCompilerImpl.TruffleCompilationWrapper wrapper) { + SpeculationLog speculationLog = wrapper.compilable.getCompilationSpeculationLog(); + if (speculationLog != null) { + speculationLog.collectFailedSpeculations(); + } + return speculationLog; + } +} diff --git a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/nodes/asserts/NeverPartOfCompilationNode.java b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/nodes/asserts/NeverPartOfCompilationNode.java index 3a5315608602..8cbbb1624afe 100644 --- a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/nodes/asserts/NeverPartOfCompilationNode.java +++ b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/nodes/asserts/NeverPartOfCompilationNode.java @@ -28,7 +28,6 @@ import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_0; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_0; -import org.graalvm.compiler.core.common.GraalBailoutException; import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.graph.IterableNodeType; import org.graalvm.compiler.graph.NodeClass; @@ -36,8 +35,6 @@ import org.graalvm.compiler.nodes.ControlSinkNode; import org.graalvm.compiler.nodes.FrameState; import org.graalvm.compiler.nodes.StateSplit; -import org.graalvm.compiler.nodes.StructuredGraph; -import org.graalvm.compiler.nodes.util.GraphUtil; @NodeInfo(cycles = CYCLES_0, size = SIZE_0) public final class NeverPartOfCompilationNode extends ControlSinkNode implements StateSplit, IterableNodeType { @@ -72,24 +69,4 @@ public boolean hasSideEffect() { return true; } - public static void verifyNotFoundIn(final StructuredGraph graph) { - for (NeverPartOfCompilationNode neverPartOfCompilationNode : graph.getNodes(NeverPartOfCompilationNode.TYPE)) { - final NeverPartOfCompilationException neverPartOfCompilationException = new NeverPartOfCompilationException(neverPartOfCompilationNode.getMessage()); - neverPartOfCompilationException.setStackTrace(GraphUtil.approxSourceStackTraceElement(neverPartOfCompilationNode)); - throw neverPartOfCompilationException; - } - } - - @SuppressWarnings("serial") - private static class NeverPartOfCompilationException extends GraalBailoutException { - - NeverPartOfCompilationException(String message) { - super(null, message, new Object[]{}); - } - - @Override - public boolean isCausedByCompilerAssert() { - return true; - } - } } diff --git a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/FrameAccessVerificationPhase.java b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/FrameAccessVerificationPhase.java index 360988de3f18..511038465d22 100644 --- a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/FrameAccessVerificationPhase.java +++ b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/FrameAccessVerificationPhase.java @@ -49,7 +49,6 @@ import org.graalvm.compiler.nodes.LoopEndNode; import org.graalvm.compiler.nodes.LoopExitNode; import org.graalvm.compiler.nodes.StructuredGraph; -import org.graalvm.compiler.nodes.spi.CoreProviders; import org.graalvm.compiler.nodes.util.GraphUtil; import org.graalvm.compiler.phases.BasePhase; import org.graalvm.compiler.phases.graph.ReentrantNodeIterator; @@ -57,6 +56,7 @@ import org.graalvm.compiler.phases.graph.ReentrantNodeIterator.NodeIteratorClosure; import org.graalvm.compiler.truffle.common.CompilableTruffleAST; import org.graalvm.compiler.truffle.compiler.PerformanceInformationHandler; +import org.graalvm.compiler.truffle.compiler.TruffleTierContext; import org.graalvm.compiler.truffle.compiler.nodes.frame.NewFrameNode; import org.graalvm.compiler.truffle.compiler.nodes.frame.VirtualFrameAccessType; import org.graalvm.compiler.truffle.compiler.nodes.frame.VirtualFrameAccessorNode; @@ -78,7 +78,7 @@ * This analysis will insert {@link VirtualFrameSetNode}s to change the type of uninitialized slots * whenever this is necessary to produce matching types at merges. */ -public final class FrameAccessVerificationPhase extends BasePhase { +public final class FrameAccessVerificationPhase extends BasePhase { private static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; @@ -107,8 +107,6 @@ private static byte mode(byte tag) { return (byte) (tag & MODE_MASK); } - private final CompilableTruffleAST compilable; - private abstract static class Effect { final NewFrameNode frame; final AbstractEndNode insertBefore; @@ -125,8 +123,11 @@ private abstract static class Effect { private final class DeoptEffect extends Effect { - DeoptEffect(NewFrameNode frame, AbstractEndNode insertBefore, int index) { + private final CompilableTruffleAST compilable; + + DeoptEffect(NewFrameNode frame, AbstractEndNode insertBefore, int index, CompilableTruffleAST compilable) { super(frame, insertBefore, index); + this.compilable = compilable; } @SuppressWarnings("try") @@ -188,36 +189,36 @@ void apply() { } } - private final ArrayList effects = new ArrayList<>(); - - public FrameAccessVerificationPhase(CompilableTruffleAST compilable) { - this.compilable = compilable; - } - @Override - protected void run(StructuredGraph graph, CoreProviders context) { + protected void run(StructuredGraph graph, TruffleTierContext context) { if (graph.getNodes(NewFrameNode.TYPE).isNotEmpty()) { - ReentrantNodeIterator.apply(new ReentrantIterator(), graph.start(), new State()); + ArrayList effects = new ArrayList<>(); + ReentrantNodeIterator.apply(new ReentrantIterator(context.compilable, effects), graph.start(), new State(effects)); for (Effect effect : effects) { effect.apply(); } } } - private final class State implements Cloneable { + private static final class State implements Cloneable { private final HashMap states = new HashMap<>(); private final HashMap indexedStates = new HashMap<>(); + private final ArrayList effects; + + State(ArrayList effects) { + this.effects = effects; + } @Override public State clone() { - State newState = new State(); + State newState = new State(effects); copy(states, newState.states); copy(indexedStates, newState.indexedStates); return newState; } - private void copy(HashMap from, HashMap to) { + private static void copy(HashMap from, HashMap to) { for (Map.Entry entry : from.entrySet()) { to.put(entry.getKey(), entry.getValue().clone()); } @@ -264,6 +265,14 @@ private static boolean inRange(byte[] array, int index) { private final class ReentrantIterator extends NodeIteratorClosure { + private final CompilableTruffleAST compilable; + private final ArrayList effects; + + ReentrantIterator(CompilableTruffleAST compilable, ArrayList effects) { + this.compilable = compilable; + this.effects = effects; + } + @Override protected State processNode(FixedNode node, State currentState) { if (node instanceof NewFrameNode) { @@ -372,7 +381,7 @@ private void mergeEntries(AbstractMergeNode merge, NewFrameNode frame, byte[] re // match } else { // different definitive types at merge - (i == 0 ? firstEndEffects : effects).add(new DeoptEffect(frame, merge.phiPredecessorAt(i), entryIndex)); + (i == 0 ? firstEndEffects : effects).add(new DeoptEffect(frame, merge.phiPredecessorAt(i), entryIndex, compilable)); entries[i] = withValue(definitiveType); } } diff --git a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/InliningAcrossTruffleBoundaryPhase.java b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/InliningAcrossTruffleBoundaryPhase.java new file mode 100644 index 000000000000..24ff36d7b8e3 --- /dev/null +++ b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/InliningAcrossTruffleBoundaryPhase.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013, 2022, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 org.graalvm.compiler.truffle.compiler.phases; + +import org.graalvm.compiler.nodes.StructuredGraph; +import org.graalvm.compiler.nodes.java.MethodCallTargetNode; +import org.graalvm.compiler.phases.BasePhase; +import org.graalvm.compiler.truffle.common.TruffleCompilerRuntime; +import org.graalvm.compiler.truffle.compiler.TruffleTierContext; + +public final class InliningAcrossTruffleBoundaryPhase extends BasePhase { + @Override + protected void run(StructuredGraph graph, TruffleTierContext context) { + graph.checkCancellation(); + TruffleCompilerRuntime rt = TruffleCompilerRuntime.getRuntime(); + for (MethodCallTargetNode mct : graph.getNodes(MethodCallTargetNode.TYPE)) { + TruffleCompilerRuntime.InlineKind inlineKind = rt.getInlineKind(mct.targetMethod(), false); + if (!inlineKind.allowsInlining()) { + mct.invoke().setUseForInlining(false); + } + } + } +} diff --git a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/InstrumentBranchesPhase.java b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/InstrumentBranchesPhase.java index 3d1cdab1c370..ca289159e0f7 100644 --- a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/InstrumentBranchesPhase.java +++ b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/InstrumentBranchesPhase.java @@ -25,14 +25,14 @@ package org.graalvm.compiler.truffle.compiler.phases; import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; +import org.graalvm.compiler.debug.MethodFilter; import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.graph.NodeSourcePosition; import org.graalvm.compiler.nodes.IfNode; import org.graalvm.compiler.nodes.StructuredGraph; -import org.graalvm.compiler.nodes.spi.CoreProviders; -import org.graalvm.options.OptionValues; import jdk.vm.ci.meta.JavaConstant; +import org.graalvm.compiler.truffle.compiler.TruffleTierContext; /** * Instruments {@link IfNode}s in the graph, by adding execution counters to the true and the false @@ -58,15 +58,16 @@ public class InstrumentBranchesPhase extends InstrumentPhase { private final boolean isInstrumentPerInlineSite; - public InstrumentBranchesPhase(OptionValues options, SnippetReflectionProvider snippetReflection, Instrumentation instrumentation, boolean instrumentPerInlineSite) { - super(options, snippetReflection, instrumentation); + public InstrumentBranchesPhase(SnippetReflectionProvider snippetReflection, Instrumentation instrumentation, boolean instrumentPerInlineSite) { + super(snippetReflection, instrumentation); isInstrumentPerInlineSite = instrumentPerInlineSite; } @Override - protected void instrumentGraph(StructuredGraph graph, CoreProviders context, JavaConstant tableConstant) { + protected void instrumentGraph(StructuredGraph graph, TruffleTierContext context, JavaConstant tableConstant) { + MethodFilter methodFilter = methodFilter(context); for (IfNode n : graph.getNodes(IfNode.TYPE)) { - Point p = getOrCreatePoint(n); + Point p = getOrCreatePoint(n, methodFilter); if (p != null) { insertCounter(graph, context, tableConstant, n.trueSuccessor(), p.slotIndex(0)); insertCounter(graph, context, tableConstant, n.falseSuccessor(), p.slotIndex(1)); diff --git a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/InstrumentPhase.java b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/InstrumentPhase.java index 4196d62d1632..0a40ae1d1eb2 100644 --- a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/InstrumentPhase.java +++ b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/InstrumentPhase.java @@ -53,8 +53,8 @@ import org.graalvm.compiler.nodes.calc.AddNode; import org.graalvm.compiler.nodes.java.LoadIndexedNode; import org.graalvm.compiler.nodes.java.StoreIndexedNode; -import org.graalvm.compiler.nodes.spi.CoreProviders; import org.graalvm.compiler.phases.BasePhase; +import org.graalvm.compiler.truffle.compiler.TruffleTierContext; import org.graalvm.compiler.truffle.options.PolyglotCompilerOptions; import org.graalvm.options.OptionValues; @@ -63,7 +63,7 @@ import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.MetaUtil; -public abstract class InstrumentPhase extends BasePhase { +public abstract class InstrumentPhase extends BasePhase { private static boolean checkMethodExists(String declaringClassName, String methodName) { try { @@ -91,16 +91,9 @@ private static String asStackPattern(String declaringClassName, String methodNam asStackPattern("org.graalvm.compiler.truffle.runtime.OptimizedDirectCallNode", "call"), }; private final Instrumentation instrumentation; - protected final MethodFilter methodFilter; protected final SnippetReflectionProvider snippetReflection; - public InstrumentPhase(OptionValues options, SnippetReflectionProvider snippetReflection, Instrumentation instrumentation) { - String filterValue = instrumentationFilter(options); - if (filterValue != null) { - methodFilter = MethodFilter.parse(filterValue); - } else { - methodFilter = MethodFilter.matchNothing(); - } + public InstrumentPhase(SnippetReflectionProvider snippetReflection, Instrumentation instrumentation) { this.snippetReflection = snippetReflection; this.instrumentation = instrumentation; } @@ -113,7 +106,7 @@ protected String instrumentationFilter(OptionValues options) { return options.get(PolyglotCompilerOptions.InstrumentFilter); } - protected static void insertCounter(StructuredGraph graph, CoreProviders context, JavaConstant tableConstant, + protected static void insertCounter(StructuredGraph graph, TruffleTierContext context, JavaConstant tableConstant, FixedWithNextNode targetNode, int slotIndex) { assert (tableConstant != null); TypeReference typeRef = TypeReference.createExactTrusted(context.getMetaAccess().lookupJavaType(tableConstant)); @@ -134,7 +127,7 @@ public float codeSizeIncrease() { } @Override - protected void run(StructuredGraph graph, CoreProviders context) { + protected void run(StructuredGraph graph, TruffleTierContext context) { JavaConstant tableConstant = snippetReflection.forObject(instrumentation.getAccessTable()); try { instrumentGraph(graph, context, tableConstant); @@ -143,7 +136,16 @@ protected void run(StructuredGraph graph, CoreProviders context) { } } - protected abstract void instrumentGraph(StructuredGraph graph, CoreProviders context, JavaConstant tableConstant); + protected MethodFilter methodFilter(TruffleTierContext context) { + String filterValue = instrumentationFilter(context.options); + if (filterValue != null) { + return MethodFilter.parse(filterValue); + } else { + return MethodFilter.matchNothing(); + } + } + + protected abstract void instrumentGraph(StructuredGraph graph, TruffleTierContext context, JavaConstant tableConstant); protected abstract int instrumentationPointSlotCount(); @@ -151,7 +153,7 @@ protected void run(StructuredGraph graph, CoreProviders context) { protected abstract Point createPoint(int id, int startIndex, Node n); - public Point getOrCreatePoint(Node n) { + public Point getOrCreatePoint(Node n, MethodFilter methodFilter) { Point point = instrumentation.getOrCreatePoint(methodFilter, n, this); assert point == null || point.slotCount() == instrumentationPointSlotCount() : "Slot count mismatch between instrumentation point and expected value."; return point; diff --git a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/InstrumentTruffleBoundariesPhase.java b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/InstrumentTruffleBoundariesPhase.java index db74ea71404c..f8f31fd5f234 100644 --- a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/InstrumentTruffleBoundariesPhase.java +++ b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/InstrumentTruffleBoundariesPhase.java @@ -25,16 +25,16 @@ package org.graalvm.compiler.truffle.compiler.phases; import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; +import org.graalvm.compiler.debug.MethodFilter; import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.graph.NodeSourcePosition; import org.graalvm.compiler.nodes.FixedWithNextNode; import org.graalvm.compiler.nodes.Invoke; import org.graalvm.compiler.nodes.StructuredGraph; -import org.graalvm.compiler.nodes.spi.CoreProviders; import org.graalvm.compiler.truffle.common.TruffleCompilerRuntime; -import org.graalvm.options.OptionValues; import jdk.vm.ci.meta.JavaConstant; +import org.graalvm.compiler.truffle.compiler.TruffleTierContext; /** * Instruments calls to {@code TruffleBoundary}-annotated methods in the graph, by adding execution @@ -66,17 +66,18 @@ public class InstrumentTruffleBoundariesPhase extends InstrumentPhase { private final boolean isInstrumentPerInlineSite; - public InstrumentTruffleBoundariesPhase(OptionValues options, SnippetReflectionProvider snippetReflection, Instrumentation instrumentation, boolean instrumentPerInlineSite) { - super(options, snippetReflection, instrumentation); + public InstrumentTruffleBoundariesPhase(SnippetReflectionProvider snippetReflection, Instrumentation instrumentation, boolean instrumentPerInlineSite) { + super(snippetReflection, instrumentation); isInstrumentPerInlineSite = instrumentPerInlineSite; } @Override - protected void instrumentGraph(StructuredGraph graph, CoreProviders context, JavaConstant tableConstant) { + protected void instrumentGraph(StructuredGraph graph, TruffleTierContext context, JavaConstant tableConstant) { TruffleCompilerRuntime runtime = TruffleCompilerRuntime.getRuntime(); + MethodFilter methodFilter = methodFilter(context); for (Node n : graph.getNodes()) { if (n instanceof Invoke && runtime.isTruffleBoundary(((Invoke) n).callTarget().targetMethod())) { - Point p = getOrCreatePoint(n); + Point p = getOrCreatePoint(n, methodFilter); if (p != null) { insertCounter(graph, context, tableConstant, (FixedWithNextNode) n.predecessor(), p.slotIndex(0)); } diff --git a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/InstrumentationSuite.java b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/InstrumentationSuite.java new file mode 100644 index 000000000000..7cac6eea53cd --- /dev/null +++ b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/InstrumentationSuite.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2015, 2020, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 org.graalvm.compiler.truffle.compiler.phases; + +import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; +import org.graalvm.compiler.phases.PhaseSuite; +import org.graalvm.compiler.truffle.compiler.TruffleTierContext; + +public class InstrumentationSuite extends PhaseSuite { + public InstrumentationSuite(InstrumentPhase.InstrumentationConfiguration instrumentationCfg, SnippetReflectionProvider snippetReflection, InstrumentPhase.Instrumentation instrumentation) { + if (instrumentationCfg.instrumentBranches) { + appendPhase(new InstrumentBranchesPhase(snippetReflection, instrumentation, instrumentationCfg.instrumentBranchesPerInlineSite)); + } + if (instrumentationCfg.instrumentBoundaries) { + appendPhase(new InstrumentTruffleBoundariesPhase(snippetReflection, instrumentation, instrumentationCfg.instrumentBoundariesPerInlineSite)); + } + } +} diff --git a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/MaterializeFramesPhase.java b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/MaterializeFramesPhase.java new file mode 100644 index 000000000000..1475dd86d35b --- /dev/null +++ b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/MaterializeFramesPhase.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2013, 2022, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 org.graalvm.compiler.truffle.compiler.phases; + +import org.graalvm.compiler.nodes.StructuredGraph; +import org.graalvm.compiler.phases.BasePhase; +import org.graalvm.compiler.truffle.compiler.TruffleTierContext; +import org.graalvm.compiler.truffle.compiler.nodes.frame.AllowMaterializeNode; + +public final class MaterializeFramesPhase extends BasePhase { + @Override + protected void run(StructuredGraph graph, TruffleTierContext context) { + graph.checkCancellation(); + for (AllowMaterializeNode materializeNode : graph.getNodes(AllowMaterializeNode.TYPE).snapshot()) { + materializeNode.replaceAtUsages(materializeNode.getFrame()); + graph.removeFixed(materializeNode); + } + } +} diff --git a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/NeverPartOfCompilationPhase.java b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/NeverPartOfCompilationPhase.java new file mode 100644 index 000000000000..6b19b592adef --- /dev/null +++ b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/NeverPartOfCompilationPhase.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013, 2022, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 org.graalvm.compiler.truffle.compiler.phases; + +import org.graalvm.compiler.core.common.GraalBailoutException; +import org.graalvm.compiler.nodes.StructuredGraph; +import org.graalvm.compiler.nodes.util.GraphUtil; +import org.graalvm.compiler.phases.BasePhase; +import org.graalvm.compiler.truffle.compiler.TruffleTierContext; +import org.graalvm.compiler.truffle.compiler.nodes.asserts.NeverPartOfCompilationNode; + +public final class NeverPartOfCompilationPhase extends BasePhase { + @Override + protected void run(StructuredGraph graph, TruffleTierContext context) { + graph.checkCancellation(); + for (NeverPartOfCompilationNode neverPartOfCompilationNode : graph.getNodes(NeverPartOfCompilationNode.TYPE)) { + final NeverPartOfCompilationException neverPartOfCompilationException = new NeverPartOfCompilationException(neverPartOfCompilationNode.getMessage()); + neverPartOfCompilationException.setStackTrace(GraphUtil.approxSourceStackTraceElement(neverPartOfCompilationNode)); + throw neverPartOfCompilationException; + } + } + + @SuppressWarnings("serial") + private static class NeverPartOfCompilationException extends GraalBailoutException { + + NeverPartOfCompilationException(String message) { + super(null, message, new Object[]{}); + } + + @Override + public boolean isCausedByCompilerAssert() { + return true; + } + } +} diff --git a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/ReportPerformanceWarningsPhase.java b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/ReportPerformanceWarningsPhase.java new file mode 100644 index 000000000000..a78a7726d163 --- /dev/null +++ b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/ReportPerformanceWarningsPhase.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013, 2022, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 org.graalvm.compiler.truffle.compiler.phases; + +import org.graalvm.compiler.nodes.StructuredGraph; +import org.graalvm.compiler.phases.BasePhase; +import org.graalvm.compiler.truffle.compiler.TruffleTierContext; + +public final class ReportPerformanceWarningsPhase extends BasePhase { + + @Override + protected void run(StructuredGraph graph, TruffleTierContext context) { + if (context.handler != null) { + context.handler.reportPerformanceWarnings(context.compilable, graph); + } + } +} diff --git a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/SetIdentityForValueTypesPhase.java b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/SetIdentityForValueTypesPhase.java new file mode 100644 index 000000000000..79207608c58f --- /dev/null +++ b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/SetIdentityForValueTypesPhase.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013, 2022, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 org.graalvm.compiler.truffle.compiler.phases; + +import org.graalvm.compiler.nodes.StructuredGraph; +import org.graalvm.compiler.nodes.virtual.VirtualInstanceNode; +import org.graalvm.compiler.nodes.virtual.VirtualObjectNode; +import org.graalvm.compiler.phases.BasePhase; +import org.graalvm.compiler.truffle.common.TruffleCompilerRuntime; + +import jdk.vm.ci.meta.ResolvedJavaType; +import org.graalvm.compiler.truffle.compiler.TruffleTierContext; + +public final class SetIdentityForValueTypesPhase extends BasePhase { + @Override + protected void run(StructuredGraph graph, TruffleTierContext context) { + graph.checkCancellation(); + TruffleCompilerRuntime rt = TruffleCompilerRuntime.getRuntime(); + for (VirtualObjectNode virtualObjectNode : graph.getNodes(VirtualObjectNode.TYPE)) { + if (virtualObjectNode instanceof VirtualInstanceNode) { + VirtualInstanceNode virtualInstanceNode = (VirtualInstanceNode) virtualObjectNode; + ResolvedJavaType type = virtualInstanceNode.type(); + if (rt.isValueType(type)) { + virtualInstanceNode.setIdentity(false); + } + } + } + } +} diff --git a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/TruffleTier.java b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/TruffleTier.java new file mode 100644 index 000000000000..c0a8f89d8f44 --- /dev/null +++ b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/TruffleTier.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013, 2022, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 org.graalvm.compiler.truffle.compiler.phases; + +import static org.graalvm.compiler.truffle.options.PolyglotCompilerOptions.InlineAcrossTruffleBoundary; + +import org.graalvm.compiler.core.phases.BaseTier; +import org.graalvm.compiler.truffle.compiler.PartialEvaluator; +import org.graalvm.compiler.truffle.compiler.PostPartialEvaluationSuite; +import org.graalvm.compiler.truffle.compiler.TruffleTierContext; +import org.graalvm.compiler.truffle.compiler.phases.inlining.AgnosticInliningPhase; +import org.graalvm.options.OptionValues; + +public class TruffleTier extends BaseTier { + + public TruffleTier(OptionValues options, PartialEvaluator partialEvaluator, InstrumentationSuite instrumentationSuite, PostPartialEvaluationSuite postPartialEvaluationSuite) { + appendPhase(new AgnosticInliningPhase(partialEvaluator, postPartialEvaluationSuite)); + appendPhase(instrumentationSuite); + appendPhase(new ReportPerformanceWarningsPhase()); + appendPhase(new VerifyFrameDoesNotEscapePhase()); + appendPhase(new NeverPartOfCompilationPhase()); + appendPhase(new MaterializeFramesPhase()); + appendPhase(new SetIdentityForValueTypesPhase()); + if (!options.get(InlineAcrossTruffleBoundary)) { + appendPhase(new InliningAcrossTruffleBoundaryPhase()); + } + } +} diff --git a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/VerifyFrameDoesNotEscapePhase.java b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/VerifyFrameDoesNotEscapePhase.java index b7f1f244d4da..2a28adfc7c87 100644 --- a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/VerifyFrameDoesNotEscapePhase.java +++ b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/VerifyFrameDoesNotEscapePhase.java @@ -28,17 +28,18 @@ import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.java.MethodCallTargetNode; import org.graalvm.compiler.nodes.util.GraphUtil; -import org.graalvm.compiler.phases.Phase; +import org.graalvm.compiler.phases.BasePhase; +import org.graalvm.compiler.truffle.compiler.TruffleTierContext; import org.graalvm.compiler.truffle.compiler.nodes.frame.NewFrameNode; /** * Compiler phase for verifying that the Truffle virtual frame does not escape and can therefore be * escape analyzed. */ -public class VerifyFrameDoesNotEscapePhase extends Phase { - +public class VerifyFrameDoesNotEscapePhase extends BasePhase { @Override - protected void run(StructuredGraph graph) { + protected void run(StructuredGraph graph, TruffleTierContext context) { + graph.checkCancellation(); for (NewFrameNode virtualFrame : graph.getNodes(NewFrameNode.TYPE)) { for (MethodCallTargetNode callTarget : virtualFrame.usages().filter(MethodCallTargetNode.class)) { if (callTarget.invoke() != null) { @@ -49,5 +50,6 @@ protected void run(StructuredGraph graph) { } } } + } } diff --git a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/inlining/AgnosticInliningPhase.java b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/inlining/AgnosticInliningPhase.java index e30d7779f7f3..2da1a7f6b456 100644 --- a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/inlining/AgnosticInliningPhase.java +++ b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/inlining/AgnosticInliningPhase.java @@ -29,13 +29,15 @@ import java.util.Objects; import org.graalvm.compiler.nodes.StructuredGraph; -import org.graalvm.compiler.nodes.spi.CoreProviders; -import org.graalvm.compiler.phases.SingleRunSubphase; +import org.graalvm.compiler.phases.BasePhase; +import org.graalvm.compiler.phases.util.GraphOrder; import org.graalvm.compiler.serviceprovider.GraalServices; import org.graalvm.compiler.truffle.compiler.PartialEvaluator; +import org.graalvm.compiler.truffle.compiler.PostPartialEvaluationSuite; +import org.graalvm.compiler.truffle.compiler.TruffleTierContext; import org.graalvm.compiler.truffle.options.PolyglotCompilerOptions; -public final class AgnosticInliningPhase extends SingleRunSubphase { +public final class AgnosticInliningPhase extends BasePhase { private static final ArrayList POLICY_PROVIDERS; @@ -50,12 +52,11 @@ public final class AgnosticInliningPhase extends SingleRunSubphase graphCacheForInlining; private final EconomicMap irCache = EconomicMap.create(); - private final PartialEvaluator.Request rootRequest; + private final TruffleTierContext rootContext; + private final PostPartialEvaluationSuite postPartialEvaluationSuite; - GraphManager(PartialEvaluator partialEvaluator, PartialEvaluator.Request rootRequest) { + GraphManager(PartialEvaluator partialEvaluator, PostPartialEvaluationSuite postPartialEvaluationSuite, TruffleTierContext rootContext) { this.partialEvaluator = partialEvaluator; - this.rootRequest = rootRequest; + this.postPartialEvaluationSuite = postPartialEvaluationSuite; + this.rootContext = rootContext; this.graphCacheForInlining = partialEvaluator.getOrCreateEncodedGraphCache(); } @@ -64,38 +68,40 @@ Entry pe(CompilableTruffleAST truffleAST) { Entry entry = irCache.get(truffleAST); if (entry == null) { final PEAgnosticInlineInvokePlugin plugin = newPlugin(); - final PartialEvaluator.Request request = newRequest(truffleAST, false); - request.graph.getAssumptions().record(new TruffleAssumption(truffleAST.getNodeRewritingAssumptionConstant())); - partialEvaluator.doGraphPE(request, plugin, graphCacheForInlining); - StructuredGraph graphAfterPE = copyGraphForDebugDump(request); - partialEvaluator.truffleTier(request); - entry = new Entry(request.graph, plugin, graphAfterPE); + final TruffleTierContext context = newContext(truffleAST, false); + context.graph.getAssumptions().record(new TruffleAssumption(truffleAST.getNodeRewritingAssumptionConstant())); + partialEvaluator.doGraphPE(context, plugin, graphCacheForInlining); + StructuredGraph graphAfterPE = copyGraphForDebugDump(context); + postPartialEvaluationSuite.apply(context.graph, context); + entry = new Entry(context.graph, plugin, graphAfterPE); irCache.put(truffleAST, entry); } return entry; } - private PartialEvaluator.Request newRequest(CompilableTruffleAST truffleAST, boolean finalize) { - return partialEvaluator.new Request( - rootRequest.options, - rootRequest.debug, + private TruffleTierContext newContext(CompilableTruffleAST truffleAST, boolean finalize) { + return new TruffleTierContext( + partialEvaluator, + rootContext.options, + rootContext.debug, truffleAST, finalize ? partialEvaluator.getCallDirect() : partialEvaluator.inlineRootForCallTarget(truffleAST), - rootRequest.compilationId, - rootRequest.log, - rootRequest.task); + rootContext.compilationId, + rootContext.log, + rootContext.task, + rootContext.handler); } private PEAgnosticInlineInvokePlugin newPlugin() { - return new PEAgnosticInlineInvokePlugin(rootRequest.task.inliningData(), partialEvaluator); + return new PEAgnosticInlineInvokePlugin(rootContext.task.inliningData(), partialEvaluator); } Entry peRoot() { final PEAgnosticInlineInvokePlugin plugin = newPlugin(); - partialEvaluator.doGraphPE(rootRequest, plugin, graphCacheForInlining); - StructuredGraph graphAfterPE = copyGraphForDebugDump(rootRequest); - partialEvaluator.truffleTier(rootRequest); - return new Entry(rootRequest.graph, plugin, graphAfterPE); + partialEvaluator.doGraphPE(rootContext, plugin, graphCacheForInlining); + StructuredGraph graphAfterPE = copyGraphForDebugDump(rootContext); + postPartialEvaluationSuite.apply(rootContext.graph, rootContext); + return new Entry(rootContext.graph, plugin, graphAfterPE); } UnmodifiableEconomicMap doInline(Invoke invoke, StructuredGraph ir, CompilableTruffleAST truffleAST, InliningUtil.InlineeReturnAction returnAction) { @@ -104,19 +110,19 @@ UnmodifiableEconomicMap doInline(Invoke invoke, StructuredGraph ir, } void finalizeGraph(Invoke invoke, CompilableTruffleAST truffleAST) { - final PartialEvaluator.Request request = newRequest(truffleAST, true); - partialEvaluator.doGraphPE(request, new InlineInvokePlugin() { + final TruffleTierContext context = newContext(truffleAST, true); + partialEvaluator.doGraphPE(context, new InlineInvokePlugin() { @Override public InlineInfo shouldInlineInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) { return PartialEvaluator.asInlineInfo(method); } }, graphCacheForInlining); - InliningUtil.inline(invoke, request.graph, true, partialEvaluator.getCallInlined(), "finalization", AgnosticInliningPhase.class.getName()); + InliningUtil.inline(invoke, context.graph, true, partialEvaluator.getCallInlined(), "finalization", AgnosticInliningPhase.class.getName()); } - private static StructuredGraph copyGraphForDebugDump(PartialEvaluator.Request request) { - if (request.debug.isDumpEnabled(DebugContext.INFO_LEVEL)) { - return (StructuredGraph) request.graph.copy(request.debug); + private static StructuredGraph copyGraphForDebugDump(TruffleTierContext context) { + if (context.debug.isDumpEnabled(DebugContext.INFO_LEVEL)) { + return (StructuredGraph) context.graph.copy(context.debug); } return null; } diff --git a/compiler/src/org.graalvm.compiler.truffle.test/src/org/graalvm/compiler/truffle/test/AgnosticInliningPhaseTest.java b/compiler/src/org.graalvm.compiler.truffle.test/src/org/graalvm/compiler/truffle/test/AgnosticInliningPhaseTest.java index e76011760c60..74410ec45b46 100644 --- a/compiler/src/org.graalvm.compiler.truffle.test/src/org/graalvm/compiler/truffle/test/AgnosticInliningPhaseTest.java +++ b/compiler/src/org.graalvm.compiler.truffle.test/src/org/graalvm/compiler/truffle/test/AgnosticInliningPhaseTest.java @@ -30,6 +30,8 @@ import org.graalvm.compiler.truffle.common.TruffleInliningData; import org.graalvm.compiler.truffle.compiler.PartialEvaluator; import org.graalvm.compiler.truffle.compiler.TruffleCompilerImpl; +import org.graalvm.compiler.truffle.compiler.PostPartialEvaluationSuite; +import org.graalvm.compiler.truffle.compiler.TruffleTierContext; import org.graalvm.compiler.truffle.compiler.phases.inlining.AgnosticInliningPhase; import org.graalvm.compiler.truffle.runtime.OptimizedCallTarget; import org.graalvm.compiler.truffle.runtime.OptimizedDirectCallNode; @@ -61,7 +63,7 @@ public String toString(Verbosity verbosity) { return ""; } }; - final PartialEvaluator.Request request = partialEvaluator.new Request(callTarget.getOptionValues(), getDebugContext(), callTarget, partialEvaluator.rootForCallTarget(callTarget), + final TruffleTierContext context = new TruffleTierContext(partialEvaluator, callTarget.getOptionValues(), getDebugContext(), callTarget, partialEvaluator.rootForCallTarget(callTarget), compilationIdentifier, getSpeculationLog(), new TruffleCompilerImpl.CancellableTruffleCompilationTask(new TruffleCompilationTask() { private TruffleInliningData inlining = new TruffleInlining(); @@ -85,10 +87,10 @@ public TruffleInliningData inliningData() { public boolean hasNextTier() { return false; } - })); - final AgnosticInliningPhase agnosticInliningPhase = new AgnosticInliningPhase(partialEvaluator, request); - agnosticInliningPhase.apply(request.graph, getTruffleCompiler(callTarget).getPartialEvaluator().getProviders()); - return request.graph; + }), null); + final AgnosticInliningPhase agnosticInliningPhase = new AgnosticInliningPhase(partialEvaluator, new PostPartialEvaluationSuite(false)); + agnosticInliningPhase.apply(context.graph, context); + return context.graph; } protected static final OptimizedCallTarget createDummyNode() { diff --git a/compiler/src/org.graalvm.compiler.truffle.test/src/org/graalvm/compiler/truffle/test/PartialEvaluationTest.java b/compiler/src/org.graalvm.compiler.truffle.test/src/org/graalvm/compiler/truffle/test/PartialEvaluationTest.java index df1c7005e073..1fc6dc43331f 100644 --- a/compiler/src/org.graalvm.compiler.truffle.test/src/org/graalvm/compiler/truffle/test/PartialEvaluationTest.java +++ b/compiler/src/org.graalvm.compiler.truffle.test/src/org/graalvm/compiler/truffle/test/PartialEvaluationTest.java @@ -48,7 +48,10 @@ import org.graalvm.compiler.truffle.common.TruffleDebugJavaMethod; import org.graalvm.compiler.truffle.common.TruffleInliningData; import org.graalvm.compiler.truffle.compiler.PartialEvaluator; +import org.graalvm.compiler.truffle.compiler.PerformanceInformationHandler; import org.graalvm.compiler.truffle.compiler.TruffleCompilerImpl; +import org.graalvm.compiler.truffle.compiler.TruffleTierContext; +import org.graalvm.compiler.truffle.compiler.phases.TruffleTier; import org.graalvm.compiler.truffle.runtime.OptimizedCallTarget; import org.graalvm.compiler.truffle.runtime.TruffleInlining; import org.junit.Assert; @@ -245,12 +248,18 @@ private StructuredGraph partialEval(OptimizedCallTarget compilable, Object[] arg if (!compilable.wasExecuted()) { compilable.prepareForAOT(); } - final PartialEvaluator partialEvaluator = getTruffleCompiler(compilable).getPartialEvaluator(); - final PartialEvaluator.Request request = partialEvaluator.new Request(compilable.getOptionValues(), debug, compilable, partialEvaluator.rootForCallTarget(compilable), - compilationId, speculationLog, - new TruffleCompilerImpl.CancellableTruffleCompilationTask(newTask())); - try (Graph.NodeEventScope nes = nodeEventListener == null ? null : request.graph.trackNodeEvents(nodeEventListener)) { - return partialEvaluator.evaluate(request); + TruffleCompilerImpl truffleCompiler = getTruffleCompiler(compilable); + TruffleTier truffleTier = truffleCompiler.getTruffleTier(); + final PartialEvaluator partialEvaluator = truffleCompiler.getPartialEvaluator(); + try (PerformanceInformationHandler handler = PerformanceInformationHandler.install(compilable.getOptionValues())) { + final TruffleTierContext context = new TruffleTierContext(partialEvaluator, compilable.getOptionValues(), debug, compilable, partialEvaluator.rootForCallTarget(compilable), + compilationId, speculationLog, + new TruffleCompilerImpl.CancellableTruffleCompilationTask(newTask()), + handler); + try (Graph.NodeEventScope nes = nodeEventListener == null ? null : context.graph.trackNodeEvents(nodeEventListener)) { + truffleTier.apply(context.graph, context); + return context.graph; + } } } catch (Throwable e) { throw debug.handle(e); diff --git a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/TruffleSupport.java b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/TruffleSupport.java index facbaae9f198..3ad044551c1c 100644 --- a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/TruffleSupport.java +++ b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/TruffleSupport.java @@ -87,14 +87,14 @@ public void registerInterpreterEntryMethodsAsCompiled(PartialEvaluator partialEv } public SubstrateTruffleCompiler createTruffleCompiler(SubstrateTruffleRuntime runtime) { - SubstrateTruffleCompiler compiler = createSubstrateTruffleCompilerImpl(runtime, "community"); + SubstrateTruffleCompiler compiler = new SubstrateTruffleCompilerImpl(createSubstrateTruffleCompilerConfig(runtime, "community")); if (SubstrateOptions.supportCompileInIsolates()) { compiler = new IsolateAwareTruffleCompiler(compiler); } return compiler; } - protected static SubstrateTruffleCompiler createSubstrateTruffleCompilerImpl(SubstrateTruffleRuntime runtime, String compilerConfigurationName) { + protected static TruffleCompilerConfiguration createSubstrateTruffleCompilerConfig(SubstrateTruffleRuntime runtime, String compilerConfigurationName) { GraalFeature graalFeature = ImageSingletons.lookup(GraalFeature.class); SnippetReflectionProvider snippetReflectionProvider = graalFeature.getHostedProviders().getSnippetReflection(); final GraphBuilderConfiguration.Plugins graphBuilderPlugins = graalFeature.getHostedProviders().getGraphBuilderPlugins(); @@ -104,9 +104,7 @@ protected static SubstrateTruffleCompiler createSubstrateTruffleCompilerImpl(Sub PartialEvaluatorConfiguration peConfig = TruffleCompilerImpl.createPartialEvaluatorConfiguration(compilerConfigurationName); final TruffleTierConfiguration lastTier = new TruffleTierConfiguration(peConfig, GraalSupport.getRuntimeConfig().getBackendForNormalMethod(), GraalSupport.getRuntimeConfig().getProviders(), GraalSupport.getSuites(), GraalSupport.getLIRSuites()); - final TruffleCompilerConfiguration truffleCompilerConfig = new TruffleCompilerConfiguration(runtime, graphBuilderPlugins, snippetReflectionProvider, firstTier, lastTier); - - return new SubstrateTruffleCompilerImpl(truffleCompilerConfig); + return new TruffleCompilerConfiguration(runtime, graphBuilderPlugins, snippetReflectionProvider, firstTier, lastTier); } public static boolean isIsolatedCompilation() { diff --git a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/api/SubstratePartialEvaluator.java b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/api/SubstratePartialEvaluator.java index ed2f4294b862..a25e4eb1d36e 100644 --- a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/api/SubstratePartialEvaluator.java +++ b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/api/SubstratePartialEvaluator.java @@ -34,7 +34,6 @@ import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin; import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins; -import org.graalvm.compiler.nodes.graphbuilderconf.LoopExplosionPlugin; import org.graalvm.compiler.nodes.graphbuilderconf.NodePlugin; import org.graalvm.compiler.nodes.graphbuilderconf.ParameterPlugin; import org.graalvm.compiler.phases.util.Providers; @@ -43,11 +42,10 @@ import org.graalvm.compiler.truffle.compiler.PartialEvaluator; import org.graalvm.compiler.truffle.compiler.PartialEvaluatorConfiguration; import org.graalvm.compiler.truffle.compiler.TruffleCompilerConfiguration; +import org.graalvm.compiler.truffle.compiler.TruffleTierContext; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; -import com.oracle.svm.core.graal.phases.DeadStoreRemovalPhase; - import jdk.vm.ci.meta.ResolvedJavaMethod; public class SubstratePartialEvaluator extends PartialEvaluator { @@ -63,13 +61,10 @@ public SubstratePartialEvaluator(TruffleCompilerConfiguration config, GraphBuild } @Override - protected PEGraphDecoder createGraphDecoder(Request request, LoopExplosionPlugin loopExplosionPlugin, - InvocationPlugins invocationPlugins, - InlineInvokePlugin[] inlineInvokePlugins, ParameterPlugin parameterPlugin, NodePlugin[] nodePlugins, SourceLanguagePositionProvider sourceLanguagePositionProvider, - EconomicMap graphCache) { - return new SubstratePEGraphDecoder(architecture, request.graph, providers.copyWith(compilationLocalConstantProvider), loopExplosionPlugin, invocationPlugins, inlineInvokePlugins, - parameterPlugin, nodePlugins, callInlined, sourceLanguagePositionProvider, - specialCallTargetCache, invocationPluginsCache); + protected PEGraphDecoder createGraphDecoder(TruffleTierContext context, InvocationPlugins invocationPlugins, InlineInvokePlugin[] inlineInvokePlugins, ParameterPlugin parameterPlugin, + NodePlugin[] nodePlugins, SourceLanguagePositionProvider sourceLanguagePositionProvider, EconomicMap graphCache) { + return new SubstratePEGraphDecoder(config.architecture(), context.graph, config.lastTier().providers().copyWith(compilationLocalConstantProvider), loopExplosionPlugin, invocationPlugins, + inlineInvokePlugins, parameterPlugin, nodePlugins, callInlined, sourceLanguagePositionProvider, specialCallTargetCache, invocationPluginsCache); } @Override @@ -82,13 +77,6 @@ protected StructuredGraph.Builder customizeStructuredGraphBuilder(StructuredGrap return super.customizeStructuredGraphBuilder(builder).recordInlinedMethods(false); } - @Override - public void truffleTier(Request request) { - super.truffleTier(request); - new DeadStoreRemovalPhase().apply(request.graph); - new TruffleBoundaryPhase().apply(request.graph); - } - @Override protected void registerGraphBuilderInvocationPlugins(InvocationPlugins invocationPlugins, boolean canDelayIntrinsification) { super.registerGraphBuilderInvocationPlugins(invocationPlugins, canDelayIntrinsification); @@ -100,7 +88,7 @@ protected void registerGraphBuilderInvocationPlugins(InvocationPlugins invocatio protected InvocationPlugins createDecodingInvocationPlugins(PartialEvaluatorConfiguration peConfig, Plugins parent, Providers tierProviders) { InvocationPlugins decodingInvocationPlugins = new InvocationPlugins(); registerGraphBuilderInvocationPlugins(decodingInvocationPlugins, false); - peConfig.registerDecodingInvocationPlugins(decodingInvocationPlugins, false, providers, config.architecture()); + peConfig.registerDecodingInvocationPlugins(decodingInvocationPlugins, false, config.lastTier().providers(), config.architecture()); decodingInvocationPlugins.closeRegistration(); return decodingInvocationPlugins; } @@ -109,4 +97,5 @@ protected InvocationPlugins createDecodingInvocationPlugins(PartialEvaluatorConf protected NodePlugin[] createNodePlugins(Plugins plugins) { return null; } + } diff --git a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/api/SubstratePostPartialEvaluationSuite.java b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/api/SubstratePostPartialEvaluationSuite.java new file mode 100644 index 000000000000..959181053826 --- /dev/null +++ b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/api/SubstratePostPartialEvaluationSuite.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2013, 2022, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.svm.truffle.api; + +import org.graalvm.compiler.truffle.compiler.PostPartialEvaluationSuite; + +import com.oracle.svm.core.graal.phases.DeadStoreRemovalPhase; + +public class SubstratePostPartialEvaluationSuite extends PostPartialEvaluationSuite { + + public SubstratePostPartialEvaluationSuite(boolean iterativePartialEscape) { + super(iterativePartialEscape); + appendPhase(new DeadStoreRemovalPhase()); + appendPhase(new TruffleBoundaryPhase()); + } +} diff --git a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/api/SubstrateTruffleCompiler.java b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/api/SubstrateTruffleCompiler.java index d4d85f1969e8..7a26b42724c4 100644 --- a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/api/SubstrateTruffleCompiler.java +++ b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/api/SubstrateTruffleCompiler.java @@ -26,6 +26,7 @@ import org.graalvm.compiler.truffle.compiler.PartialEvaluator; import org.graalvm.compiler.truffle.compiler.TruffleCompilerBase; +import org.graalvm.compiler.truffle.compiler.phases.TruffleTier; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; @@ -35,6 +36,10 @@ public interface SubstrateTruffleCompiler extends TruffleCompilerBase { @Platforms(Platform.HOSTED_ONLY.class) PartialEvaluator getPartialEvaluator(); + @Override + @Platforms(Platform.HOSTED_ONLY.class) + TruffleTier getTruffleTier(); + /** * Called on tear-down of the current isolate. */ diff --git a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/api/SubstrateTruffleCompilerImpl.java b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/api/SubstrateTruffleCompilerImpl.java index a147fd13694a..1c9656cb54cd 100644 --- a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/api/SubstrateTruffleCompilerImpl.java +++ b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/api/SubstrateTruffleCompilerImpl.java @@ -24,6 +24,8 @@ */ package com.oracle.svm.truffle.api; +import static org.graalvm.compiler.truffle.options.PolyglotCompilerOptions.IterativePartialEscape; + import java.io.PrintStream; import java.util.Map; @@ -42,6 +44,8 @@ import org.graalvm.compiler.truffle.compiler.TruffleCompilerConfiguration; import org.graalvm.compiler.truffle.compiler.TruffleCompilerImpl; import org.graalvm.compiler.truffle.compiler.TruffleTierConfiguration; +import org.graalvm.compiler.truffle.compiler.phases.InstrumentationSuite; +import org.graalvm.compiler.truffle.compiler.phases.TruffleTier; import org.graalvm.compiler.truffle.runtime.OptimizedCallTarget; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; @@ -79,6 +83,13 @@ public void initialize(Map optionsMap, CompilableTruffleAST comp } } + @Override + protected TruffleTier newTruffleTier(org.graalvm.options.OptionValues options) { + return new TruffleTier(options, partialEvaluator, + new InstrumentationSuite(partialEvaluator.instrumentationCfg, config.snippetReflection(), partialEvaluator.getInstrumentation()), + new SubstratePostPartialEvaluationSuite(options.get(IterativePartialEscape))); + } + @Override public PhaseSuite createGraphBuilderSuite(TruffleTierConfiguration tier) { return null; diff --git a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/isolated/IsolateAwareTruffleCompiler.java b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/isolated/IsolateAwareTruffleCompiler.java index 48223611dc88..1dc570e73748 100644 --- a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/isolated/IsolateAwareTruffleCompiler.java +++ b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/isolated/IsolateAwareTruffleCompiler.java @@ -30,7 +30,6 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; -import com.oracle.svm.core.heap.Heap; import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; import org.graalvm.compiler.core.common.SuppressFBWarnings; import org.graalvm.compiler.nodes.PauseNode; @@ -41,6 +40,7 @@ import org.graalvm.compiler.truffle.common.TruffleDebugContext; import org.graalvm.compiler.truffle.compiler.PartialEvaluator; import org.graalvm.compiler.truffle.compiler.TruffleCompilationIdentifier; +import org.graalvm.compiler.truffle.compiler.phases.TruffleTier; import org.graalvm.compiler.word.Word; import org.graalvm.nativeimage.CurrentIsolate; import org.graalvm.nativeimage.Isolate; @@ -58,6 +58,7 @@ import com.oracle.svm.core.SubstrateOptions; import com.oracle.svm.core.c.function.CEntryPointOptions; +import com.oracle.svm.core.heap.Heap; import com.oracle.svm.core.jdk.UninterruptibleUtils; import com.oracle.svm.graal.isolated.ClientHandle; import com.oracle.svm.graal.isolated.ClientIsolateThread; @@ -282,6 +283,12 @@ public PartialEvaluator getPartialEvaluator() { return delegate.getPartialEvaluator(); } + @Platforms(Platform.HOSTED_ONLY.class) + @Override + public TruffleTier getTruffleTier() { + return delegate.getTruffleTier(); + } + @Override public SnippetReflectionProvider getSnippetReflection() { return delegate.getSnippetReflection();