SSALinearScanResolveDataFlowPhase.java revision 12651:6ef01bd40ce2
1/*
2 * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
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 */
23package org.graalvm.compiler.lir.alloc.lsra.ssa;
24
25import static org.graalvm.compiler.lir.LIRValueUtil.asConstant;
26import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue;
27import static org.graalvm.compiler.lir.LIRValueUtil.isStackSlotValue;
28import static jdk.vm.ci.code.ValueUtil.isRegister;
29
30import java.util.List;
31
32import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
33import org.graalvm.compiler.debug.Debug;
34import org.graalvm.compiler.debug.DebugCounter;
35import org.graalvm.compiler.lir.LIRInstruction;
36import org.graalvm.compiler.lir.alloc.lsra.Interval;
37import org.graalvm.compiler.lir.alloc.lsra.LinearScan;
38import org.graalvm.compiler.lir.alloc.lsra.LinearScanResolveDataFlowPhase;
39import org.graalvm.compiler.lir.alloc.lsra.MoveResolver;
40import org.graalvm.compiler.lir.ssa.SSAUtil;
41import org.graalvm.compiler.lir.ssa.SSAUtil.PhiValueVisitor;
42
43import jdk.vm.ci.meta.Value;
44
45class SSALinearScanResolveDataFlowPhase extends LinearScanResolveDataFlowPhase {
46
47    private static final DebugCounter numPhiResolutionMoves = Debug.counter("SSA LSRA[numPhiResolutionMoves]");
48    private static final DebugCounter numStackToStackMoves = Debug.counter("SSA LSRA[numStackToStackMoves]");
49
50    SSALinearScanResolveDataFlowPhase(LinearScan allocator) {
51        super(allocator);
52    }
53
54    @Override
55    protected void resolveCollectMappings(AbstractBlockBase<?> fromBlock, AbstractBlockBase<?> toBlock, AbstractBlockBase<?> midBlock, MoveResolver moveResolver) {
56        super.resolveCollectMappings(fromBlock, toBlock, midBlock, moveResolver);
57
58        if (toBlock.getPredecessorCount() > 1) {
59            int toBlockFirstInstructionId = allocator.getFirstLirInstructionId(toBlock);
60            int fromBlockLastInstructionId = allocator.getLastLirInstructionId(fromBlock) + 1;
61
62            AbstractBlockBase<?> phiOutBlock = midBlock != null ? midBlock : fromBlock;
63            List<LIRInstruction> instructions = allocator.getLIR().getLIRforBlock(phiOutBlock);
64            int phiOutIdx = SSAUtil.phiOutIndex(allocator.getLIR(), phiOutBlock);
65            int phiOutId = midBlock != null ? fromBlockLastInstructionId : instructions.get(phiOutIdx).id();
66            assert phiOutId >= 0;
67
68            PhiValueVisitor visitor = new PhiValueVisitor() {
69
70                @Override
71                public void visit(Value phiIn, Value phiOut) {
72                    assert !isRegister(phiOut) : "phiOut is a register: " + phiOut;
73                    assert !isRegister(phiIn) : "phiIn is a register: " + phiIn;
74                    Interval toInterval = allocator.splitChildAtOpId(allocator.intervalFor(phiIn), toBlockFirstInstructionId, LIRInstruction.OperandMode.DEF);
75                    if (isConstantValue(phiOut)) {
76                        numPhiResolutionMoves.increment();
77                        moveResolver.addMapping(asConstant(phiOut), toInterval);
78                    } else {
79                        Interval fromInterval = allocator.splitChildAtOpId(allocator.intervalFor(phiOut), phiOutId, LIRInstruction.OperandMode.DEF);
80                        if (fromInterval != toInterval && !fromInterval.location().equals(toInterval.location())) {
81                            numPhiResolutionMoves.increment();
82                            if (!(isStackSlotValue(toInterval.location()) && isStackSlotValue(fromInterval.location()))) {
83                                moveResolver.addMapping(fromInterval, toInterval);
84                            } else {
85                                numStackToStackMoves.increment();
86                                moveResolver.addMapping(fromInterval, toInterval);
87                            }
88                        }
89                    }
90                }
91            };
92
93            SSAUtil.forEachPhiValuePair(allocator.getLIR(), toBlock, phiOutBlock, visitor);
94            SSAUtil.removePhiOut(allocator.getLIR(), phiOutBlock);
95        }
96    }
97
98}
99