Search in sources :

Example 1 with ControlFlowAnchorNode

use of org.graalvm.compiler.nodes.debug.ControlFlowAnchorNode in project graal by oracle.

the class DefaultLoopPolicies method shouldPartiallyUnroll.

@Override
public boolean shouldPartiallyUnroll(LoopEx loop) {
    LoopBeginNode loopBegin = loop.loopBegin();
    if (!loop.isCounted()) {
        loopBegin.getDebug().log(DebugContext.VERBOSE_LEVEL, "shouldPartiallyUnroll %s isn't counted", loopBegin);
        return false;
    }
    OptionValues options = loop.entryPoint().getOptions();
    int maxNodes = Options.ExactPartialUnrollMaxNodes.getValue(options);
    maxNodes = Math.min(maxNodes, Math.max(0, MaximumDesiredSize.getValue(options) - loop.loopBegin().graph().getNodeCount()));
    int size = Math.max(1, loop.size() - 1 - loop.loopBegin().phis().count());
    int unrollFactor = loopBegin.getUnrollFactor();
    if (unrollFactor == 1) {
        double loopFrequency = loopBegin.loopFrequency();
        if (loopBegin.isSimpleLoop() && loopFrequency < 5.0) {
            loopBegin.getDebug().log(DebugContext.VERBOSE_LEVEL, "shouldPartiallyUnroll %s frequency too low %s ", loopBegin, loopFrequency);
            return false;
        }
        loopBegin.setLoopOrigFrequency(loopFrequency);
    }
    int maxUnroll = Options.UnrollMaxIterations.getValue(options);
    // Now correct size for the next unroll. UnrollMaxIterations == 1 means perform the
    // pre/main/post transformation but don't actually unroll the main loop.
    size += size;
    if (maxUnroll == 1 && loopBegin.isSimpleLoop() || size <= maxNodes && unrollFactor < maxUnroll) {
        // Will the next unroll fit?
        if ((int) loopBegin.loopOrigFrequency() < (unrollFactor * 2)) {
            return false;
        }
        // Check whether we're allowed to unroll this loop
        for (Node node : loop.inside().nodes()) {
            if (node instanceof ControlFlowAnchorNode) {
                return false;
            }
            if (node instanceof InvokeNode) {
                return false;
            }
        }
        return true;
    } else {
        loopBegin.getDebug().log(DebugContext.VERBOSE_LEVEL, "shouldPartiallyUnroll %s unrolled loop is too large %s ", loopBegin, size);
        return false;
    }
}
Also used : LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) OptionValues(org.graalvm.compiler.options.OptionValues) ControlFlowAnchorNode(org.graalvm.compiler.nodes.debug.ControlFlowAnchorNode) ControlSplitNode(org.graalvm.compiler.nodes.ControlSplitNode) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) Node(org.graalvm.compiler.graph.Node) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) TypeSwitchNode(org.graalvm.compiler.nodes.java.TypeSwitchNode) ControlFlowAnchorNode(org.graalvm.compiler.nodes.debug.ControlFlowAnchorNode) InvokeNode(org.graalvm.compiler.nodes.InvokeNode)

Example 2 with ControlFlowAnchorNode

use of org.graalvm.compiler.nodes.debug.ControlFlowAnchorNode 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 ControlFlowAnchorNode

use of org.graalvm.compiler.nodes.debug.ControlFlowAnchorNode in project graal by oracle.

the class ProbabilityDirectiveTest method returnValue.

private static int returnValue(AbstractBeginNode b) {
    ControlFlowAnchorNode anchor = (ControlFlowAnchorNode) b.next();
    ReturnNode returnNode = (ReturnNode) anchor.next();
    return returnNode.result().asJavaConstant().asInt();
}
Also used : ReturnNode(org.graalvm.compiler.nodes.ReturnNode) ControlFlowAnchorNode(org.graalvm.compiler.nodes.debug.ControlFlowAnchorNode)

Example 4 with ControlFlowAnchorNode

use of org.graalvm.compiler.nodes.debug.ControlFlowAnchorNode in project graal by oracle.

the class ControlFlowAnchorDirectiveTest method checkLowTierGraph.

@Override
protected boolean checkLowTierGraph(StructuredGraph graph) {
    List<ControlFlowAnchorNode> anchors = graph.getNodes().filter(ControlFlowAnchorNode.class).snapshot();
    for (int i = 0; i < anchors.size(); i++) {
        ControlFlowAnchorNode a = anchors.get(i);
        for (int j = i + 1; j < anchors.size(); j++) {
            ControlFlowAnchorNode b = anchors.get(j);
            if (a.valueEquals(b)) {
                Assert.fail("found duplicated control flow anchors (" + a + " and " + b + ")");
            }
        }
    }
    for (NodeCount nodeCount : getNodeCountAnnotations(graph)) {
        NodeIterable<? extends Node> nodes = graph.getNodes().filter(nodeCount.nodeClass());
        Assert.assertEquals(nodeCount.nodeClass().getSimpleName(), nodeCount.expectedCount(), nodes.count());
    }
    return true;
}
Also used : ControlFlowAnchorNode(org.graalvm.compiler.nodes.debug.ControlFlowAnchorNode)

Aggregations

ControlFlowAnchorNode (org.graalvm.compiler.nodes.debug.ControlFlowAnchorNode)4 DeoptimizeNode (org.graalvm.compiler.nodes.DeoptimizeNode)2 BytecodePosition (jdk.vm.ci.code.BytecodePosition)1 JavaConstant (jdk.vm.ci.meta.JavaConstant)1 JavaKind (jdk.vm.ci.meta.JavaKind)1 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)1 Node (org.graalvm.compiler.graph.Node)1 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)1 ControlSplitNode (org.graalvm.compiler.nodes.ControlSplitNode)1 FixedNode (org.graalvm.compiler.nodes.FixedNode)1 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)1 InvokeNode (org.graalvm.compiler.nodes.InvokeNode)1 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)1 MergeNode (org.graalvm.compiler.nodes.MergeNode)1 ReturnNode (org.graalvm.compiler.nodes.ReturnNode)1 ValueNode (org.graalvm.compiler.nodes.ValueNode)1 BindToRegisterNode (org.graalvm.compiler.nodes.debug.BindToRegisterNode)1 BlackholeNode (org.graalvm.compiler.nodes.debug.BlackholeNode)1 OpaqueNode (org.graalvm.compiler.nodes.debug.OpaqueNode)1 SpillRegistersNode (org.graalvm.compiler.nodes.debug.SpillRegistersNode)1