Search in sources :

Example 66 with CanonicalizerPhase

use of org.graalvm.compiler.phases.common.CanonicalizerPhase in project graal by oracle.

the class MacroNode method lowerReplacement.

/**
 * Applies {@linkplain LoweringPhase lowering} to a replacement graph.
 *
 * @param replacementGraph a replacement (i.e., snippet or method substitution) graph
 */
@SuppressWarnings("try")
protected StructuredGraph lowerReplacement(final StructuredGraph replacementGraph, LoweringTool tool) {
    final PhaseContext c = new PhaseContext(tool.getMetaAccess(), tool.getConstantReflection(), tool.getConstantFieldProvider(), tool.getLowerer(), tool.getReplacements(), tool.getStampProvider());
    if (!graph().hasValueProxies()) {
        new RemoveValueProxyPhase().apply(replacementGraph);
    }
    GuardsStage guardsStage = graph().getGuardsStage();
    if (!guardsStage.allowsFloatingGuards()) {
        new GuardLoweringPhase().apply(replacementGraph, null);
        if (guardsStage.areFrameStatesAtDeopts()) {
            new FrameStateAssignmentPhase().apply(replacementGraph);
        }
    }
    DebugContext debug = replacementGraph.getDebug();
    try (DebugContext.Scope s = debug.scope("LoweringSnippetTemplate", replacementGraph)) {
        new LoweringPhase(new CanonicalizerPhase(), tool.getLoweringStage()).apply(replacementGraph, c);
    } catch (Throwable e) {
        throw debug.handle(e);
    }
    return replacementGraph;
}
Also used : PhaseContext(org.graalvm.compiler.phases.tiers.PhaseContext) FrameStateAssignmentPhase(org.graalvm.compiler.phases.common.FrameStateAssignmentPhase) RemoveValueProxyPhase(org.graalvm.compiler.phases.common.RemoveValueProxyPhase) GuardsStage(org.graalvm.compiler.nodes.StructuredGraph.GuardsStage) GuardLoweringPhase(org.graalvm.compiler.phases.common.GuardLoweringPhase) LoweringPhase(org.graalvm.compiler.phases.common.LoweringPhase) CanonicalizerPhase(org.graalvm.compiler.phases.common.CanonicalizerPhase) DebugContext(org.graalvm.compiler.debug.DebugContext) GuardLoweringPhase(org.graalvm.compiler.phases.common.GuardLoweringPhase)

Example 67 with CanonicalizerPhase

use of org.graalvm.compiler.phases.common.CanonicalizerPhase in project graal by oracle.

the class CompileQueue method doInlineTrivial.

@SuppressWarnings("try")
private void doInlineTrivial(DebugContext debug, final HostedMethod method) {
    /*
         * Make a copy of the graph to avoid concurrency problems. Graph manipulations are not
         * thread safe, and another thread can concurrently inline this method.
         */
    final StructuredGraph graph = (StructuredGraph) method.compilationInfo.getGraph().copy(debug);
    try (DebugContext.Scope s = debug.scope("InlineTrivial", graph, method, this)) {
        try {
            try (Indent in = debug.logAndIndent("do inline trivial in %s", method)) {
                boolean inlined = false;
                for (Invoke invoke : graph.getInvokes()) {
                    if (invoke.useForInlining()) {
                        inlined |= tryInlineTrivial(graph, invoke, !inlined);
                    }
                }
                if (inlined) {
                    Providers providers = runtimeConfig.lookupBackend(method).getProviders();
                    new CanonicalizerPhase().apply(graph, new PhaseContext(providers));
                    /*
                         * Publish the new graph, it can be picked up immediately by other threads
                         * trying to inline this method.
                         */
                    method.compilationInfo.setGraph(graph);
                    checkTrivial(method);
                    inliningProgress = true;
                }
            }
        } catch (Throwable ex) {
            GraalError error = ex instanceof GraalError ? (GraalError) ex : new GraalError(ex);
            error.addContext("method: " + method.format("%r %H.%n(%p)"));
            throw error;
        }
    } catch (Throwable e) {
        throw debug.handle(e);
    }
}
Also used : PhaseContext(org.graalvm.compiler.phases.tiers.PhaseContext) Indent(org.graalvm.compiler.debug.Indent) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) GraalError(org.graalvm.compiler.debug.GraalError) CanonicalizerPhase(org.graalvm.compiler.phases.common.CanonicalizerPhase) DebugContext(org.graalvm.compiler.debug.DebugContext) HostedProviders(com.oracle.graal.pointsto.meta.HostedProviders) Providers(org.graalvm.compiler.phases.util.Providers) Invoke(org.graalvm.compiler.nodes.Invoke)

Example 68 with CanonicalizerPhase

use of org.graalvm.compiler.phases.common.CanonicalizerPhase in project graal by oracle.

the class MethodTypeFlowBuilder method parse.

@SuppressWarnings("try")
private boolean parse() {
    OptionValues options = bb.getOptions();
    DebugContext debug = DebugContext.create(options, new GraalDebugHandlersFactory(bb.getProviders().getSnippetReflection()));
    try (Indent indent = debug.logAndIndent("parse graph %s", method)) {
        boolean needParsing = false;
        graph = method.buildGraph(debug, method, bb.getProviders(), Purpose.ANALYSIS);
        if (graph == null) {
            InvocationPlugin plugin = bb.getProviders().getGraphBuilderPlugins().getInvocationPlugins().lookupInvocation(method);
            if (plugin != null && !plugin.inlineOnly()) {
                Bytecode code = new ResolvedJavaMethodBytecode(method);
                graph = new SubstrateIntrinsicGraphBuilder(options, debug, bb.getProviders().getMetaAccess(), bb.getProviders().getConstantReflection(), bb.getProviders().getConstantFieldProvider(), bb.getProviders().getStampProvider(), code).buildGraph(plugin);
            }
        }
        if (graph == null) {
            if (!method.hasBytecodes()) {
                return false;
            }
            needParsing = true;
            graph = new StructuredGraph.Builder(options, debug).method(method).build();
        }
        try (DebugContext.Scope s = debug.scope("ClosedWorldAnalysis", graph, method, this)) {
            // enable this logging to get log output in compilation passes
            try (Indent indent2 = debug.logAndIndent("parse graph phases")) {
                if (needParsing) {
                    GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault(bb.getProviders().getGraphBuilderPlugins()).withEagerResolving(true).withUnresolvedIsError(PointstoOptions.UnresolvedIsError.getValue(bb.getOptions())).withNodeSourcePosition(true).withBytecodeExceptionMode(BytecodeExceptionMode.CheckAll);
                    bb.getHostVM().createGraphBuilderPhase(bb.getProviders(), config, OptimisticOptimizations.NONE, null).apply(graph);
                }
            } catch (PermanentBailoutException ex) {
                bb.getUnsupportedFeatures().addMessage(method.format("%H.%n(%p)"), method, ex.getLocalizedMessage(), null, ex);
                return false;
            }
            // Register used types and fields before canonicalization can optimize them.
            registerUsedElements(bb, graph, methodFlow);
            new CanonicalizerPhase().apply(graph, new PhaseContext(bb.getProviders()));
            // Do it again after canonicalization changed type checks and field accesses.
            registerUsedElements(bb, graph, methodFlow);
        } catch (Throwable e) {
            throw debug.handle(e);
        }
    }
    return true;
}
Also used : Indent(org.graalvm.compiler.debug.Indent) OptionValues(org.graalvm.compiler.options.OptionValues) SubstrateIntrinsicGraphBuilder(com.oracle.graal.pointsto.phases.SubstrateIntrinsicGraphBuilder) GraphBuilderConfiguration(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration) DebugContext(org.graalvm.compiler.debug.DebugContext) GraalDebugHandlersFactory(org.graalvm.compiler.printer.GraalDebugHandlersFactory) PhaseContext(org.graalvm.compiler.phases.tiers.PhaseContext) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) InvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin) ResolvedJavaMethodBytecode(org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecode) Bytecode(org.graalvm.compiler.bytecode.Bytecode) CanonicalizerPhase(org.graalvm.compiler.phases.common.CanonicalizerPhase) ResolvedJavaMethodBytecode(org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecode) PermanentBailoutException(org.graalvm.compiler.core.common.PermanentBailoutException)

Example 69 with CanonicalizerPhase

use of org.graalvm.compiler.phases.common.CanonicalizerPhase in project graal by oracle.

the class RuntimeStrengthenStampsPhase method processMethod.

@SuppressWarnings("try")
private void processMethod(CallTreeNode node, Deque<CallTreeNode> worklist, BigBang bb) {
    AnalysisMethod method = node.implementationMethod;
    assert method.isImplementationInvoked();
    if (node.graph == null) {
        if (method.getAnnotation(Fold.class) != null || method.getAnnotation(NodeIntrinsic.class) != null) {
            VMError.shouldNotReachHere("Parsing method annotated with @Fold or @NodeIntrinsic: " + method.format("%H.%n(%p)"));
        }
        boolean parse = false;
        DebugContext debug = bb.getDebug();
        StructuredGraph graph = method.buildGraph(debug, method, hostedProviders, Purpose.PREPARE_RUNTIME_COMPILATION);
        if (graph == null) {
            if (!method.hasBytecodes()) {
                return;
            }
            parse = true;
            graph = new StructuredGraph.Builder(debug.getOptions(), debug, AllowAssumptions.YES).method(method).build();
        }
        try (DebugContext.Scope scope = debug.scope("RuntimeCompile", graph)) {
            if (parse) {
                RuntimeGraphBuilderPhase builderPhase = new RuntimeGraphBuilderPhase(hostedProviders.getMetaAccess(), hostedProviders.getStampProvider(), hostedProviders.getConstantReflection(), hostedProviders.getConstantFieldProvider(), graphBuilderConfig, optimisticOpts, null, hostedProviders.getWordTypes(), deoptimizeOnExceptionPredicate, node);
                builderPhase.apply(graph);
            }
            if (graph.getNodes(StackValueNode.TYPE).isNotEmpty()) {
                /*
                     * Stack allocated memory is not seen by the deoptimization code, i.e., it is
                     * not copied in case of deoptimization. Also, pointers to it can be used for
                     * arbitrary address arithmetic, so we would not know how to update derived
                     * pointers into stack memory during deoptimization. Therefore, we cannot allow
                     * methods that allocate stack memory for runtime compilation. To remove this
                     * limitation, we would need to change how we handle stack allocated memory in
                     * Graal.
                     */
                return;
            }
            PhaseContext phaseContext = new PhaseContext(hostedProviders);
            new CanonicalizerPhase().apply(graph, phaseContext);
            new ConvertDeoptimizeToGuardPhase().apply(graph, phaseContext);
            graphEncoder.prepare(graph);
            node.graph = graph;
        } catch (Throwable ex) {
            debug.handle(ex);
        }
    }
    assert node.graph != null;
    List<MethodCallTargetNode> callTargets = node.graph.getNodes(MethodCallTargetNode.TYPE).snapshot();
    callTargets.sort((t1, t2) -> Integer.compare(t1.invoke().bci(), t2.invoke().bci()));
    for (MethodCallTargetNode targetNode : callTargets) {
        AnalysisMethod targetMethod = (AnalysisMethod) targetNode.targetMethod();
        AnalysisMethod callerMethod = (AnalysisMethod) targetNode.invoke().stateAfter().getMethod();
        InvokeTypeFlow invokeFlow = callerMethod.getTypeFlow().getOriginalMethodFlows().getInvoke(targetNode.invoke().bci());
        if (invokeFlow == null) {
            continue;
        }
        Collection<AnalysisMethod> allImplementationMethods = invokeFlow.getCallees();
        /*
             * Eventually we want to remove all invokes that are unreachable, i.e., have no
             * implementation. But the analysis is iterative, and we don't know here if we have
             * already reached the fixed point. So we only collect unreachable invokes here, and
             * remove them after the analysis has finished.
             */
        if (allImplementationMethods.size() == 0) {
            node.unreachableInvokes.add(targetNode.invoke());
        } else {
            node.unreachableInvokes.remove(targetNode.invoke());
        }
        List<AnalysisMethod> implementationMethods = new ArrayList<>();
        for (AnalysisMethod implementationMethod : allImplementationMethods) {
            /* Filter out all the implementation methods that have already been processed. */
            if (!methods.containsKey(implementationMethod)) {
                implementationMethods.add(implementationMethod);
            }
        }
        if (implementationMethods.size() > 0) {
            /* Sort to make printing order and method discovery order deterministic. */
            implementationMethods.sort((m1, m2) -> m1.format("%H.%n(%p)").compareTo(m2.format("%H.%n(%p)")));
            String sourceReference = buildSourceReference(targetNode.invoke().stateAfter());
            for (AnalysisMethod implementationMethod : implementationMethods) {
                CallTreeNode calleeNode = new CallTreeNode(implementationMethod, targetMethod, node, node.level + 1, sourceReference);
                if (includeCalleePredicate.includeCallee(calleeNode, implementationMethods)) {
                    assert !methods.containsKey(implementationMethod);
                    methods.put(implementationMethod, calleeNode);
                    worklist.add(calleeNode);
                    node.children.add(calleeNode);
                    objectReplacer.createMethod(implementationMethod);
                }
                /*
                     * We must compile all methods which may be called. It may be the case that a
                     * call target does not reach the compile queue by default, e.g. if it is
                     * inlined at image generation but not at runtime compilation.
                     */
                CompilationInfoSupport.singleton().registerForcedCompilation(implementationMethod);
            }
        }
    }
}
Also used : ArrayList(java.util.ArrayList) DebugContext(org.graalvm.compiler.debug.DebugContext) InvokeTypeFlow(com.oracle.graal.pointsto.flow.InvokeTypeFlow) ConvertDeoptimizeToGuardPhase(org.graalvm.compiler.phases.common.ConvertDeoptimizeToGuardPhase) PhaseContext(org.graalvm.compiler.phases.tiers.PhaseContext) AnalysisMethod(com.oracle.graal.pointsto.meta.AnalysisMethod) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) CanonicalizerPhase(org.graalvm.compiler.phases.common.CanonicalizerPhase)

Example 70 with CanonicalizerPhase

use of org.graalvm.compiler.phases.common.CanonicalizerPhase in project graal by oracle.

the class CompareCanonicalizerTest method getCanonicalizedGraph.

private StructuredGraph getCanonicalizedGraph(String name) {
    StructuredGraph graph = parseEager(name, AllowAssumptions.YES);
    new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
    return graph;
}
Also used : PhaseContext(org.graalvm.compiler.phases.tiers.PhaseContext) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) CanonicalizerPhase(org.graalvm.compiler.phases.common.CanonicalizerPhase)

Aggregations

CanonicalizerPhase (org.graalvm.compiler.phases.common.CanonicalizerPhase)114 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)98 PhaseContext (org.graalvm.compiler.phases.tiers.PhaseContext)60 HighTierContext (org.graalvm.compiler.phases.tiers.HighTierContext)48 DebugContext (org.graalvm.compiler.debug.DebugContext)34 Test (org.junit.Test)33 LoweringPhase (org.graalvm.compiler.phases.common.LoweringPhase)31 InliningPhase (org.graalvm.compiler.phases.common.inlining.InliningPhase)27 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)17 DeadCodeEliminationPhase (org.graalvm.compiler.phases.common.DeadCodeEliminationPhase)16 PartialEscapePhase (org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase)14 Node (org.graalvm.compiler.graph.Node)12 FloatingReadPhase (org.graalvm.compiler.phases.common.FloatingReadPhase)12 DebugDumpScope (org.graalvm.compiler.debug.DebugDumpScope)10 OptionValues (org.graalvm.compiler.options.OptionValues)10 GuardLoweringPhase (org.graalvm.compiler.phases.common.GuardLoweringPhase)10 ConditionalEliminationPhase (org.graalvm.compiler.phases.common.ConditionalEliminationPhase)9 MidTierContext (org.graalvm.compiler.phases.tiers.MidTierContext)9 GraalCompilerTest (org.graalvm.compiler.core.test.GraalCompilerTest)8 Invoke (org.graalvm.compiler.nodes.Invoke)8