Search in sources :

Example 1 with BranchProbabilityNode

use of org.graalvm.compiler.nodes.extended.BranchProbabilityNode in project graal by oracle.

the class TruffleGraphBuilderPlugins method registerCompilerDirectivesPlugins.

public static void registerCompilerDirectivesPlugins(InvocationPlugins plugins, MetaAccessProvider metaAccess, boolean canDelayIntrinsification) {
    final ResolvedJavaType compilerDirectivesType = getRuntime().resolveType(metaAccess, "com.oracle.truffle.api.CompilerDirectives");
    Registration r = new Registration(plugins, new ResolvedJavaSymbol(compilerDirectivesType));
    r.register0("inInterpreter", new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(false));
            return true;
        }
    });
    r.register0("inCompiledCode", new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(true));
            return true;
        }
    });
    r.register0("inCompilationRoot", new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            GraphBuilderContext.ExternalInliningContext inliningContext = b.getExternalInliningContext();
            if (inliningContext != null) {
                b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(inliningContext.getInlinedDepth() == 0));
                return true;
            }
            return false;
        }
    });
    r.register0("transferToInterpreter", new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.add(new DeoptimizeNode(DeoptimizationAction.None, DeoptimizationReason.TransferToInterpreter));
            return true;
        }
    });
    r.register0("transferToInterpreterAndInvalidate", new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TransferToInterpreter));
            return true;
        }
    });
    r.register1("interpreterOnly", Runnable.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg) {
            return true;
        }
    });
    r.register1("interpreterOnly", Callable.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg) {
            return true;
        }
    });
    r.register2("injectBranchProbability", double.class, boolean.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode probability, ValueNode condition) {
            b.addPush(JavaKind.Boolean, new BranchProbabilityNode(probability, condition));
            return true;
        }
    });
    r.register1("bailout", String.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode message) {
            if (canDelayIntrinsification) {
                /*
                     * We do not want to bailout yet, since we are still parsing individual methods
                     * and constant folding could still eliminate the call to bailout(). However, we
                     * also want to stop parsing, since we are sure that we will never need the
                     * graph beyond the bailout point.
                     *
                     * Therefore, we manually emit the call to bailout, which will be intrinsified
                     * later when intrinsifications can no longer be delayed. The call is followed
                     * by a NeverPartOfCompilationNode, which is a control sink and therefore stops
                     * any further parsing.
                     */
                StampPair returnStamp = b.getInvokeReturnStamp(b.getAssumptions());
                CallTargetNode callTarget = b.add(new MethodCallTargetNode(InvokeKind.Static, targetMethod, new ValueNode[] { message }, returnStamp, null));
                b.add(new InvokeNode(callTarget, b.bci()));
                b.add(new NeverPartOfCompilationNode("intrinsification of call to bailout() will abort entire compilation"));
                return true;
            }
            if (message.isConstant()) {
                throw b.bailout(message.asConstant().toValueString());
            }
            throw b.bailout("bailout (message is not compile-time constant, so no additional information is available)");
        }
    });
    r.register1("isCompilationConstant", Object.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
            if ((value instanceof BoxNode ? ((BoxNode) value).getValue() : value).isConstant()) {
                b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(true));
            } else {
                b.addPush(JavaKind.Boolean, new IsCompilationConstantNode(value));
            }
            return true;
        }
    });
    r.register1("isPartialEvaluationConstant", Object.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
            if ((value instanceof BoxNode ? ((BoxNode) value).getValue() : value).isConstant()) {
                b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(true));
            } else if (canDelayIntrinsification) {
                return false;
            } else {
                b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(false));
            }
            return true;
        }
    });
    r.register1("materialize", Object.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
            AllowMaterializeNode materializedValue = b.append(new AllowMaterializeNode(value));
            b.add(new ForceMaterializeNode(materializedValue));
            return true;
        }
    });
    r.register1("ensureVirtualized", Object.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object) {
            b.add(new EnsureVirtualizedNode(object, false));
            return true;
        }
    });
    r.register1("ensureVirtualizedHere", Object.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object) {
            b.add(new EnsureVirtualizedNode(object, true));
            return true;
        }
    });
    r.register2("castExact", Object.class, Class.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object, ValueNode javaClass) {
            ValueNode nullCheckedClass = b.addNonNullCast(javaClass);
            LogicNode condition = b.append(InstanceOfDynamicNode.create(b.getAssumptions(), b.getConstantReflection(), nullCheckedClass, object, true, true));
            if (condition.isTautology()) {
                b.addPush(JavaKind.Object, object);
            } else {
                FixedGuardNode fixedGuard = b.add(new FixedGuardNode(condition, DeoptimizationReason.ClassCastException, DeoptimizationAction.InvalidateReprofile, false));
                b.addPush(JavaKind.Object, DynamicPiNode.create(b.getAssumptions(), b.getConstantReflection(), object, fixedGuard, nullCheckedClass, true));
            }
            return true;
        }
    });
}
Also used : EnsureVirtualizedNode(org.graalvm.compiler.nodes.virtual.EnsureVirtualizedNode) BoxNode(org.graalvm.compiler.nodes.extended.BoxNode) Receiver(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver) BranchProbabilityNode(org.graalvm.compiler.nodes.extended.BranchProbabilityNode) AllowMaterializeNode(org.graalvm.compiler.truffle.compiler.nodes.frame.AllowMaterializeNode) ResolvedJavaSymbol(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.ResolvedJavaSymbol) NeverPartOfCompilationNode(org.graalvm.compiler.truffle.compiler.nodes.asserts.NeverPartOfCompilationNode) ForceMaterializeNode(org.graalvm.compiler.truffle.compiler.nodes.frame.ForceMaterializeNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) IsCompilationConstantNode(org.graalvm.compiler.truffle.compiler.nodes.IsCompilationConstantNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) GraphBuilderContext(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext) Registration(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration) ValueNode(org.graalvm.compiler.nodes.ValueNode) StampPair(org.graalvm.compiler.core.common.type.StampPair) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) InvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) CallTargetNode(org.graalvm.compiler.nodes.CallTargetNode)

Example 2 with BranchProbabilityNode

use of org.graalvm.compiler.nodes.extended.BranchProbabilityNode in project graal by oracle.

the class StandardGraphBuilderPlugins method registerGraalDirectivesPlugins.

private static void registerGraalDirectivesPlugins(InvocationPlugins plugins) {
    Registration r = new Registration(plugins, GraalDirectives.class);
    r.register0("deoptimize", new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.add(new DeoptimizeNode(DeoptimizationAction.None, DeoptimizationReason.TransferToInterpreter));
            return true;
        }
    });
    r.register0("deoptimizeAndInvalidate", new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TransferToInterpreter));
            return true;
        }
    });
    r.register0("deoptimizeAndInvalidateWithSpeculation", new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            GraalError.guarantee(b.getGraph().getSpeculationLog() != null, "A speculation log is need to use `deoptimizeAndInvalidateWithSpeculation`");
            BytecodePosition pos = new BytecodePosition(null, b.getMethod(), b.bci());
            DirectiveSpeculationReason reason = new DirectiveSpeculationReason(pos);
            JavaConstant speculation;
            if (b.getGraph().getSpeculationLog().maySpeculate(reason)) {
                speculation = b.getGraph().getSpeculationLog().speculate(reason);
            } else {
                speculation = JavaConstant.defaultForKind(JavaKind.Object);
            }
            b.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TransferToInterpreter, speculation));
            return true;
        }
    });
    r.register0("inCompiledCode", new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(true));
            return true;
        }
    });
    r.register0("controlFlowAnchor", new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.add(new ControlFlowAnchorNode());
            return true;
        }
    });
    r.register2("injectBranchProbability", double.class, boolean.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode probability, ValueNode condition) {
            b.addPush(JavaKind.Boolean, new BranchProbabilityNode(probability, condition));
            return true;
        }
    });
    InvocationPlugin blackholePlugin = new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
            b.add(new BlackholeNode(value));
            return true;
        }
    };
    InvocationPlugin bindToRegisterPlugin = new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
            b.add(new BindToRegisterNode(value));
            return true;
        }
    };
    for (JavaKind kind : JavaKind.values()) {
        if ((kind.isPrimitive() && kind != JavaKind.Void) || kind == JavaKind.Object) {
            Class<?> javaClass = kind == JavaKind.Object ? Object.class : kind.toJavaClass();
            r.register1("blackhole", javaClass, blackholePlugin);
            r.register1("bindToRegister", javaClass, bindToRegisterPlugin);
            r.register1("opaque", javaClass, new InvocationPlugin() {

                @Override
                public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
                    b.addPush(kind, new OpaqueNode(value));
                    return true;
                }
            });
        }
    }
    InvocationPlugin spillPlugin = new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.add(new SpillRegistersNode());
            return true;
        }
    };
    r.register0("spillRegisters", spillPlugin);
    r.register1("guardingNonNull", Object.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
            b.addPush(value.getStackKind(), b.nullCheckedValue(value));
            return true;
        }
    });
    r.register1("ensureVirtualized", Object.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object) {
            b.add(new EnsureVirtualizedNode(object, false));
            return true;
        }
    });
    r.register1("ensureVirtualizedHere", Object.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object) {
            b.add(new EnsureVirtualizedNode(object, true));
            return true;
        }
    });
}
Also used : BindToRegisterNode(org.graalvm.compiler.nodes.debug.BindToRegisterNode) EnsureVirtualizedNode(org.graalvm.compiler.nodes.virtual.EnsureVirtualizedNode) BytecodePosition(jdk.vm.ci.code.BytecodePosition) SpillRegistersNode(org.graalvm.compiler.nodes.debug.SpillRegistersNode) Receiver(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver) BranchProbabilityNode(org.graalvm.compiler.nodes.extended.BranchProbabilityNode) JavaConstant(jdk.vm.ci.meta.JavaConstant) OpaqueNode(org.graalvm.compiler.nodes.debug.OpaqueNode) BlackholeNode(org.graalvm.compiler.nodes.debug.BlackholeNode) GraphBuilderContext(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext) Registration(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration) ControlFlowAnchorNode(org.graalvm.compiler.nodes.debug.ControlFlowAnchorNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) InvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) JavaKind(jdk.vm.ci.meta.JavaKind)

Example 3 with BranchProbabilityNode

use of org.graalvm.compiler.nodes.extended.BranchProbabilityNode in project graal by oracle.

the class BytecodeParser method extractInjectedProbability.

private static double extractInjectedProbability(IntegerEqualsNode condition) {
    // Propagate injected branch probability if any.
    IntegerEqualsNode equalsNode = condition;
    BranchProbabilityNode probabilityNode = null;
    ValueNode other = null;
    if (equalsNode.getX() instanceof BranchProbabilityNode) {
        probabilityNode = (BranchProbabilityNode) equalsNode.getX();
        other = equalsNode.getY();
    } else if (equalsNode.getY() instanceof BranchProbabilityNode) {
        probabilityNode = (BranchProbabilityNode) equalsNode.getY();
        other = equalsNode.getX();
    }
    if (probabilityNode != null && probabilityNode.getProbability().isConstant() && other != null && other.isConstant()) {
        double probabilityValue = probabilityNode.getProbability().asJavaConstant().asDouble();
        return other.asJavaConstant().asInt() == 0 ? 1.0 - probabilityValue : probabilityValue;
    }
    return -1;
}
Also used : IntegerEqualsNode(org.graalvm.compiler.nodes.calc.IntegerEqualsNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) BranchProbabilityNode(org.graalvm.compiler.nodes.extended.BranchProbabilityNode)

Aggregations

ValueNode (org.graalvm.compiler.nodes.ValueNode)3 BranchProbabilityNode (org.graalvm.compiler.nodes.extended.BranchProbabilityNode)3 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)2 DeoptimizeNode (org.graalvm.compiler.nodes.DeoptimizeNode)2 GraphBuilderContext (org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext)2 InvocationPlugin (org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin)2 Receiver (org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver)2 Registration (org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration)2 EnsureVirtualizedNode (org.graalvm.compiler.nodes.virtual.EnsureVirtualizedNode)2 BytecodePosition (jdk.vm.ci.code.BytecodePosition)1 JavaConstant (jdk.vm.ci.meta.JavaConstant)1 JavaKind (jdk.vm.ci.meta.JavaKind)1 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)1 StampPair (org.graalvm.compiler.core.common.type.StampPair)1 CallTargetNode (org.graalvm.compiler.nodes.CallTargetNode)1 FixedGuardNode (org.graalvm.compiler.nodes.FixedGuardNode)1 InvokeNode (org.graalvm.compiler.nodes.InvokeNode)1 LogicNode (org.graalvm.compiler.nodes.LogicNode)1 IntegerEqualsNode (org.graalvm.compiler.nodes.calc.IntegerEqualsNode)1 BindToRegisterNode (org.graalvm.compiler.nodes.debug.BindToRegisterNode)1