Mercurial > hg > graal-compiler
changeset 22559:f6aa1989bd5c
TraceRA: pull trace.TraceLocalMoveResolver up into trace.MoveResolver.
author | Josef Eisl <josef.eisl@jku.at> |
---|---|
date | Tue, 01 Sep 2015 11:46:16 +0200 |
parents | e9973570a820 |
children | 71ca282ae653 |
files | graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/MoveResolver.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScan.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLocalMoveResolver.java |
diffstat | 3 files changed, 105 insertions(+), 217 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/MoveResolver.java Tue Sep 01 11:07:34 2015 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/MoveResolver.java Tue Sep 01 11:46:16 2015 +0200 @@ -32,11 +32,13 @@ import com.oracle.graal.debug.*; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.framemap.*; /** */ public class MoveResolver { + private static final int STACK_SLOT_IN_CALLER_FRAME_IDX = -1; private final TraceLinearScan allocator; private int insertIdx; @@ -45,15 +47,58 @@ private final List<Interval> mappingFrom; private final List<Constant> mappingFromOpr; private final List<Interval> mappingTo; - private boolean multipleReadsAllowed; private final int[] registerBlocked; + private int[] stackBlocked; + private final int firstVirtualStackIndex; + + private int getStackArrayIndex(StackSlotValue stackSlotValue) { + if (isStackSlot(stackSlotValue)) { + return getStackArrayIndex(asStackSlot(stackSlotValue)); + } + if (isVirtualStackSlot(stackSlotValue)) { + return getStackArrayIndex(asVirtualStackSlot(stackSlotValue)); + } + throw JVMCIError.shouldNotReachHere("Unhandled StackSlotValue: " + stackSlotValue); + } + + private int getStackArrayIndex(StackSlot stackSlot) { + int stackIdx; + if (stackSlot.isInCallerFrame()) { + // incoming stack arguments can be ignored + stackIdx = STACK_SLOT_IN_CALLER_FRAME_IDX; + } else { + assert stackSlot.getRawAddFrameSize() : "Unexpected stack slot: " + stackSlot; + int offset = -stackSlot.getRawOffset(); + assert 0 <= offset && offset < firstVirtualStackIndex : String.format("Wrong stack slot offset: %d (first virtual stack slot index: %d", offset, firstVirtualStackIndex); + stackIdx = offset; + } + return stackIdx; + } + + private int getStackArrayIndex(VirtualStackSlot virtualStackSlot) { + return firstVirtualStackIndex + virtualStackSlot.getId(); + } + protected void setValueBlocked(Value location, int direction) { assert direction == 1 || direction == -1 : "out of bounds"; - if (isRegister(location)) { - registerBlocked[asRegister(location).number] += direction; + if (isStackSlotValue(location)) { + int stackIdx = getStackArrayIndex(asStackSlotValue(location)); + if (stackIdx == STACK_SLOT_IN_CALLER_FRAME_IDX) { + // incoming stack arguments can be ignored + return; + } + if (stackIdx >= stackBlocked.length) { + stackBlocked = Arrays.copyOf(stackBlocked, stackIdx + 1); + } + stackBlocked[stackIdx] += direction; } else { - throw JVMCIError.shouldNotReachHere("unhandled value " + location); + assert direction == 1 || direction == -1 : "out of bounds"; + if (isRegister(location)) { + registerBlocked[asRegister(location).number] += direction; + } else { + throw JVMCIError.shouldNotReachHere("unhandled value " + location); + } } } @@ -66,18 +111,25 @@ } protected int valueBlocked(Value location) { + if (isStackSlotValue(location)) { + int stackIdx = getStackArrayIndex(asStackSlotValue(location)); + if (stackIdx == STACK_SLOT_IN_CALLER_FRAME_IDX) { + // incoming stack arguments are always blocked (aka they can not be written) + return 1; + } + if (stackIdx >= stackBlocked.length) { + return 0; + } + return stackBlocked[stackIdx]; + } if (isRegister(location)) { return registerBlocked[asRegister(location).number]; } throw JVMCIError.shouldNotReachHere("unhandled value " + location); } - void setMultipleReadsAllowed() { - multipleReadsAllowed = true; - } - protected boolean areMultipleReadsAllowed() { - return multipleReadsAllowed; + return true; } boolean hasMappings() { @@ -91,17 +143,23 @@ protected MoveResolver(TraceLinearScan allocator) { this.allocator = allocator; - this.multipleReadsAllowed = false; this.mappingFrom = new ArrayList<>(8); this.mappingFromOpr = new ArrayList<>(8); this.mappingTo = new ArrayList<>(8); this.insertIdx = -1; this.insertionBuffer = new LIRInsertionBuffer(); this.registerBlocked = new int[allocator.getRegisters().length]; + FrameMapBuilderTool frameMapBuilderTool = (FrameMapBuilderTool) allocator.getFrameMapBuilder(); + FrameMap frameMap = frameMapBuilderTool.getFrameMap(); + this.stackBlocked = new int[frameMapBuilderTool.getNumberOfStackSlots()]; + this.firstVirtualStackIndex = !frameMap.frameNeedsAllocating() ? 0 : frameMap.currentFrameSize() + 1; } protected boolean checkEmpty() { assert mappingFrom.size() == 0 && mappingFromOpr.size() == 0 && mappingTo.size() == 0 : "list must be empty before and after processing"; + for (int i = 0; i < stackBlocked.length; i++) { + assert stackBlocked[i] == 0 : "stack map must be empty before and after processing"; + } for (int i = 0; i < getAllocator().getRegisters().length; i++) { assert registerBlocked[i] == 0 : "register map must be empty before and after processing"; } @@ -110,7 +168,7 @@ } protected void checkMultipleReads() { - assert !areMultipleReadsAllowed() : "must have default value"; + // multiple reads are allowed in SSA LSRA } private boolean verifyBeforeResolve() { @@ -163,25 +221,7 @@ } protected void verifyStackSlotMapping() { - HashSet<Value> usedRegs = new HashSet<>(); - for (int i = 0; i < mappingFrom.size(); i++) { - Interval interval = mappingFrom.get(i); - if (interval != null && !isRegister(interval.location())) { - usedRegs.add(interval.location()); - } - } - for (int i = 0; i < mappingTo.size(); i++) { - Interval interval = mappingTo.get(i); - assert !usedRegs.contains(interval.location()) || checkIntervalLocation(mappingFrom.get(i), interval, mappingFromOpr.get(i)) : "stack slots used in mappingFrom must be disjoint to mappingTo"; - } - } - - private static boolean checkIntervalLocation(Interval from, Interval to, Constant fromOpr) { - if (from == null) { - return fromOpr != null; - } else { - return to.location().equals(from.location()); - } + // relax disjoint stack maps invariant } // mark assignedReg and assignedRegHi of the interval as blocked @@ -235,7 +275,13 @@ } protected boolean mightBeBlocked(Value location) { - return isRegister(location); + if (isRegister(location)) { + return true; + } + if (isStackSlotValue(location)) { + return true; + } + return false; } private void createInsertionBuffer(List<LIRInstruction> list) { @@ -271,6 +317,9 @@ * @param toLocation {@link Interval#location() location} of the {@code to} interval */ protected LIRInstruction createMove(AllocatableValue fromOpr, AllocatableValue toOpr, AllocatableValue fromLocation, AllocatableValue toLocation) { + if (isStackSlotValue(toLocation) && isStackSlotValue(fromLocation)) { + return getAllocator().getSpillMoveFactory().createStackMove(toOpr, fromOpr); + } return getAllocator().getSpillMoveFactory().createMove(toOpr, fromOpr); } @@ -338,29 +387,37 @@ } } - // reset to default value - multipleReadsAllowed = false; - // check that all intervals have been processed assert checkEmpty(); } protected void breakCycle(int spillCandidate) { - // no move could be processed because there is a cycle in the move list - // (e.g. r1 . r2, r2 . r1), so one interval must be spilled to memory - assert spillCandidate != -1 : "no interval in register for spilling found"; + if (spillCandidate != -1) { + // no move could be processed because there is a cycle in the move list + // (e.g. r1 . r2, r2 . r1), so one interval must be spilled to memory + assert spillCandidate != -1 : "no interval in register for spilling found"; - // create a new spill interval and assign a stack slot to it - Interval fromInterval = mappingFrom.get(spillCandidate); - // do not allocate a new spill slot for temporary interval, but - // use spill slot assigned to fromInterval. Otherwise moves from - // one stack slot to another can happen (not allowed by LIRAssembler - StackSlotValue spillSlot = fromInterval.spillSlot(); - if (spillSlot == null) { - spillSlot = getAllocator().getFrameMapBuilder().allocateSpillSlot(fromInterval.kind()); - fromInterval.setSpillSlot(spillSlot); + // create a new spill interval and assign a stack slot to it + Interval fromInterval1 = mappingFrom.get(spillCandidate); + // do not allocate a new spill slot for temporary interval, but + // use spill slot assigned to fromInterval. Otherwise moves from + // one stack slot to another can happen (not allowed by LIRAssembler + StackSlotValue spillSlot1 = fromInterval1.spillSlot(); + if (spillSlot1 == null) { + spillSlot1 = getAllocator().getFrameMapBuilder().allocateSpillSlot(fromInterval1.kind()); + fromInterval1.setSpillSlot(spillSlot1); + } + spillInterval(spillCandidate, fromInterval1, spillSlot1); + return; } - spillInterval(spillCandidate, fromInterval, spillSlot); + assert mappingFromSize() > 1; + // Arbitrarily select the first entry for spilling. + int stackSpillCandidate = 0; + Interval fromInterval = getMappingFrom(stackSpillCandidate); + assert isStackSlotValue(fromInterval.location()); + // allocate new stack slot + StackSlotValue spillSlot = getAllocator().getFrameMapBuilder().allocateSpillSlot(fromInterval.kind()); + spillInterval(stackSpillCandidate, fromInterval, spillSlot); } protected void spillInterval(int spillCandidate, Interval fromInterval, StackSlotValue spillSlot) {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScan.java Tue Sep 01 11:07:34 2015 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScan.java Tue Sep 01 11:46:16 2015 +0200 @@ -184,7 +184,7 @@ } protected MoveResolver createMoveResolver() { - TraceLocalMoveResolver moveResolver = new TraceLocalMoveResolver(this); + MoveResolver moveResolver = new MoveResolver(this); assert moveResolver.checkEmpty(); return moveResolver; }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLocalMoveResolver.java Tue Sep 01 11:07:34 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,169 +0,0 @@ -/* - * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.lir.alloc.trace; - -import static jdk.internal.jvmci.code.ValueUtil.*; - -import java.util.*; - -import jdk.internal.jvmci.code.*; -import jdk.internal.jvmci.common.*; -import jdk.internal.jvmci.meta.*; - -import com.oracle.graal.lir.*; -import com.oracle.graal.lir.framemap.*; - -final class TraceLocalMoveResolver extends MoveResolver { - - private static final int STACK_SLOT_IN_CALLER_FRAME_IDX = -1; - private int[] stackBlocked; - private final int firstVirtualStackIndex; - - public TraceLocalMoveResolver(TraceLinearScan allocator) { - super(allocator); - FrameMapBuilderTool frameMapBuilderTool = (FrameMapBuilderTool) allocator.getFrameMapBuilder(); - FrameMap frameMap = frameMapBuilderTool.getFrameMap(); - this.stackBlocked = new int[frameMapBuilderTool.getNumberOfStackSlots()]; - this.firstVirtualStackIndex = !frameMap.frameNeedsAllocating() ? 0 : frameMap.currentFrameSize() + 1; - } - - @Override - public boolean checkEmpty() { - for (int i = 0; i < stackBlocked.length; i++) { - assert stackBlocked[i] == 0 : "stack map must be empty before and after processing"; - } - return super.checkEmpty(); - } - - @Override - protected void checkMultipleReads() { - // multiple reads are allowed in SSA LSRA - } - - @Override - protected void verifyStackSlotMapping() { - // relax disjoint stack maps invariant - } - - @Override - protected boolean areMultipleReadsAllowed() { - return true; - } - - @Override - protected boolean mightBeBlocked(Value location) { - if (super.mightBeBlocked(location)) { - return true; - } - if (isStackSlotValue(location)) { - return true; - } - return false; - } - - private int getStackArrayIndex(StackSlotValue stackSlotValue) { - if (isStackSlot(stackSlotValue)) { - return getStackArrayIndex(asStackSlot(stackSlotValue)); - } - if (isVirtualStackSlot(stackSlotValue)) { - return getStackArrayIndex(asVirtualStackSlot(stackSlotValue)); - } - throw JVMCIError.shouldNotReachHere("Unhandled StackSlotValue: " + stackSlotValue); - } - - private int getStackArrayIndex(StackSlot stackSlot) { - int stackIdx; - if (stackSlot.isInCallerFrame()) { - // incoming stack arguments can be ignored - stackIdx = STACK_SLOT_IN_CALLER_FRAME_IDX; - } else { - assert stackSlot.getRawAddFrameSize() : "Unexpected stack slot: " + stackSlot; - int offset = -stackSlot.getRawOffset(); - assert 0 <= offset && offset < firstVirtualStackIndex : String.format("Wrong stack slot offset: %d (first virtual stack slot index: %d", offset, firstVirtualStackIndex); - stackIdx = offset; - } - return stackIdx; - } - - private int getStackArrayIndex(VirtualStackSlot virtualStackSlot) { - return firstVirtualStackIndex + virtualStackSlot.getId(); - } - - @Override - protected void setValueBlocked(Value location, int direction) { - assert direction == 1 || direction == -1 : "out of bounds"; - if (isStackSlotValue(location)) { - int stackIdx = getStackArrayIndex(asStackSlotValue(location)); - if (stackIdx == STACK_SLOT_IN_CALLER_FRAME_IDX) { - // incoming stack arguments can be ignored - return; - } - if (stackIdx >= stackBlocked.length) { - stackBlocked = Arrays.copyOf(stackBlocked, stackIdx + 1); - } - stackBlocked[stackIdx] += direction; - } else { - super.setValueBlocked(location, direction); - } - } - - @Override - protected int valueBlocked(Value location) { - if (isStackSlotValue(location)) { - int stackIdx = getStackArrayIndex(asStackSlotValue(location)); - if (stackIdx == STACK_SLOT_IN_CALLER_FRAME_IDX) { - // incoming stack arguments are always blocked (aka they can not be written) - return 1; - } - if (stackIdx >= stackBlocked.length) { - return 0; - } - return stackBlocked[stackIdx]; - } - return super.valueBlocked(location); - } - - @Override - protected LIRInstruction createMove(AllocatableValue fromOpr, AllocatableValue toOpr, AllocatableValue fromLocation, AllocatableValue toLocation) { - if (isStackSlotValue(toLocation) && isStackSlotValue(fromLocation)) { - return getAllocator().getSpillMoveFactory().createStackMove(toOpr, fromOpr); - } - return super.createMove(fromOpr, toOpr, fromLocation, toLocation); - } - - @Override - protected void breakCycle(int spillCandidate) { - if (spillCandidate != -1) { - super.breakCycle(spillCandidate); - return; - } - assert mappingFromSize() > 1; - // Arbitrarily select the first entry for spilling. - int stackSpillCandidate = 0; - Interval fromInterval = getMappingFrom(stackSpillCandidate); - assert isStackSlotValue(fromInterval.location()); - // allocate new stack slot - StackSlotValue spillSlot = getAllocator().getFrameMapBuilder().allocateSpillSlot(fromInterval.kind()); - spillInterval(stackSpillCandidate, fromInterval, spillSlot); - } -}