Search in sources :

Example 1 with IntegerSwitchNode

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

the class SimplifyingGraphDecoder method canonicalizeFixedNode.

/**
 * Canonicalizes the provided node, which was originally a {@link FixedNode} but can already be
 * canonicalized (and therefore be a non-fixed node).
 *
 * @param methodScope The current method.
 * @param node The node to be canonicalized.
 */
protected Node canonicalizeFixedNode(MethodScope methodScope, Node node) {
    if (node instanceof LoadFieldNode) {
        LoadFieldNode loadFieldNode = (LoadFieldNode) node;
        return loadFieldNode.canonical(canonicalizerTool);
    } else if (node instanceof FixedGuardNode) {
        FixedGuardNode guard = (FixedGuardNode) node;
        if (guard.getCondition() instanceof LogicConstantNode) {
            LogicConstantNode condition = (LogicConstantNode) guard.getCondition();
            if (condition.getValue() == guard.isNegated()) {
                DeoptimizeNode deopt = new DeoptimizeNode(guard.getAction(), guard.getReason(), guard.getSpeculation());
                if (guard.stateBefore() != null) {
                    deopt.setStateBefore(guard.stateBefore());
                }
                return deopt;
            } else {
                return null;
            }
        }
        return node;
    } else if (node instanceof IfNode) {
        IfNode ifNode = (IfNode) node;
        if (ifNode.condition() instanceof LogicNegationNode) {
            ifNode.eliminateNegation();
        }
        if (ifNode.condition() instanceof LogicConstantNode) {
            boolean condition = ((LogicConstantNode) ifNode.condition()).getValue();
            AbstractBeginNode survivingSuccessor = ifNode.getSuccessor(condition);
            AbstractBeginNode deadSuccessor = ifNode.getSuccessor(!condition);
            graph.removeSplit(ifNode, survivingSuccessor);
            assert deadSuccessor.next() == null : "must not be parsed yet";
            deadSuccessor.safeDelete();
        }
        return node;
    } else if (node instanceof LoadIndexedNode) {
        LoadIndexedNode loadIndexedNode = (LoadIndexedNode) node;
        return loadIndexedNode.canonical(canonicalizerTool);
    } else if (node instanceof ArrayLengthNode) {
        ArrayLengthNode arrayLengthNode = (ArrayLengthNode) node;
        return arrayLengthNode.canonical(canonicalizerTool);
    } else if (node instanceof IntegerSwitchNode && ((IntegerSwitchNode) node).value().isConstant()) {
        IntegerSwitchNode switchNode = (IntegerSwitchNode) node;
        int value = switchNode.value().asJavaConstant().asInt();
        AbstractBeginNode survivingSuccessor = switchNode.successorAtKey(value);
        List<Node> allSuccessors = switchNode.successors().snapshot();
        graph.removeSplit(switchNode, survivingSuccessor);
        for (Node successor : allSuccessors) {
            if (successor != survivingSuccessor) {
                assert ((AbstractBeginNode) successor).next() == null : "must not be parsed yet";
                successor.safeDelete();
            }
        }
        return node;
    } else if (node instanceof Canonicalizable) {
        return ((Canonicalizable) node).canonical(canonicalizerTool);
    } else {
        return node;
    }
}
Also used : IntegerSwitchNode(org.graalvm.compiler.nodes.extended.IntegerSwitchNode) FloatingNode(org.graalvm.compiler.nodes.calc.FloatingNode) LoadFieldNode(org.graalvm.compiler.nodes.java.LoadFieldNode) ArrayLengthNode(org.graalvm.compiler.nodes.java.ArrayLengthNode) Node(org.graalvm.compiler.graph.Node) GuardingNode(org.graalvm.compiler.nodes.extended.GuardingNode) LoadIndexedNode(org.graalvm.compiler.nodes.java.LoadIndexedNode) LoadFieldNode(org.graalvm.compiler.nodes.java.LoadFieldNode) LoadIndexedNode(org.graalvm.compiler.nodes.java.LoadIndexedNode) Canonicalizable(org.graalvm.compiler.graph.spi.Canonicalizable) List(java.util.List) ArrayLengthNode(org.graalvm.compiler.nodes.java.ArrayLengthNode) IntegerSwitchNode(org.graalvm.compiler.nodes.extended.IntegerSwitchNode)

Example 2 with IntegerSwitchNode

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

the class BytecodeParser method genIntegerSwitch.

protected void genIntegerSwitch(ValueNode value, ArrayList<BciBlock> actualSuccessors, int[] keys, double[] keyProbabilities, int[] keySuccessors) {
    if (value.isConstant()) {
        JavaConstant constant = (JavaConstant) value.asConstant();
        int constantValue = constant.asInt();
        for (int i = 0; i < keys.length; ++i) {
            if (keys[i] == constantValue) {
                appendGoto(actualSuccessors.get(keySuccessors[i]));
                return;
            }
        }
        appendGoto(actualSuccessors.get(keySuccessors[keys.length]));
    } else {
        this.controlFlowSplit = true;
        double[] successorProbabilities = successorProbabilites(actualSuccessors.size(), keySuccessors, keyProbabilities);
        IntegerSwitchNode switchNode = append(new IntegerSwitchNode(value, actualSuccessors.size(), keys, keyProbabilities, keySuccessors));
        for (int i = 0; i < actualSuccessors.size(); i++) {
            switchNode.setBlockSuccessor(i, createBlockTarget(successorProbabilities[i], actualSuccessors.get(i), frameState));
        }
    }
}
Also used : JavaConstant(jdk.vm.ci.meta.JavaConstant) RuntimeConstraint(jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint) IntegerSwitchNode(org.graalvm.compiler.nodes.extended.IntegerSwitchNode)

Example 3 with IntegerSwitchNode

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

the class NodeLIRBuilder method emitSwitch.

/**
 * This method tries to create a switch implementation that is optimal for the given switch. It
 * will either generate a sequential if/then/else cascade, a set of range tests or a table
 * switch.
 *
 * If the given switch does not contain int keys, it will always create a sequential
 * implementation.
 */
@Override
public void emitSwitch(SwitchNode x) {
    assert x.defaultSuccessor() != null;
    LabelRef defaultTarget = getLIRBlock(x.defaultSuccessor());
    int keyCount = x.keyCount();
    if (keyCount == 0) {
        gen.emitJump(defaultTarget);
    } else {
        Variable value = gen.load(operand(x.value()));
        if (keyCount == 1) {
            assert defaultTarget != null;
            double probability = x.probability(x.keySuccessor(0));
            LIRKind kind = gen.getLIRKind(x.value().stamp(NodeView.DEFAULT));
            Value key = gen.emitConstant(kind, x.keyAt(0));
            gen.emitCompareBranch(kind.getPlatformKind(), gen.load(operand(x.value())), key, Condition.EQ, false, getLIRBlock(x.keySuccessor(0)), defaultTarget, probability);
        } else if (x instanceof IntegerSwitchNode && x.isSorted()) {
            IntegerSwitchNode intSwitch = (IntegerSwitchNode) x;
            LabelRef[] keyTargets = new LabelRef[keyCount];
            JavaConstant[] keyConstants = new JavaConstant[keyCount];
            double[] keyProbabilities = new double[keyCount];
            JavaKind keyKind = intSwitch.keyAt(0).getJavaKind();
            for (int i = 0; i < keyCount; i++) {
                keyTargets[i] = getLIRBlock(intSwitch.keySuccessor(i));
                keyConstants[i] = intSwitch.keyAt(i);
                keyProbabilities[i] = intSwitch.keyProbability(i);
                assert keyConstants[i].getJavaKind() == keyKind;
            }
            gen.emitStrategySwitch(keyConstants, keyProbabilities, keyTargets, defaultTarget, value);
        } else {
            // keyKind != JavaKind.Int || !x.isSorted()
            LabelRef[] keyTargets = new LabelRef[keyCount];
            Constant[] keyConstants = new Constant[keyCount];
            double[] keyProbabilities = new double[keyCount];
            for (int i = 0; i < keyCount; i++) {
                keyTargets[i] = getLIRBlock(x.keySuccessor(i));
                keyConstants[i] = x.keyAt(i);
                keyProbabilities[i] = x.keyProbability(i);
            }
            // hopefully only a few entries
            gen.emitStrategySwitch(new SwitchStrategy.SequentialStrategy(keyProbabilities, keyConstants), value, keyTargets, defaultTarget);
        }
    }
}
Also used : Variable(org.graalvm.compiler.lir.Variable) ComplexMatchValue(org.graalvm.compiler.core.match.ComplexMatchValue) Value(jdk.vm.ci.meta.Value) AllocatableValue(jdk.vm.ci.meta.AllocatableValue) LIRKind(org.graalvm.compiler.core.common.LIRKind) LabelRef(org.graalvm.compiler.lir.LabelRef) IntegerSwitchNode(org.graalvm.compiler.nodes.extended.IntegerSwitchNode) JavaKind(jdk.vm.ci.meta.JavaKind)

Aggregations

IntegerSwitchNode (org.graalvm.compiler.nodes.extended.IntegerSwitchNode)3 List (java.util.List)1 AllocatableValue (jdk.vm.ci.meta.AllocatableValue)1 RuntimeConstraint (jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint)1 JavaConstant (jdk.vm.ci.meta.JavaConstant)1 JavaKind (jdk.vm.ci.meta.JavaKind)1 Value (jdk.vm.ci.meta.Value)1 LIRKind (org.graalvm.compiler.core.common.LIRKind)1 ComplexMatchValue (org.graalvm.compiler.core.match.ComplexMatchValue)1 Node (org.graalvm.compiler.graph.Node)1 Canonicalizable (org.graalvm.compiler.graph.spi.Canonicalizable)1 LabelRef (org.graalvm.compiler.lir.LabelRef)1 Variable (org.graalvm.compiler.lir.Variable)1 FloatingNode (org.graalvm.compiler.nodes.calc.FloatingNode)1 GuardingNode (org.graalvm.compiler.nodes.extended.GuardingNode)1 ArrayLengthNode (org.graalvm.compiler.nodes.java.ArrayLengthNode)1 LoadFieldNode (org.graalvm.compiler.nodes.java.LoadFieldNode)1 LoadIndexedNode (org.graalvm.compiler.nodes.java.LoadIndexedNode)1