9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package org.graalvm.compiler.lir.alloc.trace.bu;
24
25 import static jdk.vm.ci.code.ValueUtil.asAllocatableValue;
26 import static jdk.vm.ci.code.ValueUtil.asRegister;
27 import static jdk.vm.ci.code.ValueUtil.isIllegal;
28 import static jdk.vm.ci.code.ValueUtil.isRegister;
29 import static org.graalvm.compiler.core.common.GraalOptions.DetailedAsserts;
30 import static org.graalvm.compiler.lir.LIRValueUtil.asVariable;
31 import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue;
32 import static org.graalvm.compiler.lir.LIRValueUtil.isStackSlotValue;
33 import static org.graalvm.compiler.lir.LIRValueUtil.isVariable;
34
35 import java.util.ArrayList;
36 import java.util.BitSet;
37 import java.util.Collections;
38 import java.util.EnumSet;
39
40 import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig;
41 import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig.AllocatableRegisters;
42 import org.graalvm.compiler.core.common.alloc.Trace;
43 import org.graalvm.compiler.core.common.alloc.TraceBuilderResult;
44 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
45 import org.graalvm.compiler.debug.DebugContext;
46 import org.graalvm.compiler.debug.Indent;
47 import org.graalvm.compiler.lir.InstructionValueProcedure;
48 import org.graalvm.compiler.lir.LIR;
49 import org.graalvm.compiler.lir.LIRInstruction;
50 import org.graalvm.compiler.lir.LIRInstruction.OperandFlag;
51 import org.graalvm.compiler.lir.LIRInstruction.OperandMode;
52 import org.graalvm.compiler.lir.LIRValueUtil;
53 import org.graalvm.compiler.lir.RedundantMoveElimination;
54 import org.graalvm.compiler.lir.StandardOp;
55 import org.graalvm.compiler.lir.StandardOp.BlockEndOp;
56 import org.graalvm.compiler.lir.StandardOp.JumpOp;
57 import org.graalvm.compiler.lir.StandardOp.LabelOp;
58 import org.graalvm.compiler.lir.Variable;
59 import org.graalvm.compiler.lir.VirtualStackSlot;
60 import org.graalvm.compiler.lir.alloc.OutOfRegistersException;
61 import org.graalvm.compiler.lir.alloc.trace.GlobalLivenessInfo;
62 import org.graalvm.compiler.lir.alloc.trace.TraceAllocationPhase;
63 import org.graalvm.compiler.lir.alloc.trace.TraceAllocationPhase.TraceAllocationContext;
64 import org.graalvm.compiler.lir.alloc.trace.TraceGlobalMoveResolutionPhase;
207 LIR lir = lirGenRes.getLIR();
208 if (fromBlock.getSuccessorCount() <= 1) {
209 if (debug.isLogEnabled()) {
210 debug.log("inserting moves at end of fromBlock B%d", fromBlock.getId());
211 }
212
213 ArrayList<LIRInstruction> instructions = lir.getLIRforBlock(fromBlock);
214 LIRInstruction instr = instructions.get(instructions.size() - 1);
215 if (instr instanceof StandardOp.JumpOp) {
216 // insert moves before branch
217 moveResolver.setInsertPosition(instructions, instructions.size() - 1);
218 } else {
219 moveResolver.setInsertPosition(instructions, instructions.size());
220 }
221
222 } else {
223 if (debug.isLogEnabled()) {
224 debug.log("inserting moves at beginning of toBlock B%d", toBlock.getId());
225 }
226
227 if (DetailedAsserts.getValue(getLIR().getOptions())) {
228 assert lir.getLIRforBlock(fromBlock).get(0) instanceof StandardOp.LabelOp : "block does not start with a label";
229
230 /*
231 * Because the number of predecessor edges matches the number of successor edges,
232 * blocks which are reached by switch statements may have be more than one
233 * predecessor but it will be guaranteed that all predecessors will be the same.
234 */
235 for (AbstractBlockBase<?> predecessor : toBlock.getPredecessors()) {
236 assert fromBlock == predecessor : "all critical edges must be broken";
237 }
238 }
239
240 moveResolver.setInsertPosition(lir.getLIRforBlock(toBlock), 1);
241 }
242 }
243
244 private final class Allocator {
245
246 /**
247 * Maps from {@linkplain Register#number register} to the current {@linkplain Variable
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package org.graalvm.compiler.lir.alloc.trace.bu;
24
25 import static jdk.vm.ci.code.ValueUtil.asAllocatableValue;
26 import static jdk.vm.ci.code.ValueUtil.asRegister;
27 import static jdk.vm.ci.code.ValueUtil.isIllegal;
28 import static jdk.vm.ci.code.ValueUtil.isRegister;
29 import static org.graalvm.compiler.lir.LIRValueUtil.asVariable;
30 import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue;
31 import static org.graalvm.compiler.lir.LIRValueUtil.isStackSlotValue;
32 import static org.graalvm.compiler.lir.LIRValueUtil.isVariable;
33
34 import java.util.ArrayList;
35 import java.util.BitSet;
36 import java.util.Collections;
37 import java.util.EnumSet;
38
39 import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig;
40 import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig.AllocatableRegisters;
41 import org.graalvm.compiler.core.common.alloc.Trace;
42 import org.graalvm.compiler.core.common.alloc.TraceBuilderResult;
43 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
44 import org.graalvm.compiler.debug.Assertions;
45 import org.graalvm.compiler.debug.DebugContext;
46 import org.graalvm.compiler.debug.Indent;
47 import org.graalvm.compiler.lir.InstructionValueProcedure;
48 import org.graalvm.compiler.lir.LIR;
49 import org.graalvm.compiler.lir.LIRInstruction;
50 import org.graalvm.compiler.lir.LIRInstruction.OperandFlag;
51 import org.graalvm.compiler.lir.LIRInstruction.OperandMode;
52 import org.graalvm.compiler.lir.LIRValueUtil;
53 import org.graalvm.compiler.lir.RedundantMoveElimination;
54 import org.graalvm.compiler.lir.StandardOp;
55 import org.graalvm.compiler.lir.StandardOp.BlockEndOp;
56 import org.graalvm.compiler.lir.StandardOp.JumpOp;
57 import org.graalvm.compiler.lir.StandardOp.LabelOp;
58 import org.graalvm.compiler.lir.Variable;
59 import org.graalvm.compiler.lir.VirtualStackSlot;
60 import org.graalvm.compiler.lir.alloc.OutOfRegistersException;
61 import org.graalvm.compiler.lir.alloc.trace.GlobalLivenessInfo;
62 import org.graalvm.compiler.lir.alloc.trace.TraceAllocationPhase;
63 import org.graalvm.compiler.lir.alloc.trace.TraceAllocationPhase.TraceAllocationContext;
64 import org.graalvm.compiler.lir.alloc.trace.TraceGlobalMoveResolutionPhase;
207 LIR lir = lirGenRes.getLIR();
208 if (fromBlock.getSuccessorCount() <= 1) {
209 if (debug.isLogEnabled()) {
210 debug.log("inserting moves at end of fromBlock B%d", fromBlock.getId());
211 }
212
213 ArrayList<LIRInstruction> instructions = lir.getLIRforBlock(fromBlock);
214 LIRInstruction instr = instructions.get(instructions.size() - 1);
215 if (instr instanceof StandardOp.JumpOp) {
216 // insert moves before branch
217 moveResolver.setInsertPosition(instructions, instructions.size() - 1);
218 } else {
219 moveResolver.setInsertPosition(instructions, instructions.size());
220 }
221
222 } else {
223 if (debug.isLogEnabled()) {
224 debug.log("inserting moves at beginning of toBlock B%d", toBlock.getId());
225 }
226
227 if (Assertions.detailedAssertionsEnabled(getLIR().getOptions())) {
228 assert lir.getLIRforBlock(fromBlock).get(0) instanceof StandardOp.LabelOp : "block does not start with a label";
229
230 /*
231 * Because the number of predecessor edges matches the number of successor edges,
232 * blocks which are reached by switch statements may have be more than one
233 * predecessor but it will be guaranteed that all predecessors will be the same.
234 */
235 for (AbstractBlockBase<?> predecessor : toBlock.getPredecessors()) {
236 assert fromBlock == predecessor : "all critical edges must be broken";
237 }
238 }
239
240 moveResolver.setInsertPosition(lir.getLIRforBlock(toBlock), 1);
241 }
242 }
243
244 private final class Allocator {
245
246 /**
247 * Maps from {@linkplain Register#number register} to the current {@linkplain Variable
|