src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/ConvertDeoptimizeToGuardPhase.java
author chegar
Thu, 17 Oct 2019 20:54:25 +0100
branchdatagramsocketimpl-branch
changeset 58679 9c3209ff7550
parent 58678 9cf78a70fa4f
parent 58299 6df94ce3ab2f
permissions -rw-r--r--
datagramsocketimpl-branch: merge with default
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
54084
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
     1
/*
58299
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 55509
diff changeset
     2
 * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
54084
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
     4
 *
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
     7
 * published by the Free Software Foundation.
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
     8
 *
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    13
 * accompanied this code).
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    14
 *
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    18
 *
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    21
 * questions.
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    22
 */
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    23
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    24
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    25
package org.graalvm.compiler.loop.phases;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    26
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    27
import static org.graalvm.compiler.phases.common.DeadCodeEliminationPhase.Optionality.Optional;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    28
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    29
import java.util.List;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    30
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    31
import org.graalvm.compiler.core.common.GraalOptions;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    32
import org.graalvm.compiler.core.common.cfg.Loop;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    33
import org.graalvm.compiler.debug.DebugCloseable;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    34
import org.graalvm.compiler.graph.Node;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    35
import org.graalvm.compiler.graph.NodeSourcePosition;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    36
import org.graalvm.compiler.graph.spi.SimplifierTool;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    37
import org.graalvm.compiler.loop.LoopEx;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    38
import org.graalvm.compiler.loop.LoopsData;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    39
import org.graalvm.compiler.nodeinfo.InputType;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    40
import org.graalvm.compiler.nodes.AbstractBeginNode;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    41
import org.graalvm.compiler.nodes.AbstractEndNode;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    42
import org.graalvm.compiler.nodes.AbstractMergeNode;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    43
import org.graalvm.compiler.nodes.ConstantNode;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    44
import org.graalvm.compiler.nodes.ControlSplitNode;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    45
import org.graalvm.compiler.nodes.DeoptimizeNode;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    46
import org.graalvm.compiler.nodes.EndNode;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    47
import org.graalvm.compiler.nodes.FixedGuardNode;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    48
import org.graalvm.compiler.nodes.FixedNode;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    49
import org.graalvm.compiler.nodes.FixedWithNextNode;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    50
import org.graalvm.compiler.nodes.GuardNode;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    51
import org.graalvm.compiler.nodes.IfNode;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    52
import org.graalvm.compiler.nodes.LogicNode;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    53
import org.graalvm.compiler.nodes.LoopExitNode;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    54
import org.graalvm.compiler.nodes.ProxyNode;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    55
import org.graalvm.compiler.nodes.StartNode;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    56
import org.graalvm.compiler.nodes.StaticDeoptimizingNode;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    57
import org.graalvm.compiler.nodes.StructuredGraph;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    58
import org.graalvm.compiler.nodes.ValueNode;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    59
import org.graalvm.compiler.nodes.ValuePhiNode;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    60
import org.graalvm.compiler.nodes.calc.CompareNode;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    61
import org.graalvm.compiler.nodes.cfg.Block;
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54084
diff changeset
    62
import org.graalvm.compiler.nodes.spi.CoreProviders;
54084
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    63
import org.graalvm.compiler.nodes.spi.LoweringProvider;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    64
import org.graalvm.compiler.nodes.util.GraphUtil;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    65
import org.graalvm.compiler.phases.BasePhase;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    66
import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    67
import org.graalvm.compiler.phases.common.LazyValue;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    68
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    69
import jdk.vm.ci.meta.Constant;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    70
import jdk.vm.ci.meta.DeoptimizationAction;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    71
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    72
/**
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    73
 * This phase will find branches which always end with a {@link DeoptimizeNode} and replace their
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    74
 * {@link ControlSplitNode ControlSplitNodes} with {@link FixedGuardNode FixedGuardNodes}.
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    75
 *
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    76
 * This is useful because {@link FixedGuardNode FixedGuardNodes} will be lowered to {@link GuardNode
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    77
 * GuardNodes} which can later be optimized more aggressively than control-flow constructs.
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    78
 *
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    79
 * This is currently only done for branches that start from a {@link IfNode}. If it encounters a
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    80
 * branch starting at an other kind of {@link ControlSplitNode}, it will only bring the
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    81
 * {@link DeoptimizeNode} as close to the {@link ControlSplitNode} as possible.
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    82
 *
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    83
 */
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54084
diff changeset
    84
public class ConvertDeoptimizeToGuardPhase extends BasePhase<CoreProviders> {
54084
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    85
    @Override
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    86
    @SuppressWarnings("try")
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54084
diff changeset
    87
    protected void run(final StructuredGraph graph, CoreProviders context) {
54084
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    88
        assert graph.hasValueProxies() : "ConvertDeoptimizeToGuardPhase always creates proxies";
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    89
        assert !graph.getGuardsStage().areFrameStatesAtDeopts() : graph.getGuardsStage();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    90
        LazyValue<LoopsData> lazyLoops = new LazyValue<>(() -> new LoopsData(graph));
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    91
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    92
        for (DeoptimizeNode d : graph.getNodes(DeoptimizeNode.TYPE)) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    93
            assert d.isAlive();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    94
            if (d.getAction() == DeoptimizationAction.None) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    95
                continue;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    96
            }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    97
            try (DebugCloseable closable = d.withNodeSourcePosition()) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    98
                propagateFixed(d, d, context != null ? context.getLowerer() : null, lazyLoops);
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
    99
            }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   100
        }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   101
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   102
        if (context != null) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   103
            for (FixedGuardNode fixedGuard : graph.getNodes(FixedGuardNode.TYPE)) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   104
                try (DebugCloseable closable = fixedGuard.withNodeSourcePosition()) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   105
                    trySplitFixedGuard(fixedGuard, context, lazyLoops);
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   106
                }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   107
            }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   108
        }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   109
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   110
        new DeadCodeEliminationPhase(Optional).apply(graph);
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   111
    }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   112
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54084
diff changeset
   113
    private static void trySplitFixedGuard(FixedGuardNode fixedGuard, CoreProviders context, LazyValue<LoopsData> lazyLoops) {
54084
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   114
        LogicNode condition = fixedGuard.condition();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   115
        if (condition instanceof CompareNode) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   116
            CompareNode compare = (CompareNode) condition;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   117
            ValueNode x = compare.getX();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   118
            ValuePhiNode xPhi = (x instanceof ValuePhiNode) ? (ValuePhiNode) x : null;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   119
            if (x instanceof ConstantNode || xPhi != null) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   120
                ValueNode y = compare.getY();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   121
                ValuePhiNode yPhi = (y instanceof ValuePhiNode) ? (ValuePhiNode) y : null;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   122
                if (y instanceof ConstantNode || yPhi != null) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   123
                    processFixedGuardAndPhis(fixedGuard, context, compare, x, xPhi, y, yPhi, lazyLoops);
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   124
                }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   125
            }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   126
        }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   127
    }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   128
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54084
diff changeset
   129
    private static void processFixedGuardAndPhis(FixedGuardNode fixedGuard, CoreProviders context, CompareNode compare, ValueNode x, ValuePhiNode xPhi, ValueNode y, ValuePhiNode yPhi,
54084
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   130
                    LazyValue<LoopsData> lazyLoops) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   131
        AbstractBeginNode pred = AbstractBeginNode.prevBegin(fixedGuard);
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   132
        if (pred instanceof AbstractMergeNode) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   133
            AbstractMergeNode merge = (AbstractMergeNode) pred;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   134
            if (xPhi != null && xPhi.merge() != merge) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   135
                return;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   136
            }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   137
            if (yPhi != null && yPhi.merge() != merge) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   138
                return;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   139
            }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   140
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   141
            processFixedGuardAndMerge(fixedGuard, context, compare, x, xPhi, y, yPhi, merge, lazyLoops);
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   142
        }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   143
    }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   144
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   145
    @SuppressWarnings("try")
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54084
diff changeset
   146
    private static void processFixedGuardAndMerge(FixedGuardNode fixedGuard, CoreProviders context, CompareNode compare, ValueNode x, ValuePhiNode xPhi, ValueNode y, ValuePhiNode yPhi,
54084
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   147
                    AbstractMergeNode merge, LazyValue<LoopsData> lazyLoops) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   148
        List<EndNode> mergePredecessors = merge.cfgPredecessors().snapshot();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   149
        for (AbstractEndNode mergePredecessor : mergePredecessors) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   150
            if (!mergePredecessor.isAlive()) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   151
                break;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   152
            }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   153
            Constant xs;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   154
            if (xPhi == null) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   155
                xs = x.asConstant();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   156
            } else {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   157
                xs = xPhi.valueAt(mergePredecessor).asConstant();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   158
            }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   159
            Constant ys;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   160
            if (yPhi == null) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   161
                ys = y.asConstant();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   162
            } else {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   163
                ys = yPhi.valueAt(mergePredecessor).asConstant();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   164
            }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   165
            if (xs != null && ys != null && compare.condition().foldCondition(xs, ys, context.getConstantReflection(), compare.unorderedIsTrue()) == fixedGuard.isNegated()) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   166
                try (DebugCloseable position = fixedGuard.withNodeSourcePosition()) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   167
                    propagateFixed(mergePredecessor, fixedGuard, context.getLowerer(), lazyLoops);
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   168
                }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   169
            }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   170
        }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   171
    }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   172
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   173
    @SuppressWarnings("try")
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   174
    private static void propagateFixed(FixedNode from, StaticDeoptimizingNode deopt, LoweringProvider loweringProvider, LazyValue<LoopsData> lazyLoops) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   175
        Node current = from;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   176
        while (current != null) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   177
            if (GraalOptions.GuardPriorities.getValue(from.getOptions()) && current instanceof FixedGuardNode) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   178
                FixedGuardNode otherGuard = (FixedGuardNode) current;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   179
                if (otherGuard.computePriority().isHigherPriorityThan(deopt.computePriority())) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   180
                    moveAsDeoptAfter(otherGuard, deopt);
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   181
                    return;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   182
                }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   183
            } else if (current instanceof AbstractBeginNode) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   184
                if (current instanceof AbstractMergeNode) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   185
                    AbstractMergeNode mergeNode = (AbstractMergeNode) current;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   186
                    FixedNode next = mergeNode.next();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   187
                    while (mergeNode.isAlive()) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   188
                        AbstractEndNode end = mergeNode.forwardEnds().first();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   189
                        propagateFixed(end, deopt, loweringProvider, lazyLoops);
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   190
                    }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   191
                    if (next.isAlive()) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   192
                        propagateFixed(next, deopt, loweringProvider, lazyLoops);
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   193
                    }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   194
                    return;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   195
                } else if (current.predecessor() instanceof IfNode) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   196
                    AbstractBeginNode begin = (AbstractBeginNode) current;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   197
                    IfNode ifNode = (IfNode) current.predecessor();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   198
                    if (isOsrLoopExit(begin) || isCountedLoopExit(ifNode, lazyLoops)) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   199
                        moveAsDeoptAfter(begin, deopt);
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   200
                    } else {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   201
                        // Prioritize the source position of the IfNode
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   202
                        try (DebugCloseable closable = ifNode.withNodeSourcePosition()) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   203
                            StructuredGraph graph = ifNode.graph();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   204
                            LogicNode conditionNode = ifNode.condition();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   205
                            boolean negateGuardCondition = current == ifNode.trueSuccessor();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   206
                            NodeSourcePosition survivingSuccessorPosition = negateGuardCondition ? ifNode.falseSuccessor().getNodeSourcePosition() : ifNode.trueSuccessor().getNodeSourcePosition();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   207
                            FixedGuardNode guard = graph.add(
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   208
                                            new FixedGuardNode(conditionNode, deopt.getReason(), deopt.getAction(), deopt.getSpeculation(), negateGuardCondition, survivingSuccessorPosition));
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   209
                            FixedWithNextNode pred = (FixedWithNextNode) ifNode.predecessor();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   210
                            AbstractBeginNode survivingSuccessor;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   211
                            if (negateGuardCondition) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   212
                                survivingSuccessor = ifNode.falseSuccessor();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   213
                            } else {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   214
                                survivingSuccessor = ifNode.trueSuccessor();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   215
                            }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   216
                            graph.removeSplitPropagate(ifNode, survivingSuccessor);
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   217
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   218
                            Node newGuard = guard;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   219
                            if (survivingSuccessor instanceof LoopExitNode) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   220
                                newGuard = ProxyNode.forGuard(guard, (LoopExitNode) survivingSuccessor, graph);
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   221
                            }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   222
                            survivingSuccessor.replaceAtUsages(InputType.Guard, newGuard);
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   223
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   224
                            graph.getDebug().log("Converting deopt on %-5s branch of %s to guard for remaining branch %s.", negateGuardCondition, ifNode, survivingSuccessor);
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   225
                            FixedNode next = pred.next();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   226
                            pred.setNext(guard);
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   227
                            guard.setNext(next);
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   228
                            SimplifierTool simplifierTool = GraphUtil.getDefaultSimplifier(null, null, null, false, graph.getAssumptions(), graph.getOptions(), loweringProvider);
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   229
                            survivingSuccessor.simplify(simplifierTool);
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   230
                        }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   231
                    }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   232
                    return;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   233
                } else if (current.predecessor() == null || current.predecessor() instanceof ControlSplitNode) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   234
                    assert current.predecessor() != null || (current instanceof StartNode && current == ((AbstractBeginNode) current).graph().start());
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   235
                    moveAsDeoptAfter((AbstractBeginNode) current, deopt);
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   236
                    return;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   237
                }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   238
            }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   239
            current = current.predecessor();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   240
        }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   241
    }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   242
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   243
    @SuppressWarnings("try")
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   244
    private static void moveAsDeoptAfter(FixedWithNextNode node, StaticDeoptimizingNode deopt) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   245
        try (DebugCloseable position = deopt.asNode().withNodeSourcePosition()) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   246
            FixedNode next = node.next();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   247
            if (next != deopt.asNode()) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   248
                node.setNext(node.graph().add(new DeoptimizeNode(deopt.getAction(), deopt.getReason(), deopt.getSpeculation())));
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   249
                GraphUtil.killCFG(next);
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   250
            }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   251
        }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   252
    }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   253
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   254
    private static boolean isOsrLoopExit(AbstractBeginNode node) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   255
        if (!(node instanceof LoopExitNode)) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   256
            return false;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   257
        }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   258
        return ((LoopExitNode) node).loopBegin().isOsrLoop();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   259
    }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   260
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   261
    private static boolean isCountedLoopExit(IfNode ifNode, LazyValue<LoopsData> lazyLoops) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   262
        LoopsData loopsData = lazyLoops.get();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   263
        Loop<Block> loop = loopsData.getCFG().getNodeToBlock().get(ifNode).getLoop();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   264
        if (loop != null) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   265
            LoopEx loopEx = loopsData.loop(loop);
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   266
            if (loopEx.detectCounted()) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   267
                return ifNode == loopEx.counted().getLimitTest();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   268
            }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   269
        }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   270
        return false;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   271
    }
84f10bbf993f 8218074: Update Graal
jwilhelm
parents:
diff changeset
   272
}