src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConvertDeoptimizeToGuardPhase.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConvertDeoptimizeToGuardPhase.java

Print this page




   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package org.graalvm.compiler.phases.common;
  24 
  25 import static org.graalvm.compiler.phases.common.DeadCodeEliminationPhase.Optionality.Optional;
  26 
  27 import java.util.List;
  28 
  29 import org.graalvm.compiler.debug.Debug;
  30 import org.graalvm.compiler.debug.DebugCloseable;

  31 import org.graalvm.compiler.graph.Node;
  32 import org.graalvm.compiler.graph.spi.SimplifierTool;
  33 import org.graalvm.compiler.nodeinfo.InputType;
  34 import org.graalvm.compiler.nodes.AbstractBeginNode;
  35 import org.graalvm.compiler.nodes.AbstractEndNode;
  36 import org.graalvm.compiler.nodes.AbstractMergeNode;
  37 import org.graalvm.compiler.nodes.ConstantNode;
  38 import org.graalvm.compiler.nodes.ControlSplitNode;
  39 import org.graalvm.compiler.nodes.DeoptimizeNode;
  40 import org.graalvm.compiler.nodes.EndNode;
  41 import org.graalvm.compiler.nodes.FixedGuardNode;
  42 import org.graalvm.compiler.nodes.FixedNode;
  43 import org.graalvm.compiler.nodes.FixedWithNextNode;
  44 import org.graalvm.compiler.nodes.GuardNode;
  45 import org.graalvm.compiler.nodes.IfNode;
  46 import org.graalvm.compiler.nodes.LogicNode;
  47 import org.graalvm.compiler.nodes.LoopExitNode;
  48 import org.graalvm.compiler.nodes.ProxyNode;
  49 import org.graalvm.compiler.nodes.StructuredGraph;
  50 import org.graalvm.compiler.nodes.ValueNode;


 152                 ys = y.asConstant();
 153             } else {
 154                 ys = yPhi.valueAt(mergePredecessor).asConstant();
 155             }
 156             if (xs != null && ys != null && compare.condition().foldCondition(xs, ys, context.getConstantReflection(), compare.unorderedIsTrue()) == fixedGuard.isNegated()) {
 157                 visitDeoptBegin(AbstractBeginNode.prevBegin(mergePredecessor), fixedGuard.getAction(), fixedGuard.getReason(), fixedGuard.getSpeculation(), fixedGuard.graph(), context.getLowerer());
 158             }
 159         }
 160     }
 161 
 162     private void visitDeoptBegin(AbstractBeginNode deoptBegin, DeoptimizationAction deoptAction, DeoptimizationReason deoptReason, JavaConstant speculation, StructuredGraph graph,
 163                     LoweringProvider loweringProvider) {
 164         if (deoptBegin.predecessor() instanceof AbstractBeginNode) {
 165             /*
 166              * Walk up chains of LoopExitNodes to the "real" BeginNode that leads to deoptimization.
 167              */
 168             visitDeoptBegin((AbstractBeginNode) deoptBegin.predecessor(), deoptAction, deoptReason, speculation, graph, loweringProvider);
 169             return;
 170         }
 171 

 172         if (deoptBegin instanceof AbstractMergeNode) {
 173             AbstractMergeNode mergeNode = (AbstractMergeNode) deoptBegin;
 174             Debug.log("Visiting %s", mergeNode);
 175             FixedNode next = mergeNode.next();
 176             while (mergeNode.isAlive()) {
 177                 AbstractEndNode end = mergeNode.forwardEnds().first();
 178                 AbstractBeginNode newBeginNode = AbstractBeginNode.prevBegin(end);
 179                 visitDeoptBegin(newBeginNode, deoptAction, deoptReason, speculation, graph, loweringProvider);
 180             }
 181             assert next.isAlive();
 182             AbstractBeginNode newBeginNode = AbstractBeginNode.prevBegin(next);
 183             visitDeoptBegin(newBeginNode, deoptAction, deoptReason, speculation, graph, loweringProvider);
 184             return;
 185         } else if (deoptBegin.predecessor() instanceof IfNode) {
 186             IfNode ifNode = (IfNode) deoptBegin.predecessor();
 187             LogicNode conditionNode = ifNode.condition();
 188             FixedGuardNode guard = graph.add(new FixedGuardNode(conditionNode, deoptReason, deoptAction, speculation, deoptBegin == ifNode.trueSuccessor()));
 189             FixedWithNextNode pred = (FixedWithNextNode) ifNode.predecessor();
 190             AbstractBeginNode survivingSuccessor;
 191             if (deoptBegin == ifNode.trueSuccessor()) {
 192                 survivingSuccessor = ifNode.falseSuccessor();
 193             } else {
 194                 survivingSuccessor = ifNode.trueSuccessor();
 195             }
 196             graph.removeSplitPropagate(ifNode, survivingSuccessor);
 197 
 198             Node newGuard = guard;
 199             if (survivingSuccessor instanceof LoopExitNode) {
 200                 newGuard = ProxyNode.forGuard(guard, (LoopExitNode) survivingSuccessor, graph);
 201             }
 202             survivingSuccessor.replaceAtUsages(InputType.Guard, newGuard);
 203 
 204             Debug.log("Converting deopt on %-5s branch of %s to guard for remaining branch %s.", deoptBegin == ifNode.trueSuccessor() ? "true" : "false", ifNode, survivingSuccessor);
 205             FixedNode next = pred.next();
 206             pred.setNext(guard);
 207             guard.setNext(next);
 208             SimplifierTool simplifierTool = GraphUtil.getDefaultSimplifier(null, null, null, false, graph.getAssumptions(), graph.getOptions(), loweringProvider);
 209             survivingSuccessor.simplify(simplifierTool);
 210             return;
 211         }
 212 
 213         // We could not convert the control split - at least cut off control flow after the split.
 214         FixedWithNextNode deoptPred = deoptBegin;
 215         FixedNode next = deoptPred.next();
 216 
 217         if (!(next instanceof DeoptimizeNode)) {
 218             DeoptimizeNode newDeoptNode = graph.add(new DeoptimizeNode(deoptAction, deoptReason, speculation));
 219             deoptPred.setNext(newDeoptNode);
 220             assert deoptPred == newDeoptNode.predecessor();
 221             GraphUtil.killCFG(next);
 222         }
 223     }
 224 }


   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package org.graalvm.compiler.phases.common;
  24 
  25 import static org.graalvm.compiler.phases.common.DeadCodeEliminationPhase.Optionality.Optional;
  26 
  27 import java.util.List;
  28 

  29 import org.graalvm.compiler.debug.DebugCloseable;
  30 import org.graalvm.compiler.debug.DebugContext;
  31 import org.graalvm.compiler.graph.Node;
  32 import org.graalvm.compiler.graph.spi.SimplifierTool;
  33 import org.graalvm.compiler.nodeinfo.InputType;
  34 import org.graalvm.compiler.nodes.AbstractBeginNode;
  35 import org.graalvm.compiler.nodes.AbstractEndNode;
  36 import org.graalvm.compiler.nodes.AbstractMergeNode;
  37 import org.graalvm.compiler.nodes.ConstantNode;
  38 import org.graalvm.compiler.nodes.ControlSplitNode;
  39 import org.graalvm.compiler.nodes.DeoptimizeNode;
  40 import org.graalvm.compiler.nodes.EndNode;
  41 import org.graalvm.compiler.nodes.FixedGuardNode;
  42 import org.graalvm.compiler.nodes.FixedNode;
  43 import org.graalvm.compiler.nodes.FixedWithNextNode;
  44 import org.graalvm.compiler.nodes.GuardNode;
  45 import org.graalvm.compiler.nodes.IfNode;
  46 import org.graalvm.compiler.nodes.LogicNode;
  47 import org.graalvm.compiler.nodes.LoopExitNode;
  48 import org.graalvm.compiler.nodes.ProxyNode;
  49 import org.graalvm.compiler.nodes.StructuredGraph;
  50 import org.graalvm.compiler.nodes.ValueNode;


 152                 ys = y.asConstant();
 153             } else {
 154                 ys = yPhi.valueAt(mergePredecessor).asConstant();
 155             }
 156             if (xs != null && ys != null && compare.condition().foldCondition(xs, ys, context.getConstantReflection(), compare.unorderedIsTrue()) == fixedGuard.isNegated()) {
 157                 visitDeoptBegin(AbstractBeginNode.prevBegin(mergePredecessor), fixedGuard.getAction(), fixedGuard.getReason(), fixedGuard.getSpeculation(), fixedGuard.graph(), context.getLowerer());
 158             }
 159         }
 160     }
 161 
 162     private void visitDeoptBegin(AbstractBeginNode deoptBegin, DeoptimizationAction deoptAction, DeoptimizationReason deoptReason, JavaConstant speculation, StructuredGraph graph,
 163                     LoweringProvider loweringProvider) {
 164         if (deoptBegin.predecessor() instanceof AbstractBeginNode) {
 165             /*
 166              * Walk up chains of LoopExitNodes to the "real" BeginNode that leads to deoptimization.
 167              */
 168             visitDeoptBegin((AbstractBeginNode) deoptBegin.predecessor(), deoptAction, deoptReason, speculation, graph, loweringProvider);
 169             return;
 170         }
 171 
 172         DebugContext debug = deoptBegin.getDebug();
 173         if (deoptBegin instanceof AbstractMergeNode) {
 174             AbstractMergeNode mergeNode = (AbstractMergeNode) deoptBegin;
 175             debug.log("Visiting %s", mergeNode);
 176             FixedNode next = mergeNode.next();
 177             while (mergeNode.isAlive()) {
 178                 AbstractEndNode end = mergeNode.forwardEnds().first();
 179                 AbstractBeginNode newBeginNode = AbstractBeginNode.prevBegin(end);
 180                 visitDeoptBegin(newBeginNode, deoptAction, deoptReason, speculation, graph, loweringProvider);
 181             }
 182             assert next.isAlive();
 183             AbstractBeginNode newBeginNode = AbstractBeginNode.prevBegin(next);
 184             visitDeoptBegin(newBeginNode, deoptAction, deoptReason, speculation, graph, loweringProvider);
 185             return;
 186         } else if (deoptBegin.predecessor() instanceof IfNode) {
 187             IfNode ifNode = (IfNode) deoptBegin.predecessor();
 188             LogicNode conditionNode = ifNode.condition();
 189             FixedGuardNode guard = graph.add(new FixedGuardNode(conditionNode, deoptReason, deoptAction, speculation, deoptBegin == ifNode.trueSuccessor()));
 190             FixedWithNextNode pred = (FixedWithNextNode) ifNode.predecessor();
 191             AbstractBeginNode survivingSuccessor;
 192             if (deoptBegin == ifNode.trueSuccessor()) {
 193                 survivingSuccessor = ifNode.falseSuccessor();
 194             } else {
 195                 survivingSuccessor = ifNode.trueSuccessor();
 196             }
 197             graph.removeSplitPropagate(ifNode, survivingSuccessor);
 198 
 199             Node newGuard = guard;
 200             if (survivingSuccessor instanceof LoopExitNode) {
 201                 newGuard = ProxyNode.forGuard(guard, (LoopExitNode) survivingSuccessor, graph);
 202             }
 203             survivingSuccessor.replaceAtUsages(InputType.Guard, newGuard);
 204 
 205             debug.log("Converting deopt on %-5s branch of %s to guard for remaining branch %s.", deoptBegin == ifNode.trueSuccessor() ? "true" : "false", ifNode, survivingSuccessor);
 206             FixedNode next = pred.next();
 207             pred.setNext(guard);
 208             guard.setNext(next);
 209             SimplifierTool simplifierTool = GraphUtil.getDefaultSimplifier(null, null, null, false, graph.getAssumptions(), graph.getOptions(), loweringProvider);
 210             survivingSuccessor.simplify(simplifierTool);
 211             return;
 212         }
 213 
 214         // We could not convert the control split - at least cut off control flow after the split.
 215         FixedWithNextNode deoptPred = deoptBegin;
 216         FixedNode next = deoptPred.next();
 217 
 218         if (!(next instanceof DeoptimizeNode)) {
 219             DeoptimizeNode newDeoptNode = graph.add(new DeoptimizeNode(deoptAction, deoptReason, speculation));
 220             deoptPred.setNext(newDeoptNode);
 221             assert deoptPred == newDeoptNode.predecessor();
 222             GraphUtil.killCFG(next);
 223         }
 224     }
 225 }
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConvertDeoptimizeToGuardPhase.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File