src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/UseTrappingNullChecksPhase.java
changeset 58299 6df94ce3ab2f
parent 55509 d58442b8abc1
child 58679 9c3209ff7550
equal deleted inserted replaced
58298:0152ad7b38b8 58299:6df94ce3ab2f
     1 /*
     1 /*
     2  * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    43 import org.graalvm.compiler.nodes.DynamicDeoptimizeNode;
    43 import org.graalvm.compiler.nodes.DynamicDeoptimizeNode;
    44 import org.graalvm.compiler.nodes.EndNode;
    44 import org.graalvm.compiler.nodes.EndNode;
    45 import org.graalvm.compiler.nodes.FixedNode;
    45 import org.graalvm.compiler.nodes.FixedNode;
    46 import org.graalvm.compiler.nodes.IfNode;
    46 import org.graalvm.compiler.nodes.IfNode;
    47 import org.graalvm.compiler.nodes.LogicNode;
    47 import org.graalvm.compiler.nodes.LogicNode;
       
    48 import org.graalvm.compiler.nodes.LoopExitNode;
    48 import org.graalvm.compiler.nodes.StructuredGraph;
    49 import org.graalvm.compiler.nodes.StructuredGraph;
    49 import org.graalvm.compiler.nodes.ValueNode;
    50 import org.graalvm.compiler.nodes.ValueNode;
    50 import org.graalvm.compiler.nodes.ValuePhiNode;
    51 import org.graalvm.compiler.nodes.ValuePhiNode;
    51 import org.graalvm.compiler.nodes.calc.IsNullNode;
    52 import org.graalvm.compiler.nodes.calc.IsNullNode;
    52 import org.graalvm.compiler.nodes.extended.NullCheckNode;
    53 import org.graalvm.compiler.nodes.extended.NullCheckNode;
   163         }
   164         }
   164     }
   165     }
   165 
   166 
   166     private static void tryUseTrappingNullCheck(AbstractDeoptimizeNode deopt, Node predecessor, DeoptimizationReason deoptimizationReason, Speculation speculation, long implicitNullCheckLimit) {
   167     private static void tryUseTrappingNullCheck(AbstractDeoptimizeNode deopt, Node predecessor, DeoptimizationReason deoptimizationReason, Speculation speculation, long implicitNullCheckLimit) {
   167         assert predecessor != null;
   168         assert predecessor != null;
   168         if (deoptimizationReason != DeoptimizationReason.NullCheckException && deoptimizationReason != DeoptimizationReason.UnreachedCode) {
   169         if (deoptimizationReason != DeoptimizationReason.NullCheckException && deoptimizationReason != DeoptimizationReason.UnreachedCode &&
       
   170                         deoptimizationReason != DeoptimizationReason.TypeCheckedInliningViolated) {
   169             deopt.getDebug().log(DebugContext.INFO_LEVEL, "Not a null check or unreached %s", predecessor);
   171             deopt.getDebug().log(DebugContext.INFO_LEVEL, "Not a null check or unreached %s", predecessor);
   170             return;
   172             return;
   171         }
   173         }
   172         assert speculation != null;
   174         assert speculation != null;
   173         if (!speculation.equals(SpeculationLog.NO_SPECULATION)) {
   175         if (!speculation.equals(SpeculationLog.NO_SPECULATION)) {
   174             deopt.getDebug().log(DebugContext.INFO_LEVEL, "Has a speculation %s", predecessor);
   176             deopt.getDebug().log(DebugContext.INFO_LEVEL, "Has a speculation %s", predecessor);
   175             return;
   177             return;
   176         }
   178         }
   177         if (predecessor instanceof AbstractMergeNode) {
   179 
   178             AbstractMergeNode merge = (AbstractMergeNode) predecessor;
   180         // Skip over loop exit nodes.
       
   181         Node pred = predecessor;
       
   182         while (pred instanceof LoopExitNode) {
       
   183             pred = pred.predecessor();
       
   184         }
       
   185         if (pred instanceof AbstractMergeNode) {
       
   186             AbstractMergeNode merge = (AbstractMergeNode) pred;
   179             if (merge.phis().isEmpty()) {
   187             if (merge.phis().isEmpty()) {
   180                 for (AbstractEndNode end : merge.cfgPredecessors().snapshot()) {
   188                 for (AbstractEndNode end : merge.cfgPredecessors().snapshot()) {
   181                     checkPredecessor(deopt, end.predecessor(), deoptimizationReason, implicitNullCheckLimit);
   189                     checkPredecessor(deopt, end.predecessor(), deoptimizationReason, implicitNullCheckLimit);
   182                 }
   190                 }
   183             }
   191             }
   184         } else if (predecessor instanceof AbstractBeginNode) {
   192         } else if (pred instanceof AbstractBeginNode) {
   185             checkPredecessor(deopt, predecessor, deoptimizationReason, implicitNullCheckLimit);
   193             checkPredecessor(deopt, pred, deoptimizationReason, implicitNullCheckLimit);
   186         } else {
   194         } else {
   187             deopt.getDebug().log(DebugContext.INFO_LEVEL, "Not a Begin or Merge %s", predecessor);
   195             deopt.getDebug().log(DebugContext.INFO_LEVEL, "Not a Begin or Merge %s", pred);
   188         }
   196         }
   189     }
   197     }
   190 
   198 
   191     private static void checkPredecessor(AbstractDeoptimizeNode deopt, Node predecessor, DeoptimizationReason deoptimizationReason, long implicitNullCheckLimit) {
   199     private static void checkPredecessor(AbstractDeoptimizeNode deopt, Node predecessor, DeoptimizationReason deoptimizationReason, long implicitNullCheckLimit) {
   192         Node current = predecessor;
   200         Node current = predecessor;