annotate graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanEliminateSpillMovePhase.java @ 21554:b1530a6cce8c

renamed com.oracle.graal.[debug|options|hotspotvmconfig]* modules to com.oracle.jvmci.[debug|options|hotspotvmconfig]* modules (JBS:GRAAL-53)
author Doug Simon <doug.simon@oracle.com>
date Tue, 26 May 2015 23:21:15 +0200
parents 93c50cefb9e8
children 48c1ebd24120
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
21336
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
1 /*
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
2 * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
4 *
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
7 * published by the Free Software Foundation.
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
8 *
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
13 * accompanied this code).
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
14 *
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
18 *
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
21 * questions.
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
22 */
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
23 package com.oracle.graal.lir.alloc.lsra;
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
24
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
25 import static com.oracle.graal.api.code.ValueUtil.*;
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
26 import static com.oracle.graal.compiler.common.GraalOptions.*;
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
27 import static com.oracle.graal.lir.LIRValueUtil.*;
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
28
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
29 import java.util.*;
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
30
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
31 import com.oracle.graal.api.code.*;
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
32 import com.oracle.graal.api.meta.*;
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
33 import com.oracle.graal.compiler.common.cfg.*;
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
34 import com.oracle.graal.lir.*;
21543
93c50cefb9e8 moved GraalInternalError to com.oracle.jvmci.common and renamed it to JVMCIError (JBS:GRAAL-53)
Doug Simon <doug.simon@oracle.com>
parents: 21440
diff changeset
35 import com.oracle.graal.lir.StandardOp.MoveOp;
93c50cefb9e8 moved GraalInternalError to com.oracle.jvmci.common and renamed it to JVMCIError (JBS:GRAAL-53)
Doug Simon <doug.simon@oracle.com>
parents: 21440
diff changeset
36 import com.oracle.graal.lir.alloc.lsra.Interval.SpillState;
93c50cefb9e8 moved GraalInternalError to com.oracle.jvmci.common and renamed it to JVMCIError (JBS:GRAAL-53)
Doug Simon <doug.simon@oracle.com>
parents: 21440
diff changeset
37 import com.oracle.graal.lir.alloc.lsra.LinearScan.IntervalPredicate;
21336
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
38 import com.oracle.graal.lir.gen.*;
21543
93c50cefb9e8 moved GraalInternalError to com.oracle.jvmci.common and renamed it to JVMCIError (JBS:GRAAL-53)
Doug Simon <doug.simon@oracle.com>
parents: 21440
diff changeset
39 import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
21336
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
40 import com.oracle.graal.lir.phases.*;
21554
b1530a6cce8c renamed com.oracle.graal.[debug|options|hotspotvmconfig]* modules to com.oracle.jvmci.[debug|options|hotspotvmconfig]* modules (JBS:GRAAL-53)
Doug Simon <doug.simon@oracle.com>
parents: 21543
diff changeset
41 import com.oracle.jvmci.debug.*;
21336
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
42
21339
1c56b7be2731 LinearScan: renamed sub phases.
Josef Eisl <josef.eisl@jku.at>
parents: 21336
diff changeset
43 class LinearScanEliminateSpillMovePhase extends AllocationPhase {
21336
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
44
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
45 private static final IntervalPredicate mustStoreAtDefinition = new LinearScan.IntervalPredicate() {
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
46
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
47 @Override
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
48 public boolean apply(Interval i) {
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
49 return i.isSplitParent() && i.spillState() == SpillState.StoreAtDefinition;
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
50 }
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
51 };
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
52
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
53 protected final LinearScan allocator;
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
54
21339
1c56b7be2731 LinearScan: renamed sub phases.
Josef Eisl <josef.eisl@jku.at>
parents: 21336
diff changeset
55 LinearScanEliminateSpillMovePhase(LinearScan allocator) {
21336
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
56 this.allocator = allocator;
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
57 }
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
58
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
59 @Override
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
60 protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, SpillMoveFactory spillMoveFactory) {
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
61 eliminateSpillMoves();
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
62 }
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
63
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
64 /**
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
65 * @return the index of the first instruction that is of interest for
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
66 * {@link #eliminateSpillMoves()}
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
67 */
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
68 protected int firstInstructionOfInterest() {
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
69 // skip the first because it is always a label
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
70 return 1;
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
71 }
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
72
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
73 // called once before assignment of register numbers
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
74 void eliminateSpillMoves() {
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
75 try (Indent indent = Debug.logAndIndent("Eliminating unnecessary spill moves")) {
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
76
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
77 /*
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
78 * collect all intervals that must be stored after their definition. The list is sorted
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
79 * by Interval.spillDefinitionPos.
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
80 */
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
81 Interval interval;
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
82 interval = allocator.createUnhandledLists(mustStoreAtDefinition, null).first;
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
83 if (DetailedAsserts.getValue()) {
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
84 checkIntervals(interval);
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
85 }
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
86
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
87 LIRInsertionBuffer insertionBuffer = new LIRInsertionBuffer();
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
88 for (AbstractBlockBase<?> block : allocator.sortedBlocks) {
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
89 try (Indent indent1 = Debug.logAndIndent("Handle %s", block)) {
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
90 List<LIRInstruction> instructions = allocator.ir.getLIRforBlock(block);
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
91 int numInst = instructions.size();
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
92
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
93 // iterate all instructions of the block.
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
94 for (int j = firstInstructionOfInterest(); j < numInst; j++) {
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
95 LIRInstruction op = instructions.get(j);
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
96 int opId = op.id();
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
97
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
98 if (opId == -1) {
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
99 MoveOp move = (MoveOp) op;
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
100 /*
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
101 * Remove move from register to stack if the stack slot is guaranteed to
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
102 * be correct. Only moves that have been inserted by LinearScan can be
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
103 * removed.
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
104 */
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
105 if (canEliminateSpillMove(block, move)) {
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
106 /*
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
107 * Move target is a stack slot that is always correct, so eliminate
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
108 * instruction.
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
109 */
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
110 if (Debug.isLogEnabled()) {
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
111 Debug.log("eliminating move from interval %d (%s) to %d (%s) in block %s", allocator.operandNumber(move.getInput()), move.getInput(),
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
112 allocator.operandNumber(move.getResult()), move.getResult(), block);
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
113 }
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
114
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
115 // null-instructions are deleted by assignRegNum
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
116 instructions.set(j, null);
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
117 }
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
118
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
119 } else {
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
120 /*
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
121 * Insert move from register to stack just after the beginning of the
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
122 * interval.
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
123 */
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
124 assert interval == Interval.EndMarker || interval.spillDefinitionPos() >= opId : "invalid order";
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
125 assert interval == Interval.EndMarker || (interval.isSplitParent() && interval.spillState() == SpillState.StoreAtDefinition) : "invalid interval";
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
126
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
127 while (interval != Interval.EndMarker && interval.spillDefinitionPos() == opId) {
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
128 if (!interval.canMaterialize()) {
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
129 if (!insertionBuffer.initialized()) {
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
130 /*
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
131 * prepare insertion buffer (appended when all instructions
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
132 * in the block are processed)
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
133 */
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
134 insertionBuffer.init(instructions);
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
135 }
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
136
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
137 AllocatableValue fromLocation = interval.location();
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
138 AllocatableValue toLocation = LinearScan.canonicalSpillOpr(interval);
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
139 if (!fromLocation.equals(toLocation)) {
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
140
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
141 assert isRegister(fromLocation) : "from operand must be a register but is: " + fromLocation + " toLocation=" + toLocation + " spillState=" +
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
142 interval.spillState();
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
143 assert isStackSlotValue(toLocation) : "to operand must be a stack slot";
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
144
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
145 LIRInstruction move = allocator.getSpillMoveFactory().createMove(toLocation, fromLocation);
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
146 insertionBuffer.append(j + 1, move);
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
147
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
148 if (Debug.isLogEnabled()) {
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
149 Debug.log("inserting move after definition of interval %d to stack slot %s at opId %d", interval.operandNumber, interval.spillSlot(), opId);
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
150 }
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
151 }
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
152 }
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
153 interval = interval.next;
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
154 }
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
155 }
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
156 } // end of instruction iteration
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
157
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
158 if (insertionBuffer.initialized()) {
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
159 insertionBuffer.finish();
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
160 }
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
161 }
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
162 } // end of block iteration
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
163
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
164 assert interval == Interval.EndMarker : "missed an interval";
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
165 }
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
166 }
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
167
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
168 /**
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
169 * @param block The block {@code move} is located in.
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
170 * @param move Spill move.
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
171 */
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
172 protected boolean canEliminateSpillMove(AbstractBlockBase<?> block, MoveOp move) {
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
173 assert isVariable(move.getResult()) : "LinearScan inserts only moves to variables: " + move;
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
174
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
175 Interval curInterval = allocator.intervalFor(move.getResult());
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
176
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
177 if (!isRegister(curInterval.location()) && curInterval.alwaysInMemory()) {
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
178 assert isStackSlotValue(curInterval.location()) : "Not a stack slot: " + curInterval.location();
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
179 return true;
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
180 }
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
181 return false;
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
182 }
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
183
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
184 private static void checkIntervals(Interval interval) {
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
185 Interval prev = null;
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
186 Interval temp = interval;
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
187 while (temp != Interval.EndMarker) {
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
188 assert temp.spillDefinitionPos() > 0 : "invalid spill definition pos";
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
189 if (prev != null) {
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
190 assert temp.from() >= prev.from() : "intervals not sorted";
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
191 assert temp.spillDefinitionPos() >= prev.spillDefinitionPos() : "when intervals are sorted by from : then they must also be sorted by spillDefinitionPos";
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
192 }
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
193
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
194 assert temp.spillSlot() != null || temp.canMaterialize() : "interval has no spill slot assigned";
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
195 assert temp.spillDefinitionPos() >= temp.from() : "invalid order";
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
196 assert temp.spillDefinitionPos() <= temp.from() + 2 : "only intervals defined once at their start-pos can be optimized";
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
197
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
198 if (Debug.isLogEnabled()) {
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
199 Debug.log("interval %d (from %d to %d) must be stored at %d", temp.operandNumber, temp.from(), temp.to(), temp.spillDefinitionPos());
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
200 }
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
201
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
202 prev = temp;
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
203 temp = temp.next;
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
204 }
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
205 }
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
206
5661a921e123 LinearScan: outsource EliminateSpillMove.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
207 }