src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/GuardLoweringPhase.java
changeset 58877 aec7bf35d6f5
parent 52910 583fd71c47d6
equal deleted inserted replaced
58876:1a8d65e71a66 58877:aec7bf35d6f5
     1 /*
     1 /*
     2  * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2013, 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.
    22  */
    22  */
    23 
    23 
    24 
    24 
    25 package org.graalvm.compiler.phases.common;
    25 package org.graalvm.compiler.phases.common;
    26 
    26 
    27 import org.graalvm.compiler.core.common.cfg.Loop;
       
    28 import org.graalvm.compiler.debug.DebugCloseable;
    27 import org.graalvm.compiler.debug.DebugCloseable;
    29 import org.graalvm.compiler.debug.DebugContext;
    28 import org.graalvm.compiler.debug.DebugContext;
    30 import org.graalvm.compiler.graph.Node;
    29 import org.graalvm.compiler.graph.Node;
    31 import org.graalvm.compiler.nodes.AbstractBeginNode;
    30 import org.graalvm.compiler.nodes.AbstractBeginNode;
    32 import org.graalvm.compiler.nodes.BeginNode;
    31 import org.graalvm.compiler.nodes.BeginNode;
    33 import org.graalvm.compiler.nodes.DeoptimizeNode;
    32 import org.graalvm.compiler.nodes.DeoptimizeNode;
    34 import org.graalvm.compiler.nodes.FixedWithNextNode;
    33 import org.graalvm.compiler.nodes.FixedWithNextNode;
    35 import org.graalvm.compiler.nodes.GuardNode;
    34 import org.graalvm.compiler.nodes.GuardNode;
    36 import org.graalvm.compiler.nodes.IfNode;
    35 import org.graalvm.compiler.nodes.IfNode;
    37 import org.graalvm.compiler.nodes.LoopBeginNode;
       
    38 import org.graalvm.compiler.nodes.LoopExitNode;
       
    39 import org.graalvm.compiler.nodes.StructuredGraph;
    36 import org.graalvm.compiler.nodes.StructuredGraph;
    40 import org.graalvm.compiler.nodes.StructuredGraph.GuardsStage;
    37 import org.graalvm.compiler.nodes.StructuredGraph.GuardsStage;
    41 import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
    38 import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
    42 import org.graalvm.compiler.nodes.cfg.Block;
    39 import org.graalvm.compiler.nodes.cfg.Block;
    43 import org.graalvm.compiler.phases.BasePhase;
    40 import org.graalvm.compiler.phases.BasePhase;
    60  */
    57  */
    61 public class GuardLoweringPhase extends BasePhase<MidTierContext> {
    58 public class GuardLoweringPhase extends BasePhase<MidTierContext> {
    62 
    59 
    63     private static class LowerGuards extends ScheduledNodeIterator {
    60     private static class LowerGuards extends ScheduledNodeIterator {
    64 
    61 
    65         private final Block block;
       
    66         private boolean useGuardIdAsDebugId;
    62         private boolean useGuardIdAsDebugId;
    67 
    63 
    68         LowerGuards(Block block, boolean useGuardIdAsDebugId) {
    64         LowerGuards(boolean useGuardIdAsDebugId) {
    69             this.block = block;
       
    70             this.useGuardIdAsDebugId = useGuardIdAsDebugId;
    65             this.useGuardIdAsDebugId = useGuardIdAsDebugId;
    71         }
    66         }
    72 
    67 
    73         @Override
    68         @Override
    74         protected void processNode(Node node) {
    69         protected void processNode(Node node) {
    93                 int debugId = useGuardIdAsDebugId ? guard.getId() : DeoptimizeNode.DEFAULT_DEBUG_ID;
    88                 int debugId = useGuardIdAsDebugId ? guard.getId() : DeoptimizeNode.DEFAULT_DEBUG_ID;
    94                 DeoptimizeNode deopt = graph.add(new DeoptimizeNode(guard.getAction(), guard.getReason(), debugId, guard.getSpeculation(), null));
    89                 DeoptimizeNode deopt = graph.add(new DeoptimizeNode(guard.getAction(), guard.getReason(), debugId, guard.getSpeculation(), null));
    95                 AbstractBeginNode deoptBranch = BeginNode.begin(deopt);
    90                 AbstractBeginNode deoptBranch = BeginNode.begin(deopt);
    96                 AbstractBeginNode trueSuccessor;
    91                 AbstractBeginNode trueSuccessor;
    97                 AbstractBeginNode falseSuccessor;
    92                 AbstractBeginNode falseSuccessor;
    98                 insertLoopExits(deopt);
       
    99                 if (guard.isNegated()) {
    93                 if (guard.isNegated()) {
   100                     trueSuccessor = deoptBranch;
    94                     trueSuccessor = deoptBranch;
   101                     falseSuccessor = fastPath;
    95                     falseSuccessor = fastPath;
   102                 } else {
    96                 } else {
   103                     trueSuccessor = fastPath;
    97                     trueSuccessor = fastPath;
   104                     falseSuccessor = deoptBranch;
    98                     falseSuccessor = deoptBranch;
   105                 }
    99                 }
   106                 IfNode ifNode = graph.add(new IfNode(guard.getCondition(), trueSuccessor, falseSuccessor, trueSuccessor == fastPath ? 1 : 0));
   100                 IfNode ifNode = graph.add(new IfNode(guard.getCondition(), trueSuccessor, falseSuccessor, trueSuccessor == fastPath ? 1 : 0));
   107                 guard.replaceAndDelete(fastPath);
   101                 guard.replaceAndDelete(fastPath);
   108                 insert(ifNode, fastPath);
   102                 insert(ifNode, fastPath);
   109             }
       
   110         }
       
   111 
       
   112         private void insertLoopExits(DeoptimizeNode deopt) {
       
   113             Loop<Block> loop = block.getLoop();
       
   114             StructuredGraph graph = deopt.graph();
       
   115             while (loop != null) {
       
   116                 LoopExitNode exit = graph.add(new LoopExitNode((LoopBeginNode) loop.getHeader().getBeginNode()));
       
   117                 graph.addBeforeFixed(deopt, exit);
       
   118                 loop = loop.getParent();
       
   119             }
   103             }
   120         }
   104         }
   121     }
   105     }
   122 
   106 
   123     @Override
   107     @Override
   141         return true;
   125         return true;
   142     }
   126     }
   143 
   127 
   144     private static void processBlock(Block block, ScheduleResult schedule) {
   128     private static void processBlock(Block block, ScheduleResult schedule) {
   145         DebugContext debug = block.getBeginNode().getDebug();
   129         DebugContext debug = block.getBeginNode().getDebug();
   146         new LowerGuards(block, debug.isDumpEnabledForMethod() || debug.isLogEnabledForMethod()).processNodes(block, schedule);
   130         new LowerGuards(debug.isDumpEnabledForMethod() || debug.isLogEnabledForMethod()).processNodes(block, schedule);
   147     }
   131     }
   148 }
   132 }