src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/RedundantMoveElimination.java
author iveresov
Fri, 02 Feb 2018 17:28:17 -0800
changeset 48861 47f19ff9903c
parent 47798 9fe9292f5931
child 49873 26ebfe8ce852
permissions -rw-r--r--
8194819: Update Graal Reviewed-by: 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) 2013, 2016, 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
 */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    23
package org.graalvm.compiler.lir;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    24
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    25
import static jdk.vm.ci.code.ValueUtil.isRegister;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    26
import static jdk.vm.ci.code.ValueUtil.isStackSlot;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    27
46344
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
    28
import java.util.ArrayList;
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    29
import java.util.Arrays;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    30
import java.util.Collections;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    31
import java.util.EnumSet;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    32
48861
47f19ff9903c 8194819: Update Graal
iveresov
parents: 47798
diff changeset
    33
import org.graalvm.collections.EconomicMap;
47f19ff9903c 8194819: Update Graal
iveresov
parents: 47798
diff changeset
    34
import org.graalvm.collections.Equivalence;
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    35
import org.graalvm.compiler.core.common.LIRKind;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    36
import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46459
diff changeset
    37
import org.graalvm.compiler.debug.CounterKey;
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46459
diff changeset
    38
import org.graalvm.compiler.debug.DebugContext;
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    39
import org.graalvm.compiler.debug.Indent;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    40
import org.graalvm.compiler.lir.LIRInstruction.OperandFlag;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    41
import org.graalvm.compiler.lir.LIRInstruction.OperandMode;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    42
import org.graalvm.compiler.lir.StandardOp.MoveOp;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    43
import org.graalvm.compiler.lir.StandardOp.ValueMoveOp;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    44
import org.graalvm.compiler.lir.framemap.FrameMap;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    45
import org.graalvm.compiler.lir.gen.LIRGenerationResult;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    46
import org.graalvm.compiler.lir.phases.PostAllocationOptimizationPhase;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    47
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    48
import jdk.vm.ci.code.Register;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    49
import jdk.vm.ci.code.RegisterArray;
48861
47f19ff9903c 8194819: Update Graal
iveresov
parents: 47798
diff changeset
    50
import jdk.vm.ci.code.RegisterConfig;
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    51
import jdk.vm.ci.code.RegisterValue;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    52
import jdk.vm.ci.code.StackSlot;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    53
import jdk.vm.ci.code.TargetDescription;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    54
import jdk.vm.ci.meta.Value;
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
/**
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    57
 * Removes move instructions, where the destination value is already in place.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    58
 */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    59
public final class RedundantMoveElimination extends PostAllocationOptimizationPhase {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    60
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46459
diff changeset
    61
    private static final CounterKey deletedMoves = DebugContext.counter("RedundantMovesEliminated");
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    62
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    63
    @Override
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    64
    protected void run(TargetDescription target, LIRGenerationResult lirGenRes, PostAllocationOptimizationContext context) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    65
        Optimization redundantMoveElimination = new Optimization(lirGenRes.getFrameMap());
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    66
        redundantMoveElimination.doOptimize(lirGenRes.getLIR());
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    67
    }
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
    /**
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    70
     * Holds the entry and exit states for each block for dataflow analysis. The state is an array
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    71
     * with an element for each relevant location (register or stack slot). Each element holds the
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    72
     * global number of the location's definition. A location definition is simply an output of an
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    73
     * instruction. Note that because instructions can have multiple outputs it is not possible to
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    74
     * use the instruction id for value numbering. In addition, the result of merging at block
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    75
     * entries (= phi values) get unique value numbers.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    76
     *
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    77
     * The value numbers also contain information if it is an object kind value or not: if the
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    78
     * number is negative it is an object kind value.
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 static final class BlockData {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    81
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    82
        BlockData(int stateSize) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    83
            entryState = new int[stateSize];
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    84
            exitState = new int[stateSize];
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
        /*
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    88
         * The state at block entry for global dataflow analysis. It contains a global value number
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    89
         * for each location to optimize.
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
        int[] entryState;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    92
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    93
        /*
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    94
         * The state at block exit for global dataflow analysis. It contains a global value number
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    95
         * for each location to optimize.
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
        int[] exitState;
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
        /*
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   100
         * The starting number for global value numbering in this block.
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
        int entryValueNum;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   103
    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   104
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   105
    private static final class Optimization {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   106
46344
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   107
        EconomicMap<AbstractBlockBase<?>, BlockData> blockData = EconomicMap.create(Equivalence.IDENTITY);
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   108
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   109
        RegisterArray callerSaveRegs;
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
         * Contains the register number for registers which can be optimized and -1 for the others.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   113
         */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   114
        int[] eligibleRegs;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   115
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
         * A map from the {@link StackSlot} {@link #getOffset offset} to an index into the state.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   118
         * StackSlots of different kinds that map to the same location will map to the same index.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   119
         */
46344
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   120
        EconomicMap<Integer, Integer> stackIndices = EconomicMap.create(Equivalence.DEFAULT);
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   121
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   122
        int numRegs;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   123
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   124
        private final FrameMap frameMap;
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
        /*
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   127
         * Pseudo value for a not yet assigned location.
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
        static final int INIT_VALUE = 0;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   130
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   131
        Optimization(FrameMap frameMap) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   132
            this.frameMap = frameMap;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   133
        }
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
         * The main method doing the elimination of redundant moves.
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
        @SuppressWarnings("try")
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   139
        private void doOptimize(LIR lir) {
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46459
diff changeset
   140
            DebugContext debug = lir.getDebug();
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46459
diff changeset
   141
            try (Indent indent = debug.logAndIndent("eliminate redundant moves")) {
47798
9fe9292f5931 8190710: Update Graal
dlong
parents: 47216
diff changeset
   142
                RegisterConfig registerConfig = frameMap.getRegisterConfig();
9fe9292f5931 8190710: Update Graal
dlong
parents: 47216
diff changeset
   143
                callerSaveRegs = registerConfig.getCallerSaveRegisters();
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   144
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   145
                initBlockData(lir);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   146
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   147
                // Compute a table of the registers which are eligible for move optimization.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   148
                // Unallocatable registers should never be optimized.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   149
                eligibleRegs = new int[numRegs];
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   150
                Arrays.fill(eligibleRegs, -1);
47798
9fe9292f5931 8190710: Update Graal
dlong
parents: 47216
diff changeset
   151
                for (Register reg : registerConfig.getAllocatableRegisters()) {
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   152
                    if (reg.number < numRegs) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   153
                        eligibleRegs[reg.number] = reg.number;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   154
                    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   155
                }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   156
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   157
                if (!solveDataFlow(lir)) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   158
                    return;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   159
                }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   160
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   161
                eliminateMoves(lir);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   162
            }
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
         * The maximum number of locations * blocks. This is a complexity limit for the inner loop
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   167
         * in {@link #mergeState} (assuming a small number of iterations in {@link #solveDataFlow}.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   168
         */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   169
        private static final int COMPLEXITY_LIMIT = 30000;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   170
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   171
        private void initBlockData(LIR lir) {
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46459
diff changeset
   172
            DebugContext debug = lir.getDebug();
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   173
            AbstractBlockBase<?>[] blocks = lir.linearScanOrder();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   174
            numRegs = 0;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   175
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   176
            int maxStackLocations = COMPLEXITY_LIMIT / blocks.length;
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
             * Search for relevant locations which can be optimized. These are register or stack
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   180
             * slots which occur as destinations of move instructions.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   181
             */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   182
            for (AbstractBlockBase<?> block : blocks) {
46344
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   183
                ArrayList<LIRInstruction> instructions = lir.getLIRforBlock(block);
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   184
                for (LIRInstruction op : instructions) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   185
                    if (isEligibleMove(op)) {
46459
7d4e637d3f21 8180267: Update Graal
kvn
parents: 46393
diff changeset
   186
                        Value dest = MoveOp.asMoveOp(op).getResult();
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   187
                        if (isRegister(dest)) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   188
                            int regNum = ((RegisterValue) dest).getRegister().number;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   189
                            if (regNum >= numRegs) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   190
                                numRegs = regNum + 1;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   191
                            }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   192
                        } else if (isStackSlot(dest)) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   193
                            StackSlot stackSlot = (StackSlot) dest;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   194
                            Integer offset = getOffset(stackSlot);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   195
                            if (!stackIndices.containsKey(offset) && stackIndices.size() < maxStackLocations) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   196
                                stackIndices.put(offset, stackIndices.size());
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
                        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   199
                    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   200
                }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   201
            }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   202
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
             * Now we know the number of locations to optimize, so we can allocate the block states.
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
            int numLocations = numRegs + stackIndices.size();
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46459
diff changeset
   207
            debug.log("num locations = %d (regs = %d, stack = %d)", numLocations, numRegs, stackIndices.size());
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   208
            for (AbstractBlockBase<?> block : blocks) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   209
                BlockData data = new BlockData(numLocations);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   210
                blockData.put(block, data);
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
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   213
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   214
        private int getOffset(StackSlot stackSlot) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   215
            return stackSlot.getOffset(frameMap.totalFrameSize());
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
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   218
        /**
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   219
         * Calculates the entry and exit states for all basic blocks.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   220
         *
46371
0337d0617e7b 8178088: Update Graal
iveresov
parents: 46344
diff changeset
   221
         * @return Returns true on success and false if the control flow is too complex.
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   222
         */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   223
        @SuppressWarnings("try")
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   224
        private boolean solveDataFlow(LIR lir) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   225
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46459
diff changeset
   226
            DebugContext debug = lir.getDebug();
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46459
diff changeset
   227
            try (Indent indent = debug.logAndIndent("solve data flow")) {
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   228
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   229
                AbstractBlockBase<?>[] blocks = lir.linearScanOrder();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   230
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   231
                int numIter = 0;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   232
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   233
                /*
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   234
                 * Iterate until there are no more changes.
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
                int currentValueNum = 1;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   237
                boolean firstRound = true;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   238
                boolean changed;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   239
                do {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   240
                    changed = false;
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46459
diff changeset
   241
                    try (Indent indent2 = debug.logAndIndent("new iteration")) {
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   242
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   243
                        for (AbstractBlockBase<?> block : blocks) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   244
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   245
                            BlockData data = blockData.get(block);
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
                             * Initialize the number for global value numbering for this block. It
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   248
                             * is essential that the starting number for a block is consistent at
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   249
                             * all iterations and also in eliminateMoves().
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   250
                             */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   251
                            if (firstRound) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   252
                                data.entryValueNum = currentValueNum;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   253
                            }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   254
                            int valueNum = data.entryValueNum;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   255
                            assert valueNum > 0;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   256
                            boolean newState = false;
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
                            if (block == blocks[0] || block.isExceptionEntry()) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   259
                                /*
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   260
                                 * The entry block has undefined values. And also exception handler
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   261
                                 * blocks: the LinearScan can insert moves at the end of an
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   262
                                 * exception handler predecessor block (after the invoke, which
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   263
                                 * throws the exception), and in reality such moves are not in the
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   264
                                 * control flow in case of an exception. So we assume a save default
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   265
                                 * for exception handler blocks.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   266
                                 */
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46459
diff changeset
   267
                                debug.log("kill all values at entry of block %d", block.getId());
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   268
                                clearValues(data.entryState, valueNum);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   269
                            } else {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   270
                                /*
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   271
                                 * Merge the states of predecessor blocks
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   272
                                 */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   273
                                for (AbstractBlockBase<?> predecessor : block.getPredecessors()) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   274
                                    BlockData predData = blockData.get(predecessor);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   275
                                    newState |= mergeState(data.entryState, predData.exitState, valueNum);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   276
                                }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   277
                            }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   278
                            // Advance by the value numbers which are "consumed" by
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   279
                            // clearValues and mergeState
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   280
                            valueNum += data.entryState.length;
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
                            if (newState || firstRound) {
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46459
diff changeset
   283
                                try (Indent indent3 = debug.logAndIndent("update block %d", block.getId())) {
43972
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
                                     * Derive the exit state from the entry state by iterating
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   287
                                     * through all instructions of the block.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   288
                                     */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   289
                                    int[] iterState = data.exitState;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   290
                                    copyState(iterState, data.entryState);
46344
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   291
                                    ArrayList<LIRInstruction> instructions = lir.getLIRforBlock(block);
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   292
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   293
                                    for (LIRInstruction op : instructions) {
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46459
diff changeset
   294
                                        valueNum = updateState(debug, iterState, op, valueNum);
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   295
                                    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   296
                                    changed = true;
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
                            }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   299
                            if (firstRound) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   300
                                currentValueNum = valueNum;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   301
                            }
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
                        firstRound = false;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   304
                    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   305
                    numIter++;
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
                    if (numIter > 5) {
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
                         * This is _very_ seldom.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   310
                         */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   311
                        return false;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   312
                    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   313
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   314
                } while (changed);
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
            }
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
            return true;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   319
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   320
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   321
        /**
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   322
         * Deletes all move instructions where the target location already contains the source
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   323
         * value.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   324
         */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   325
        @SuppressWarnings("try")
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   326
        private void eliminateMoves(LIR lir) {
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46459
diff changeset
   327
            DebugContext debug = lir.getDebug();
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   328
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46459
diff changeset
   329
            try (Indent indent = debug.logAndIndent("eliminate moves")) {
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   330
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   331
                AbstractBlockBase<?>[] blocks = lir.linearScanOrder();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   332
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   333
                for (AbstractBlockBase<?> block : blocks) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   334
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46459
diff changeset
   335
                    try (Indent indent2 = debug.logAndIndent("eliminate moves in block %d", block.getId())) {
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   336
46344
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   337
                        ArrayList<LIRInstruction> instructions = lir.getLIRforBlock(block);
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   338
                        BlockData data = blockData.get(block);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   339
                        boolean hasDead = false;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   340
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   341
                        // Reuse the entry state for iteration, we don't need it later.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   342
                        int[] iterState = data.entryState;
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
                        // Add the values which are "consumed" by clearValues and
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   345
                        // mergeState in solveDataFlow
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   346
                        int valueNum = data.entryValueNum + data.entryState.length;
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
                        int numInsts = instructions.size();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   349
                        for (int idx = 0; idx < numInsts; idx++) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   350
                            LIRInstruction op = instructions.get(idx);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   351
                            if (isEligibleMove(op)) {
46459
7d4e637d3f21 8180267: Update Graal
kvn
parents: 46393
diff changeset
   352
                                ValueMoveOp moveOp = ValueMoveOp.asValueMoveOp(op);
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   353
                                int sourceIdx = getStateIdx(moveOp.getInput());
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   354
                                int destIdx = getStateIdx(moveOp.getResult());
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   355
                                if (sourceIdx >= 0 && destIdx >= 0 && iterState[sourceIdx] == iterState[destIdx]) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   356
                                    assert iterState[sourceIdx] != INIT_VALUE;
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46459
diff changeset
   357
                                    debug.log("delete move %s", op);
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   358
                                    instructions.set(idx, null);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   359
                                    hasDead = true;
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46459
diff changeset
   360
                                    deletedMoves.increment(debug);
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   361
                                }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   362
                            }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   363
                            // It doesn't harm if updateState is also called for a deleted move
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46459
diff changeset
   364
                            valueNum = updateState(debug, iterState, op, valueNum);
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   365
                        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   366
                        if (hasDead) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   367
                            instructions.removeAll(Collections.singleton(null));
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   368
                        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   369
                    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   370
                }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   371
            }
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
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   374
        /**
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   375
         * Updates the state for one instruction.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   376
         */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   377
        @SuppressWarnings("try")
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46459
diff changeset
   378
        private int updateState(DebugContext debug, final int[] state, LIRInstruction op, int initValueNum) {
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   379
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46459
diff changeset
   380
            try (Indent indent = debug.logAndIndent("update state for op %s, initial value num = %d", op, initValueNum)) {
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   381
                if (isEligibleMove(op)) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   382
                    /*
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   383
                     * Handle the special case of a move instruction
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   384
                     */
46459
7d4e637d3f21 8180267: Update Graal
kvn
parents: 46393
diff changeset
   385
                    ValueMoveOp moveOp = ValueMoveOp.asValueMoveOp(op);
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   386
                    int sourceIdx = getStateIdx(moveOp.getInput());
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   387
                    int destIdx = getStateIdx(moveOp.getResult());
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   388
                    if (sourceIdx >= 0 && destIdx >= 0) {
46344
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
   389
                        assert isObjectValue(state[sourceIdx]) || LIRKind.isValue(moveOp.getInput()) : "move op moves object but input is not defined as object " + moveOp;
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   390
                        state[destIdx] = state[sourceIdx];
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46459
diff changeset
   391
                        debug.log("move value %d from %d to %d", state[sourceIdx], sourceIdx, destIdx);
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   392
                        return initValueNum;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   393
                    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   394
                }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   395
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   396
                int valueNum = initValueNum;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   397
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   398
                if (op.destroysCallerSavedRegisters()) {
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46459
diff changeset
   399
                    debug.log("kill all caller save regs");
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   400
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   401
                    for (Register reg : callerSaveRegs) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   402
                        if (reg.number < numRegs) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   403
                            // Kind.Object is the save default
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   404
                            state[reg.number] = encodeValueNum(valueNum++, true);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   405
                        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   406
                    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   407
                }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   408
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   409
                /*
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   410
                 * Value procedure for the instruction's output and temp values
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   411
                 */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   412
                class OutputValueConsumer implements ValueConsumer {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   413
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   414
                    int opValueNum;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   415
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   416
                    OutputValueConsumer(int opValueNum) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   417
                        this.opValueNum = opValueNum;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   418
                    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   419
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   420
                    @Override
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   421
                    public void visitValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   422
                        int stateIdx = getStateIdx(operand);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   423
                        if (stateIdx >= 0) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   424
                            /*
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   425
                             * Assign a unique number to the output or temp location.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   426
                             */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   427
                            state[stateIdx] = encodeValueNum(opValueNum++, !LIRKind.isValue(operand));
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46459
diff changeset
   428
                            debug.log("set def %d for register %s(%d): %d", opValueNum, operand, stateIdx, state[stateIdx]);
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   429
                        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   430
                    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   431
                }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   432
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   433
                OutputValueConsumer outputValueConsumer = new OutputValueConsumer(valueNum);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   434
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   435
                op.visitEachTemp(outputValueConsumer);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   436
                /*
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   437
                 * Semantically the output values are written _after_ the temp values
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   438
                 */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   439
                op.visitEachOutput(outputValueConsumer);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   440
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   441
                valueNum = outputValueConsumer.opValueNum;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   442
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   443
                if (op.hasState()) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   444
                    /*
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   445
                     * All instructions with framestates (mostly method calls), may do garbage
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   446
                     * collection. GC will rewrite all object references which are live at this
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   447
                     * point. So we can't rely on their values. It would be sufficient to just kill
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   448
                     * all values which are referenced in the state (or all values which are not),
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   449
                     * but for simplicity we kill all values.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   450
                     */
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46459
diff changeset
   451
                    debug.log("kill all object values");
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   452
                    clearValuesOfKindObject(state, valueNum);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   453
                    valueNum += state.length;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   454
                }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   455
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   456
                return valueNum;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   457
            }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   458
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   459
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   460
        /**
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   461
         * The state merge function for dataflow joins.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   462
         */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   463
        private static boolean mergeState(int[] dest, int[] source, int defNum) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   464
            assert dest.length == source.length;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   465
            boolean changed = false;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   466
            for (int idx = 0; idx < source.length; idx++) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   467
                int phiNum = defNum + idx;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   468
                int dst = dest[idx];
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   469
                int src = source[idx];
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   470
                if (dst != src && src != INIT_VALUE && dst != encodeValueNum(phiNum, isObjectValue(dst))) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   471
                    if (dst != INIT_VALUE) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   472
                        dst = encodeValueNum(phiNum, isObjectValue(dst) || isObjectValue(src));
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   473
                    } else {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   474
                        dst = src;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   475
                    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   476
                    dest[idx] = dst;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   477
                    changed = true;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   478
                }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   479
            }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   480
            return changed;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   481
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   482
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   483
        private static void copyState(int[] dest, int[] source) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   484
            assert dest.length == source.length;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   485
            for (int idx = 0; idx < source.length; idx++) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   486
                dest[idx] = source[idx];
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   487
            }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   488
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   489
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   490
        private static void clearValues(int[] state, int defNum) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   491
            for (int idx = 0; idx < state.length; idx++) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   492
                int phiNum = defNum + idx;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   493
                // Let the killed values assume to be object references: it's the save default.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   494
                state[idx] = encodeValueNum(phiNum, true);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   495
            }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   496
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   497
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   498
        private static void clearValuesOfKindObject(int[] state, int defNum) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   499
            for (int idx = 0; idx < state.length; idx++) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   500
                int phiNum = defNum + idx;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   501
                if (isObjectValue(state[idx])) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   502
                    state[idx] = encodeValueNum(phiNum, true);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   503
                }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   504
            }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   505
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   506
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   507
        /**
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   508
         * Returns the index to the state arrays in BlockData for a specific location.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   509
         */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   510
        private int getStateIdx(Value location) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   511
            if (isRegister(location)) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   512
                int regNum = ((RegisterValue) location).getRegister().number;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   513
                if (regNum < numRegs) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   514
                    return eligibleRegs[regNum];
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   515
                }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   516
                return -1;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   517
            }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   518
            if (isStackSlot(location)) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   519
                StackSlot slot = (StackSlot) location;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   520
                Integer index = stackIndices.get(getOffset(slot));
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   521
                if (index != null) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   522
                    return index.intValue() + numRegs;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   523
                }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   524
            }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   525
            return -1;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   526
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   527
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   528
        /**
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   529
         * Encodes a value number + the is-object information to a number to be stored in a state.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   530
         */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   531
        private static int encodeValueNum(int valueNum, boolean isObjectKind) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   532
            assert valueNum > 0;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   533
            if (isObjectKind) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   534
                return -valueNum;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   535
            }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   536
            return valueNum;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   537
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   538
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   539
        /**
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   540
         * Returns true if an encoded value number (which is stored in a state) refers to an object
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   541
         * reference.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   542
         */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   543
        private static boolean isObjectValue(int encodedValueNum) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   544
            return encodedValueNum < 0;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   545
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   546
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   547
        /**
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   548
         * Returns true for a move instruction which is a candidate for elimination.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   549
         */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   550
        private static boolean isEligibleMove(LIRInstruction op) {
46459
7d4e637d3f21 8180267: Update Graal
kvn
parents: 46393
diff changeset
   551
            if (ValueMoveOp.isValueMoveOp(op)) {
7d4e637d3f21 8180267: Update Graal
kvn
parents: 46393
diff changeset
   552
                ValueMoveOp moveOp = ValueMoveOp.asValueMoveOp(op);
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   553
                Value source = moveOp.getInput();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   554
                Value dest = moveOp.getResult();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   555
                /*
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   556
                 * Moves with mismatching kinds are not moves, but memory loads/stores!
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   557
                 */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   558
                return source.getValueKind().equals(dest.getValueKind());
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   559
            }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   560
            return false;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   561
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   562
    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   563
}