src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/IntegerSwitchNode.java
author never
Wed, 27 Jun 2018 17:02:41 -0700
changeset 50858 2d3e99a72541
parent 49451 e06f9607f370
child 52910 583fd71c47d6
permissions -rw-r--r--
8205824: Update Graal Reviewed-by: iveresov, kvn
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
     1
/*
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
     2
 * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
     4
 *
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
     7
 * published by the Free Software Foundation.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
     8
 *
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    13
 * accompanied this code).
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    14
 *
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    18
 *
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    21
 * questions.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    22
 */
50858
2d3e99a72541 8205824: Update Graal
never
parents: 49451
diff changeset
    23
2d3e99a72541 8205824: Update Graal
never
parents: 49451
diff changeset
    24
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    25
package org.graalvm.compiler.nodes.extended;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    26
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    27
import java.util.ArrayList;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    28
import java.util.Arrays;
49451
e06f9607f370 8198969: Update Graal
iveresov
parents: 48190
diff changeset
    29
import java.util.Comparator;
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    30
import java.util.HashMap;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    31
import java.util.List;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    32
import java.util.Map;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    33
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    34
import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    35
import org.graalvm.compiler.core.common.type.IntegerStamp;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    36
import org.graalvm.compiler.core.common.type.PrimitiveStamp;
46344
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
    37
import org.graalvm.compiler.core.common.type.Stamp;
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
    38
import org.graalvm.compiler.core.common.type.StampFactory;
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    39
import org.graalvm.compiler.graph.NodeClass;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    40
import org.graalvm.compiler.graph.spi.Simplifiable;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    41
import org.graalvm.compiler.graph.spi.SimplifierTool;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    42
import org.graalvm.compiler.nodeinfo.NodeInfo;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    43
import org.graalvm.compiler.nodes.AbstractBeginNode;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    44
import org.graalvm.compiler.nodes.ConstantNode;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    45
import org.graalvm.compiler.nodes.FixedGuardNode;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    46
import org.graalvm.compiler.nodes.FixedWithNextNode;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    47
import org.graalvm.compiler.nodes.LogicNode;
48190
25cfedf27edc 8192814: Update Graal
dlong
parents: 47216
diff changeset
    48
import org.graalvm.compiler.nodes.NodeView;
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    49
import org.graalvm.compiler.nodes.ValueNode;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    50
import org.graalvm.compiler.nodes.calc.IntegerBelowNode;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    51
import org.graalvm.compiler.nodes.java.LoadIndexedNode;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    52
import org.graalvm.compiler.nodes.spi.LIRLowerable;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    53
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    54
import org.graalvm.compiler.nodes.util.GraphUtil;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    55
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    56
import jdk.vm.ci.meta.DeoptimizationAction;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    57
import jdk.vm.ci.meta.DeoptimizationReason;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    58
import jdk.vm.ci.meta.JavaConstant;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    59
import jdk.vm.ci.meta.JavaKind;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    60
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    61
/**
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    62
 * The {@code IntegerSwitchNode} represents a switch on integer keys, with a sorted array of key
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    63
 * values. The actual implementation of the switch will be decided by the backend.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    64
 */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    65
@NodeInfo
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    66
public final class IntegerSwitchNode extends SwitchNode implements LIRLowerable, Simplifiable {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    67
    public static final NodeClass<IntegerSwitchNode> TYPE = NodeClass.create(IntegerSwitchNode.class);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    68
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    69
    protected final int[] keys;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    70
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    71
    public IntegerSwitchNode(ValueNode value, AbstractBeginNode[] successors, int[] keys, double[] keyProbabilities, int[] keySuccessors) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    72
        super(TYPE, value, successors, keySuccessors, keyProbabilities);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    73
        assert keySuccessors.length == keys.length + 1;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    74
        assert keySuccessors.length == keyProbabilities.length;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    75
        this.keys = keys;
48190
25cfedf27edc 8192814: Update Graal
dlong
parents: 47216
diff changeset
    76
        assert value.stamp(NodeView.DEFAULT) instanceof PrimitiveStamp && value.stamp(NodeView.DEFAULT).getStackKind().isNumericInteger();
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    77
        assert assertSorted();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    78
    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    79
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    80
    private boolean assertSorted() {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    81
        for (int i = 1; i < keys.length; i++) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    82
            assert keys[i - 1] < keys[i];
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    83
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    84
        return true;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    85
    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    86
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    87
    public IntegerSwitchNode(ValueNode value, int successorCount, int[] keys, double[] keyProbabilities, int[] keySuccessors) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    88
        this(value, new AbstractBeginNode[successorCount], keys, keyProbabilities, keySuccessors);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    89
    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    90
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    91
    @Override
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    92
    public boolean isSorted() {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    93
        return true;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    94
    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    95
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    96
    /**
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    97
     * Gets the key at the specified index.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    98
     *
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    99
     * @param i the index
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   100
     * @return the key at that index
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   101
     */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   102
    @Override
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   103
    public JavaConstant keyAt(int i) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   104
        return JavaConstant.forInt(keys[i]);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   105
    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   106
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   107
    @Override
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   108
    public int keyCount() {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   109
        return keys.length;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   110
    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   111
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   112
    @Override
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   113
    public boolean equalKeys(SwitchNode switchNode) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   114
        if (!(switchNode instanceof IntegerSwitchNode)) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   115
            return false;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   116
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   117
        IntegerSwitchNode other = (IntegerSwitchNode) switchNode;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   118
        return Arrays.equals(keys, other.keys);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   119
    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   120
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   121
    @Override
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   122
    public void generate(NodeLIRBuilderTool gen) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   123
        gen.emitSwitch(this);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   124
    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   125
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   126
    public AbstractBeginNode successorAtKey(int key) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   127
        return blockSuccessor(successorIndexAtKey(key));
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   128
    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   129
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   130
    public int successorIndexAtKey(int key) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   131
        for (int i = 0; i < keyCount(); i++) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   132
            if (keys[i] == key) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   133
                return keySuccessorIndex(i);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   134
            }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   135
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   136
        return keySuccessorIndex(keyCount());
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   137
    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   138
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   139
    @Override
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   140
    public void simplify(SimplifierTool tool) {
48190
25cfedf27edc 8192814: Update Graal
dlong
parents: 47216
diff changeset
   141
        NodeView view = NodeView.from(tool);
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   142
        if (blockSuccessorCount() == 1) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   143
            tool.addToWorkList(defaultSuccessor());
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   144
            graph().removeSplitPropagate(this, defaultSuccessor());
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   145
        } else if (value() instanceof ConstantNode) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   146
            killOtherSuccessors(tool, successorIndexAtKey(value().asJavaConstant().asInt()));
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   147
        } else if (tryOptimizeEnumSwitch(tool)) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   148
            return;
48190
25cfedf27edc 8192814: Update Graal
dlong
parents: 47216
diff changeset
   149
        } else if (tryRemoveUnreachableKeys(tool, value().stamp(view))) {
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   150
            return;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   151
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   152
    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   153
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   154
    static final class KeyData {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   155
        final int key;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   156
        final double keyProbability;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   157
        final int keySuccessor;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   158
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   159
        KeyData(int key, double keyProbability, int keySuccessor) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   160
            this.key = key;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   161
            this.keyProbability = keyProbability;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   162
            this.keySuccessor = keySuccessor;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   163
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   164
    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   165
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   166
    /**
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   167
     * Remove unreachable keys from the switch based on the stamp of the value, i.e., based on the
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   168
     * known range of the switch value.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   169
     */
46344
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   170
    public boolean tryRemoveUnreachableKeys(SimplifierTool tool, Stamp valueStamp) {
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   171
        if (!(valueStamp instanceof IntegerStamp)) {
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   172
            return false;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   173
        }
46344
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   174
        IntegerStamp integerStamp = (IntegerStamp) valueStamp;
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   175
        if (integerStamp.isUnrestricted()) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   176
            return false;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   177
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   178
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   179
        List<KeyData> newKeyDatas = new ArrayList<>(keys.length);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   180
        ArrayList<AbstractBeginNode> newSuccessors = new ArrayList<>(blockSuccessorCount());
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   181
        for (int i = 0; i < keys.length; i++) {
46344
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   182
            if (integerStamp.contains(keys[i]) && keySuccessor(i) != defaultSuccessor()) {
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   183
                newKeyDatas.add(new KeyData(keys[i], keyProbabilities[i], addNewSuccessor(keySuccessor(i), newSuccessors)));
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   184
            }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   185
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   186
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   187
        if (newKeyDatas.size() == keys.length) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   188
            /* All keys are reachable. */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   189
            return false;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   190
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   191
        } else if (newKeyDatas.size() == 0) {
46344
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   192
            if (tool != null) {
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   193
                tool.addToWorkList(defaultSuccessor());
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   194
            }
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   195
            graph().removeSplitPropagate(this, defaultSuccessor());
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   196
            return true;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   197
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   198
        } else {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   199
            int newDefaultSuccessor = addNewSuccessor(defaultSuccessor(), newSuccessors);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   200
            double newDefaultProbability = keyProbabilities[keyProbabilities.length - 1];
46371
0337d0617e7b 8178088: Update Graal
iveresov
parents: 46344
diff changeset
   201
            doReplace(value(), newKeyDatas, newSuccessors, newDefaultSuccessor, newDefaultProbability);
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   202
            return true;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   203
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   204
    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   205
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   206
    /**
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   207
     * For switch statements on enum values, the Java compiler has to generate complicated code:
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   208
     * because {@link Enum#ordinal()} can change when recompiling an enum, it cannot be used
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   209
     * directly as the value that is switched on. An intermediate int[] array, which is initialized
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   210
     * once at run time based on the actual {@link Enum#ordinal()} values, is used.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   211
     *
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   212
     * The {@link ConstantFieldProvider} of Graal already detects the int[] arrays and marks them as
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   213
     * {@link ConstantNode#isDefaultStable() stable}, i.e., the array elements are constant. The
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   214
     * code in this method detects array loads from such a stable array and re-wires the switch to
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   215
     * use the keys from the array elements, so that the array load is unnecessary.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   216
     */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   217
    private boolean tryOptimizeEnumSwitch(SimplifierTool tool) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   218
        if (!(value() instanceof LoadIndexedNode)) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   219
            /* Not the switch pattern we are looking for. */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   220
            return false;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   221
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   222
        LoadIndexedNode loadIndexed = (LoadIndexedNode) value();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   223
        if (loadIndexed.usages().count() > 1) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   224
            /*
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   225
             * The array load is necessary for other reasons too, so there is no benefit optimizing
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   226
             * the switch.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   227
             */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   228
            return false;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   229
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   230
        assert loadIndexed.usages().first() == this;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   231
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   232
        ValueNode newValue = loadIndexed.index();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   233
        JavaConstant arrayConstant = loadIndexed.array().asJavaConstant();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   234
        if (arrayConstant == null || ((ConstantNode) loadIndexed.array()).getStableDimension() != 1 || !((ConstantNode) loadIndexed.array()).isDefaultStable()) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   235
            /*
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   236
             * The array is a constant that we can optimize. We require the array elements to be
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   237
             * constant too, since we put them as literal constants into the switch keys.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   238
             */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   239
            return false;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   240
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   241
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   242
        Integer optionalArrayLength = tool.getConstantReflection().readArrayLength(arrayConstant);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   243
        if (optionalArrayLength == null) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   244
            /* Loading a constant value can be denied by the VM. */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   245
            return false;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   246
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   247
        int arrayLength = optionalArrayLength;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   248
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   249
        Map<Integer, List<Integer>> reverseArrayMapping = new HashMap<>();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   250
        for (int i = 0; i < arrayLength; i++) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   251
            JavaConstant elementConstant = tool.getConstantReflection().readArrayElement(arrayConstant, i);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   252
            if (elementConstant == null || elementConstant.getJavaKind() != JavaKind.Int) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   253
                /* Loading a constant value can be denied by the VM. */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   254
                return false;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   255
            }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   256
            int element = elementConstant.asInt();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   257
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   258
            /*
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   259
             * The value loaded from the array is the old switch key, the index into the array is
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   260
             * the new switch key. We build a mapping from the old switch key to new keys.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   261
             */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   262
            reverseArrayMapping.computeIfAbsent(element, e -> new ArrayList<>()).add(i);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   263
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   264
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   265
        /* Build high-level representation of new switch keys. */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   266
        List<KeyData> newKeyDatas = new ArrayList<>(arrayLength);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   267
        ArrayList<AbstractBeginNode> newSuccessors = new ArrayList<>(blockSuccessorCount());
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   268
        for (int i = 0; i < keys.length; i++) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   269
            List<Integer> newKeys = reverseArrayMapping.get(keys[i]);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   270
            if (newKeys == null || newKeys.size() == 0) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   271
                /* The switch case is unreachable, we can ignore it. */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   272
                continue;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   273
            }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   274
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   275
            /*
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   276
             * We do not have detailed profiling information about the individual new keys, so we
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   277
             * have to assume they split the probability of the old key.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   278
             */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   279
            double newKeyProbability = keyProbabilities[i] / newKeys.size();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   280
            int newKeySuccessor = addNewSuccessor(keySuccessor(i), newSuccessors);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   281
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   282
            for (int newKey : newKeys) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   283
                newKeyDatas.add(new KeyData(newKey, newKeyProbability, newKeySuccessor));
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   284
            }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   285
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   286
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   287
        int newDefaultSuccessor = addNewSuccessor(defaultSuccessor(), newSuccessors);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   288
        double newDefaultProbability = keyProbabilities[keyProbabilities.length - 1];
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   289
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   290
        /*
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   291
         * We remove the array load, but we still need to preserve exception semantics by keeping
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   292
         * the bounds check. Fortunately the array length is a constant.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   293
         */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   294
        LogicNode boundsCheck = graph().unique(new IntegerBelowNode(newValue, ConstantNode.forInt(arrayLength, graph())));
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   295
        graph().addBeforeFixed(this, graph().add(new FixedGuardNode(boundsCheck, DeoptimizationReason.BoundsCheckException, DeoptimizationAction.InvalidateReprofile)));
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   296
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   297
        /*
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   298
         * Build the low-level representation of the new switch keys and replace ourself with a new
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   299
         * node.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   300
         */
46371
0337d0617e7b 8178088: Update Graal
iveresov
parents: 46344
diff changeset
   301
        doReplace(newValue, newKeyDatas, newSuccessors, newDefaultSuccessor, newDefaultProbability);
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   302
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   303
        /* The array load is now unnecessary. */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   304
        assert loadIndexed.hasNoUsages();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   305
        GraphUtil.removeFixedWithUnusedInputs(loadIndexed);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   306
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   307
        return true;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   308
    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   309
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   310
    private static int addNewSuccessor(AbstractBeginNode newSuccessor, ArrayList<AbstractBeginNode> newSuccessors) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   311
        int index = newSuccessors.indexOf(newSuccessor);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   312
        if (index == -1) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   313
            index = newSuccessors.size();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   314
            newSuccessors.add(newSuccessor);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   315
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   316
        return index;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   317
    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   318
46371
0337d0617e7b 8178088: Update Graal
iveresov
parents: 46344
diff changeset
   319
    private void doReplace(ValueNode newValue, List<KeyData> newKeyDatas, ArrayList<AbstractBeginNode> newSuccessors, int newDefaultSuccessor, double newDefaultProbability) {
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   320
        /* Sort the new keys (invariant of the IntegerSwitchNode). */
49451
e06f9607f370 8198969: Update Graal
iveresov
parents: 48190
diff changeset
   321
        newKeyDatas.sort(Comparator.comparingInt(k -> k.key));
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   322
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   323
        /* Create the final data arrays. */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   324
        int newKeyCount = newKeyDatas.size();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   325
        int[] newKeys = new int[newKeyCount];
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   326
        double[] newKeyProbabilities = new double[newKeyCount + 1];
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   327
        int[] newKeySuccessors = new int[newKeyCount + 1];
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   328
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   329
        for (int i = 0; i < newKeyCount; i++) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   330
            KeyData keyData = newKeyDatas.get(i);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   331
            newKeys[i] = keyData.key;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   332
            newKeyProbabilities[i] = keyData.keyProbability;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   333
            newKeySuccessors[i] = keyData.keySuccessor;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   334
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   335
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   336
        newKeySuccessors[newKeyCount] = newDefaultSuccessor;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   337
        newKeyProbabilities[newKeyCount] = newDefaultProbability;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   338
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   339
        /* Normalize new probabilities so that they sum up to 1. */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   340
        double totalProbability = 0;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   341
        for (double probability : newKeyProbabilities) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   342
            totalProbability += probability;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   343
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   344
        if (totalProbability > 0) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   345
            for (int i = 0; i < newKeyProbabilities.length; i++) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   346
                newKeyProbabilities[i] /= totalProbability;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   347
            }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   348
        } else {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   349
            for (int i = 0; i < newKeyProbabilities.length; i++) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   350
                newKeyProbabilities[i] = 1.0 / newKeyProbabilities.length;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   351
            }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   352
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   353
49451
e06f9607f370 8198969: Update Graal
iveresov
parents: 48190
diff changeset
   354
        /*
e06f9607f370 8198969: Update Graal
iveresov
parents: 48190
diff changeset
   355
         * Collect dead successors. Successors have to be cleaned before adding the new node to the
e06f9607f370 8198969: Update Graal
iveresov
parents: 48190
diff changeset
   356
         * graph.
e06f9607f370 8198969: Update Graal
iveresov
parents: 48190
diff changeset
   357
         */
e06f9607f370 8198969: Update Graal
iveresov
parents: 48190
diff changeset
   358
        List<AbstractBeginNode> deadSuccessors = successors.filter(s -> !newSuccessors.contains(s)).snapshot();
e06f9607f370 8198969: Update Graal
iveresov
parents: 48190
diff changeset
   359
        successors.clear();
e06f9607f370 8198969: Update Graal
iveresov
parents: 48190
diff changeset
   360
e06f9607f370 8198969: Update Graal
iveresov
parents: 48190
diff changeset
   361
        /*
e06f9607f370 8198969: Update Graal
iveresov
parents: 48190
diff changeset
   362
         * Create the new switch node. This is done before removing dead successors as `killCFG`
e06f9607f370 8198969: Update Graal
iveresov
parents: 48190
diff changeset
   363
         * could edit some of the inputs (e.g., if `newValue` is a loop-phi of the loop that dies
e06f9607f370 8198969: Update Graal
iveresov
parents: 48190
diff changeset
   364
         * while removing successors).
e06f9607f370 8198969: Update Graal
iveresov
parents: 48190
diff changeset
   365
         */
e06f9607f370 8198969: Update Graal
iveresov
parents: 48190
diff changeset
   366
        AbstractBeginNode[] successorsArray = newSuccessors.toArray(new AbstractBeginNode[newSuccessors.size()]);
e06f9607f370 8198969: Update Graal
iveresov
parents: 48190
diff changeset
   367
        SwitchNode newSwitch = graph().add(new IntegerSwitchNode(newValue, successorsArray, newKeys, newKeyProbabilities, newKeySuccessors));
e06f9607f370 8198969: Update Graal
iveresov
parents: 48190
diff changeset
   368
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   369
        /* Remove dead successors. */
49451
e06f9607f370 8198969: Update Graal
iveresov
parents: 48190
diff changeset
   370
        for (AbstractBeginNode successor : deadSuccessors) {
e06f9607f370 8198969: Update Graal
iveresov
parents: 48190
diff changeset
   371
            GraphUtil.killCFG(successor);
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   372
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   373
49451
e06f9607f370 8198969: Update Graal
iveresov
parents: 48190
diff changeset
   374
        /* Replace ourselves with the new switch */
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   375
        ((FixedWithNextNode) predecessor()).setNext(newSwitch);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   376
        GraphUtil.killWithUnusedFloatingInputs(this);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   377
    }
46344
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   378
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   379
    @Override
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   380
    public Stamp getValueStampForSuccessor(AbstractBeginNode beginNode) {
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   381
        Stamp result = null;
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   382
        if (beginNode != this.defaultSuccessor()) {
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   383
            for (int i = 0; i < keyCount(); i++) {
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   384
                if (keySuccessor(i) == beginNode) {
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   385
                    if (result == null) {
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   386
                        result = StampFactory.forConstant(keyAt(i));
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   387
                    } else {
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   388
                        result = result.meet(StampFactory.forConstant(keyAt(i)));
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   389
                    }
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   390
                }
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   391
            }
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   392
        }
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   393
        return result;
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   394
    }
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   395
}