Search in sources :

Example 31 with MethodCallTargetNode

use of org.graalvm.compiler.nodes.java.MethodCallTargetNode in project graal by oracle.

the class PartialEvaluator method fastPartialEvaluation.

@SuppressWarnings({ "try", "unused" })
private void fastPartialEvaluation(CompilableTruffleAST compilable, TruffleInliningPlan inliningDecision, StructuredGraph graph, PhaseContext baseContext, HighTierContext tierContext) {
    DebugContext debug = graph.getDebug();
    doGraphPE(compilable, graph, tierContext, inliningDecision);
    debug.dump(DebugContext.BASIC_LEVEL, graph, "After Partial Evaluation");
    graph.maybeCompress();
    // Perform deoptimize to guard conversion.
    new ConvertDeoptimizeToGuardPhase().apply(graph, tierContext);
    for (MethodCallTargetNode methodCallTargetNode : graph.getNodes(MethodCallTargetNode.TYPE)) {
        StructuredGraph inlineGraph = providers.getReplacements().getSubstitution(methodCallTargetNode.targetMethod(), methodCallTargetNode.invoke().bci(), graph.trackNodeSourcePosition(), methodCallTargetNode.asNode().getNodeSourcePosition());
        if (inlineGraph != null) {
            InliningUtil.inline(methodCallTargetNode.invoke(), inlineGraph, true, methodCallTargetNode.targetMethod());
        }
    }
    // Perform conditional elimination.
    new ConditionalEliminationPhase(false).apply(graph, tierContext);
    canonicalizer.apply(graph, tierContext);
    // Do single partial escape and canonicalization pass.
    try (DebugContext.Scope pe = debug.scope("TrufflePartialEscape", graph)) {
        new PartialEscapePhase(TruffleCompilerOptions.getValue(TruffleIterativePartialEscape), canonicalizer, graph.getOptions()).apply(graph, tierContext);
    } catch (Throwable t) {
        debug.handle(t);
    }
    // recompute loop frequencies now that BranchProbabilities have had time to canonicalize
    ComputeLoopFrequenciesClosure.compute(graph);
    applyInstrumentationPhases(graph, tierContext);
    graph.maybeCompress();
    PerformanceInformationHandler.reportPerformanceWarnings(compilable, graph);
}
Also used : PartialEscapePhase(org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) ConditionalEliminationPhase(org.graalvm.compiler.phases.common.ConditionalEliminationPhase) DebugContext(org.graalvm.compiler.debug.DebugContext) ConvertDeoptimizeToGuardPhase(org.graalvm.compiler.phases.common.ConvertDeoptimizeToGuardPhase)

Example 32 with MethodCallTargetNode

use of org.graalvm.compiler.nodes.java.MethodCallTargetNode in project graal by oracle.

the class SpecialInvokeTypeFlow method onObservedUpdate.

@Override
public void onObservedUpdate(BigBang bb) {
    assert this.isClone();
    /*
         * Initialize the callee lazily so that if the invoke flow is not reached in this context,
         * i.e. for this clone, there is no callee linked.
         */
    if (callee == null) {
        MethodCallTargetNode target = (MethodCallTargetNode) invoke.callTarget();
        callee = ((AnalysisMethod) target.targetMethod()).getTypeFlow();
        // set the callee in the original invoke too
        ((DirectInvokeTypeFlow) originalInvoke).callee = callee;
    }
    TypeState invokeState = getReceiver().getState();
    for (AnalysisObject receiverObject : invokeState.objects()) {
        AnalysisContext calleeContext = bb.contextPolicy().calleeContext(bb, receiverObject, callerContext, callee);
        MethodFlowsGraph calleeFlows = callee.addContext(bb, calleeContext, this);
        if (calleesFlows.putIfAbsent(calleeFlows, Boolean.TRUE) == null) {
            linkCallee(bb, false, calleeFlows);
        }
        updateReceiver(bb, calleeFlows, receiverObject);
    }
}
Also used : AnalysisObject(com.oracle.graal.pointsto.flow.context.object.AnalysisObject) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) TypeState(com.oracle.graal.pointsto.typestate.TypeState) AnalysisContext(com.oracle.graal.pointsto.flow.context.AnalysisContext)

Example 33 with MethodCallTargetNode

use of org.graalvm.compiler.nodes.java.MethodCallTargetNode 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 34 with MethodCallTargetNode

use of org.graalvm.compiler.nodes.java.MethodCallTargetNode in project graal by oracle.

the class RuntimeStrengthenStampsPhase method printStaticTruffleBoundaries.

private void printStaticTruffleBoundaries() {
    HashSet<ResolvedJavaMethod> foundBoundaries = new HashSet<>();
    int callSiteCount = 0;
    int calleeCount = 0;
    for (CallTreeNode node : methods.values()) {
        StructuredGraph graph = node.graph;
        for (MethodCallTargetNode callTarget : graph.getNodes(MethodCallTargetNode.TYPE)) {
            ResolvedJavaMethod targetMethod = callTarget.targetMethod();
            TruffleBoundary truffleBoundary = targetMethod.getAnnotation(TruffleBoundary.class);
            if (truffleBoundary != null) {
                ++callSiteCount;
                if (foundBoundaries.contains(targetMethod)) {
                // nothing to do
                } else {
                    foundBoundaries.add(targetMethod);
                    System.out.println("Truffle boundary found: " + targetMethod);
                    calleeCount++;
                }
            }
        }
    }
    System.out.println(String.format("Number of Truffle call boundaries: %d, number of unique called methods outside the boundary: %d", callSiteCount, calleeCount));
}
Also used : StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) TruffleBoundary(com.oracle.truffle.api.CompilerDirectives.TruffleBoundary) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) HashSet(java.util.HashSet)

Example 35 with MethodCallTargetNode

use of org.graalvm.compiler.nodes.java.MethodCallTargetNode in project graal by oracle.

the class DefaultHotSpotLoweringProvider method lowerInvoke.

private void lowerInvoke(Invoke invoke, LoweringTool tool, StructuredGraph graph) {
    if (invoke.callTarget() instanceof MethodCallTargetNode) {
        MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget();
        NodeInputList<ValueNode> parameters = callTarget.arguments();
        ValueNode receiver = parameters.size() <= 0 ? null : parameters.get(0);
        if (!callTarget.isStatic() && receiver.stamp(NodeView.DEFAULT) instanceof ObjectStamp && !StampTool.isPointerNonNull(receiver)) {
            ValueNode nonNullReceiver = createNullCheckedValue(receiver, invoke.asNode(), tool);
            parameters.set(0, nonNullReceiver);
            receiver = nonNullReceiver;
        }
        JavaType[] signature = callTarget.targetMethod().getSignature().toParameterTypes(callTarget.isStatic() ? null : callTarget.targetMethod().getDeclaringClass());
        LoweredCallTargetNode loweredCallTarget = null;
        OptionValues options = graph.getOptions();
        if (InlineVTableStubs.getValue(options) && callTarget.invokeKind().isIndirect() && (AlwaysInlineVTableStubs.getValue(options) || invoke.isPolymorphic())) {
            HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) callTarget.targetMethod();
            ResolvedJavaType receiverType = invoke.getReceiverType();
            if (hsMethod.isInVirtualMethodTable(receiverType)) {
                JavaKind wordKind = runtime.getTarget().wordJavaKind;
                ValueNode hub = createReadHub(graph, receiver, tool);
                ReadNode metaspaceMethod = createReadVirtualMethod(graph, hub, hsMethod, receiverType);
                // We use LocationNode.ANY_LOCATION for the reads that access the
                // compiled code entry as HotSpot does not guarantee they are final
                // values.
                int methodCompiledEntryOffset = runtime.getVMConfig().methodCompiledEntryOffset;
                AddressNode address = createOffsetAddress(graph, metaspaceMethod, methodCompiledEntryOffset);
                ReadNode compiledEntry = graph.add(new ReadNode(address, any(), StampFactory.forKind(wordKind), BarrierType.NONE));
                loweredCallTarget = graph.add(new HotSpotIndirectCallTargetNode(metaspaceMethod, compiledEntry, parameters.toArray(new ValueNode[parameters.size()]), callTarget.returnStamp(), signature, callTarget.targetMethod(), HotSpotCallingConventionType.JavaCall, callTarget.invokeKind()));
                graph.addBeforeFixed(invoke.asNode(), metaspaceMethod);
                graph.addAfterFixed(metaspaceMethod, compiledEntry);
            }
        }
        if (loweredCallTarget == null) {
            loweredCallTarget = graph.add(new HotSpotDirectCallTargetNode(parameters.toArray(new ValueNode[parameters.size()]), callTarget.returnStamp(), signature, callTarget.targetMethod(), HotSpotCallingConventionType.JavaCall, callTarget.invokeKind()));
        }
        callTarget.replaceAndDelete(loweredCallTarget);
    }
}
Also used : HotSpotDirectCallTargetNode(org.graalvm.compiler.hotspot.nodes.HotSpotDirectCallTargetNode) HotSpotResolvedJavaMethod(jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod) ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp) OptionValues(org.graalvm.compiler.options.OptionValues) HotSpotIndirectCallTargetNode(org.graalvm.compiler.hotspot.nodes.HotSpotIndirectCallTargetNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) JavaType(jdk.vm.ci.meta.JavaType) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) GetObjectAddressNode(org.graalvm.compiler.hotspot.nodes.GetObjectAddressNode) ComputeObjectAddressNode(org.graalvm.compiler.hotspot.nodes.ComputeObjectAddressNode) AddressNode(org.graalvm.compiler.nodes.memory.address.AddressNode) FloatingReadNode(org.graalvm.compiler.nodes.memory.FloatingReadNode) ReadNode(org.graalvm.compiler.nodes.memory.ReadNode) LoweredCallTargetNode(org.graalvm.compiler.nodes.LoweredCallTargetNode) JavaKind(jdk.vm.ci.meta.JavaKind)

Aggregations

MethodCallTargetNode (org.graalvm.compiler.nodes.java.MethodCallTargetNode)46 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)17 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)15 ValueNode (org.graalvm.compiler.nodes.ValueNode)15 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)11 Invoke (org.graalvm.compiler.nodes.Invoke)10 Node (org.graalvm.compiler.graph.Node)9 InvokeNode (org.graalvm.compiler.nodes.InvokeNode)9 ArrayList (java.util.ArrayList)7 StampPair (org.graalvm.compiler.core.common.type.StampPair)7 PiNode (org.graalvm.compiler.nodes.PiNode)7 DebugContext (org.graalvm.compiler.debug.DebugContext)6 CallTargetNode (org.graalvm.compiler.nodes.CallTargetNode)6 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)5 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)5 FrameState (org.graalvm.compiler.nodes.FrameState)5 JavaType (jdk.vm.ci.meta.JavaType)4 ObjectStamp (org.graalvm.compiler.core.common.type.ObjectStamp)4 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)4 FixedGuardNode (org.graalvm.compiler.nodes.FixedGuardNode)4