Search in sources :

Example 1 with NullCheckNode

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

the class UseTrappingNullChecksPhase method replaceWithTrappingNullCheck.

private static void replaceWithTrappingNullCheck(AbstractDeoptimizeNode deopt, IfNode ifNode, LogicNode condition, DeoptimizationReason deoptimizationReason, long implicitNullCheckLimit) {
    DebugContext debug = deopt.getDebug();
    counterTrappingNullCheck.increment(debug);
    if (deopt instanceof DynamicDeoptimizeNode) {
        counterTrappingNullCheckDynamicDeoptimize.increment(debug);
    }
    if (deoptimizationReason == DeoptimizationReason.UnreachedCode) {
        counterTrappingNullCheckUnreached.increment(debug);
    }
    IsNullNode isNullNode = (IsNullNode) condition;
    AbstractBeginNode nonTrappingContinuation = ifNode.falseSuccessor();
    AbstractBeginNode trappingContinuation = ifNode.trueSuccessor();
    DeoptimizingFixedWithNextNode trappingNullCheck = null;
    FixedNode nextNonTrapping = nonTrappingContinuation.next();
    ValueNode value = isNullNode.getValue();
    if (OptImplicitNullChecks.getValue(ifNode.graph().getOptions()) && implicitNullCheckLimit > 0) {
        if (nextNonTrapping instanceof FixedAccessNode) {
            FixedAccessNode fixedAccessNode = (FixedAccessNode) nextNonTrapping;
            if (fixedAccessNode.canNullCheck()) {
                AddressNode address = fixedAccessNode.getAddress();
                ValueNode base = address.getBase();
                ValueNode index = address.getIndex();
                // intervening uncompress out of the address chain
                if (base != null && base instanceof CompressionNode) {
                    base = ((CompressionNode) base).getValue();
                }
                if (index != null && index instanceof CompressionNode) {
                    index = ((CompressionNode) index).getValue();
                }
                if (((base == value && index == null) || (base == null && index == value)) && address.getMaxConstantDisplacement() < implicitNullCheckLimit) {
                    // Opportunity for implicit null check as part of an existing read found!
                    fixedAccessNode.setStateBefore(deopt.stateBefore());
                    fixedAccessNode.setNullCheck(true);
                    deopt.graph().removeSplit(ifNode, nonTrappingContinuation);
                    trappingNullCheck = fixedAccessNode;
                    counterTrappingNullCheckExistingRead.increment(debug);
                }
            }
        }
    }
    if (trappingNullCheck == null) {
        // Need to add a null check node.
        trappingNullCheck = deopt.graph().add(new NullCheckNode(value));
        deopt.graph().replaceSplit(ifNode, trappingNullCheck, nonTrappingContinuation);
    }
    trappingNullCheck.setStateBefore(deopt.stateBefore());
    /*
         * We now have the pattern NullCheck/BeginNode/... It's possible some node is using the
         * BeginNode as a guard input, so replace guard users of the Begin with the NullCheck and
         * then remove the Begin from the graph.
         */
    nonTrappingContinuation.replaceAtUsages(InputType.Guard, trappingNullCheck);
    if (nonTrappingContinuation instanceof BeginNode) {
        GraphUtil.unlinkFixedNode(nonTrappingContinuation);
        nonTrappingContinuation.safeDelete();
    }
    GraphUtil.killCFG(trappingContinuation);
    GraphUtil.tryKillUnused(isNullNode);
}
Also used : FixedAccessNode(org.graalvm.compiler.nodes.memory.FixedAccessNode) DeoptimizingFixedWithNextNode(org.graalvm.compiler.nodes.DeoptimizingFixedWithNextNode) CompressionNode(org.graalvm.compiler.nodes.CompressionNode) IsNullNode(org.graalvm.compiler.nodes.calc.IsNullNode) NullCheckNode(org.graalvm.compiler.nodes.extended.NullCheckNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) DynamicDeoptimizeNode(org.graalvm.compiler.nodes.DynamicDeoptimizeNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) AddressNode(org.graalvm.compiler.nodes.memory.address.AddressNode) DebugContext(org.graalvm.compiler.debug.DebugContext) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode)

Aggregations

DebugContext (org.graalvm.compiler.debug.DebugContext)1 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)1 BeginNode (org.graalvm.compiler.nodes.BeginNode)1 CompressionNode (org.graalvm.compiler.nodes.CompressionNode)1 DeoptimizingFixedWithNextNode (org.graalvm.compiler.nodes.DeoptimizingFixedWithNextNode)1 DynamicDeoptimizeNode (org.graalvm.compiler.nodes.DynamicDeoptimizeNode)1 FixedNode (org.graalvm.compiler.nodes.FixedNode)1 ValueNode (org.graalvm.compiler.nodes.ValueNode)1 IsNullNode (org.graalvm.compiler.nodes.calc.IsNullNode)1 NullCheckNode (org.graalvm.compiler.nodes.extended.NullCheckNode)1 FixedAccessNode (org.graalvm.compiler.nodes.memory.FixedAccessNode)1 AddressNode (org.graalvm.compiler.nodes.memory.address.AddressNode)1