Search in sources :

Example 1 with AbstractBeginNode

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

the class IntegerSwitchNode method tryRemoveUnreachableKeys.

/**
 * Remove unreachable keys from the switch based on the stamp of the value, i.e., based on the
 * known range of the switch value.
 */
public boolean tryRemoveUnreachableKeys(SimplifierTool tool, Stamp valueStamp) {
    if (!(valueStamp instanceof IntegerStamp)) {
        return false;
    }
    IntegerStamp integerStamp = (IntegerStamp) valueStamp;
    if (integerStamp.isUnrestricted()) {
        return false;
    }
    List<KeyData> newKeyDatas = new ArrayList<>(keys.length);
    ArrayList<AbstractBeginNode> newSuccessors = new ArrayList<>(blockSuccessorCount());
    for (int i = 0; i < keys.length; i++) {
        if (integerStamp.contains(keys[i]) && keySuccessor(i) != defaultSuccessor()) {
            newKeyDatas.add(new KeyData(keys[i], keyProbabilities[i], addNewSuccessor(keySuccessor(i), newSuccessors)));
        }
    }
    if (newKeyDatas.size() == keys.length) {
        /* All keys are reachable. */
        return false;
    } else if (newKeyDatas.size() == 0) {
        if (tool != null) {
            tool.addToWorkList(defaultSuccessor());
        }
        graph().removeSplitPropagate(this, defaultSuccessor());
        return true;
    } else {
        int newDefaultSuccessor = addNewSuccessor(defaultSuccessor(), newSuccessors);
        double newDefaultProbability = keyProbabilities[keyProbabilities.length - 1];
        doReplace(value(), newKeyDatas, newSuccessors, newDefaultSuccessor, newDefaultProbability);
        return true;
    }
}
Also used : IntegerStamp(org.graalvm.compiler.core.common.type.IntegerStamp) ArrayList(java.util.ArrayList) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode)

Example 2 with AbstractBeginNode

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

the class IntegerSwitchNode method doReplace.

private void doReplace(ValueNode newValue, List<KeyData> newKeyDatas, ArrayList<AbstractBeginNode> newSuccessors, int newDefaultSuccessor, double newDefaultProbability) {
    /* Sort the new keys (invariant of the IntegerSwitchNode). */
    newKeyDatas.sort(Comparator.comparingInt(k -> k.key));
    /* Create the final data arrays. */
    int newKeyCount = newKeyDatas.size();
    int[] newKeys = new int[newKeyCount];
    double[] newKeyProbabilities = new double[newKeyCount + 1];
    int[] newKeySuccessors = new int[newKeyCount + 1];
    for (int i = 0; i < newKeyCount; i++) {
        KeyData keyData = newKeyDatas.get(i);
        newKeys[i] = keyData.key;
        newKeyProbabilities[i] = keyData.keyProbability;
        newKeySuccessors[i] = keyData.keySuccessor;
    }
    newKeySuccessors[newKeyCount] = newDefaultSuccessor;
    newKeyProbabilities[newKeyCount] = newDefaultProbability;
    /* Normalize new probabilities so that they sum up to 1. */
    double totalProbability = 0;
    for (double probability : newKeyProbabilities) {
        totalProbability += probability;
    }
    if (totalProbability > 0) {
        for (int i = 0; i < newKeyProbabilities.length; i++) {
            newKeyProbabilities[i] /= totalProbability;
        }
    } else {
        for (int i = 0; i < newKeyProbabilities.length; i++) {
            newKeyProbabilities[i] = 1.0 / newKeyProbabilities.length;
        }
    }
    /*
         * Collect dead successors. Successors have to be cleaned before adding the new node to the
         * graph.
         */
    List<AbstractBeginNode> deadSuccessors = successors.filter(s -> !newSuccessors.contains(s)).snapshot();
    successors.clear();
    /*
         * Create the new switch node. This is done before removing dead successors as `killCFG`
         * could edit some of the inputs (e.g., if `newValue` is a loop-phi of the loop that dies
         * while removing successors).
         */
    AbstractBeginNode[] successorsArray = newSuccessors.toArray(new AbstractBeginNode[newSuccessors.size()]);
    SwitchNode newSwitch = graph().add(new IntegerSwitchNode(newValue, successorsArray, newKeys, newKeyProbabilities, newKeySuccessors));
    /* Remove dead successors. */
    for (AbstractBeginNode successor : deadSuccessors) {
        GraphUtil.killCFG(successor);
    }
    /* Replace ourselves with the new switch */
    ((FixedWithNextNode) predecessor()).setNext(newSwitch);
    GraphUtil.killWithUnusedFloatingInputs(this);
}
Also used : DeoptimizationReason(jdk.vm.ci.meta.DeoptimizationReason) Arrays(java.util.Arrays) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) DeoptimizationAction(jdk.vm.ci.meta.DeoptimizationAction) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) NodeLIRBuilderTool(org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool) SimplifierTool(org.graalvm.compiler.graph.spi.SimplifierTool) IntegerStamp(org.graalvm.compiler.core.common.type.IntegerStamp) StampFactory(org.graalvm.compiler.core.common.type.StampFactory) JavaKind(jdk.vm.ci.meta.JavaKind) NodeClass(org.graalvm.compiler.graph.NodeClass) Map(java.util.Map) LoadIndexedNode(org.graalvm.compiler.nodes.java.LoadIndexedNode) IntegerBelowNode(org.graalvm.compiler.nodes.calc.IntegerBelowNode) NodeInfo(org.graalvm.compiler.nodeinfo.NodeInfo) GraphUtil(org.graalvm.compiler.nodes.util.GraphUtil) NodeView(org.graalvm.compiler.nodes.NodeView) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) PrimitiveStamp(org.graalvm.compiler.core.common.type.PrimitiveStamp) Stamp(org.graalvm.compiler.core.common.type.Stamp) LIRLowerable(org.graalvm.compiler.nodes.spi.LIRLowerable) JavaConstant(jdk.vm.ci.meta.JavaConstant) LogicNode(org.graalvm.compiler.nodes.LogicNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) List(java.util.List) ConstantFieldProvider(org.graalvm.compiler.core.common.spi.ConstantFieldProvider) Simplifiable(org.graalvm.compiler.graph.spi.Simplifiable) Comparator(java.util.Comparator) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode)

Example 3 with AbstractBeginNode

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

the class ExceptionObjectNode method lower.

@Override
public void lower(LoweringTool tool) {
    if (graph().getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
        /*
             * Now the lowering to BeginNode+LoadExceptionNode can be performed, since no more
             * deopts can float in between the begin node and the load exception node.
             */
        LocationIdentity locationsKilledByInvoke = ((InvokeWithExceptionNode) predecessor()).getLocationIdentity();
        AbstractBeginNode entry = graph().add(KillingBeginNode.create(locationsKilledByInvoke));
        LoadExceptionObjectNode loadException = graph().add(new LoadExceptionObjectNode(stamp(NodeView.DEFAULT)));
        loadException.setStateAfter(stateAfter());
        replaceAtUsages(InputType.Value, loadException);
        graph().replaceFixedWithFixed(this, entry);
        entry.graph().addAfterFixed(entry, loadException);
        loadException.lower(tool);
    }
}
Also used : InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) LocationIdentity(org.graalvm.word.LocationIdentity) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode)

Example 4 with AbstractBeginNode

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

the class ConvertDeoptimizeToGuardPhase method processFixedGuardAndPhis.

private void processFixedGuardAndPhis(FixedGuardNode fixedGuard, PhaseContext context, CompareNode compare, ValueNode x, ValuePhiNode xPhi, ValueNode y, ValuePhiNode yPhi) {
    AbstractBeginNode pred = AbstractBeginNode.prevBegin(fixedGuard);
    if (pred instanceof AbstractMergeNode) {
        AbstractMergeNode merge = (AbstractMergeNode) pred;
        if (xPhi != null && xPhi.merge() != merge) {
            return;
        }
        if (yPhi != null && yPhi.merge() != merge) {
            return;
        }
        processFixedGuardAndMerge(fixedGuard, context, compare, x, xPhi, y, yPhi, merge);
    }
}
Also used : AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode)

Example 5 with AbstractBeginNode

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

the class PropagateDeoptimizeProbabilityPhase method run.

@Override
@SuppressWarnings("try")
protected void run(final StructuredGraph graph, PhaseContext context) {
    assert !graph.hasValueProxies() : "ConvertDeoptimizeToGuardPhase always creates proxies";
    if (graph.hasNode(AbstractDeoptimizeNode.TYPE)) {
        NodeStack stack = new NodeStack();
        EconomicMap<ControlSplitNode, EconomicSet<AbstractBeginNode>> reachableSplits = EconomicMap.create();
        // Mark all control flow nodes that are post-dominated by a deoptimization.
        for (AbstractDeoptimizeNode d : graph.getNodes(AbstractDeoptimizeNode.TYPE)) {
            stack.push(AbstractBeginNode.prevBegin(d));
            while (!stack.isEmpty()) {
                AbstractBeginNode beginNode = (AbstractBeginNode) stack.pop();
                FixedNode fixedNode = (FixedNode) beginNode.predecessor();
                if (fixedNode == null) {
                // Can happen for start node.
                } else if (fixedNode instanceof AbstractMergeNode) {
                    AbstractMergeNode mergeNode = (AbstractMergeNode) fixedNode;
                    for (AbstractEndNode end : mergeNode.forwardEnds()) {
                        AbstractBeginNode newBeginNode = AbstractBeginNode.prevBegin(end);
                        stack.push(newBeginNode);
                    }
                } else if (fixedNode instanceof ControlSplitNode) {
                    ControlSplitNode controlSplitNode = (ControlSplitNode) fixedNode;
                    EconomicSet<AbstractBeginNode> reachableSuccessors = reachableSplits.get(controlSplitNode);
                    if (reachableSuccessors == null) {
                        reachableSuccessors = EconomicSet.create();
                        reachableSplits.put(controlSplitNode, reachableSuccessors);
                    }
                    if (controlSplitNode.getSuccessorCount() == reachableSuccessors.size() - 1) {
                        // All successors of this split lead to deopt, propagate reachability
                        // further upwards.
                        reachableSplits.removeKey(controlSplitNode);
                        stack.push(AbstractBeginNode.prevBegin((FixedNode) controlSplitNode.predecessor()));
                    } else {
                        reachableSuccessors.add(beginNode);
                    }
                } else {
                    stack.push(AbstractBeginNode.prevBegin(fixedNode));
                }
            }
        }
        // Make sure the probability on the path towards the deoptimization is 0.0.
        MapCursor<ControlSplitNode, EconomicSet<AbstractBeginNode>> entries = reachableSplits.getEntries();
        while (entries.advance()) {
            ControlSplitNode controlSplitNode = entries.getKey();
            EconomicSet<AbstractBeginNode> value = entries.getValue();
            for (AbstractBeginNode begin : value) {
                double probability = controlSplitNode.probability(begin);
                if (probability != 0.0) {
                    controlSplitNode.setProbability(begin, 0.0);
                }
            }
        }
    }
}
Also used : AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) NodeStack(org.graalvm.compiler.graph.NodeStack) ControlSplitNode(org.graalvm.compiler.nodes.ControlSplitNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) EconomicSet(org.graalvm.collections.EconomicSet) AbstractDeoptimizeNode(org.graalvm.compiler.nodes.AbstractDeoptimizeNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode)

Aggregations

AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)63 FixedNode (org.graalvm.compiler.nodes.FixedNode)32 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)31 Node (org.graalvm.compiler.graph.Node)24 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)23 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)23 EndNode (org.graalvm.compiler.nodes.EndNode)22 BeginNode (org.graalvm.compiler.nodes.BeginNode)21 ValueNode (org.graalvm.compiler.nodes.ValueNode)20 AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)16 IfNode (org.graalvm.compiler.nodes.IfNode)16 ControlSplitNode (org.graalvm.compiler.nodes.ControlSplitNode)15 MergeNode (org.graalvm.compiler.nodes.MergeNode)15 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)15 LoopExitNode (org.graalvm.compiler.nodes.LoopExitNode)14 PhiNode (org.graalvm.compiler.nodes.PhiNode)14 LoopEndNode (org.graalvm.compiler.nodes.LoopEndNode)13 LogicNode (org.graalvm.compiler.nodes.LogicNode)12 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)11 DeoptimizeNode (org.graalvm.compiler.nodes.DeoptimizeNode)11