SSAMoveResolver.java revision 12651:6ef01bd40ce2
1114402Sru/* 2151497Sru * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. 3114402Sru * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4114402Sru * 5114402Sru * This code is free software; you can redistribute it and/or modify it 6114402Sru * under the terms of the GNU General Public License version 2 only, as 7114402Sru * published by the Free Software Foundation. 8114402Sru * 9114402Sru * This code is distributed in the hope that it will be useful, but WITHOUT 10114402Sru * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11114402Sru * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12114402Sru * version 2 for more details (a copy is included in the LICENSE file that 13114402Sru * accompanied this code). 14114402Sru * 15114402Sru * You should have received a copy of the GNU General Public License version 16114402Sru * 2 along with this work; if not, write to the Free Software Foundation, 17114402Sru * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18114402Sru * 19114402Sru * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20151497Sru * or visit www.oracle.com if you need additional information or have any 21114402Sru * questions. 22114402Sru */ 23114402Srupackage org.graalvm.compiler.lir.alloc.lsra.ssa; 24114402Sru 25114402Sruimport static org.graalvm.compiler.lir.LIRValueUtil.asVirtualStackSlot; 26114402Sruimport static org.graalvm.compiler.lir.LIRValueUtil.isStackSlotValue; 27114402Sruimport static org.graalvm.compiler.lir.LIRValueUtil.isVirtualStackSlot; 28114402Sruimport static jdk.vm.ci.code.ValueUtil.asStackSlot; 29114402Sruimport static jdk.vm.ci.code.ValueUtil.isStackSlot; 30114402Sru 31114402Sruimport java.util.Arrays; 32114402Sru 33114402Sruimport org.graalvm.compiler.debug.GraalError; 34114402Sruimport org.graalvm.compiler.lir.LIRInstruction; 35114402Sruimport org.graalvm.compiler.lir.VirtualStackSlot; 36114402Sruimport org.graalvm.compiler.lir.alloc.lsra.Interval; 37114402Sruimport org.graalvm.compiler.lir.alloc.lsra.LinearScan; 38114402Sruimport org.graalvm.compiler.lir.alloc.lsra.MoveResolver; 39114402Sruimport org.graalvm.compiler.lir.framemap.FrameMap; 40114402Sruimport org.graalvm.compiler.lir.framemap.FrameMapBuilderTool; 41114402Sru 42114402Sruimport jdk.vm.ci.code.StackSlot; 43114402Sruimport jdk.vm.ci.meta.AllocatableValue; 44114402Sruimport jdk.vm.ci.meta.Value; 45114402Sru 46114402Srupublic final class SSAMoveResolver extends MoveResolver { 47114402Sru 48114402Sru private static final int STACK_SLOT_IN_CALLER_FRAME_IDX = -1; 49114402Sru private int[] stackBlocked; 50114402Sru private final int firstVirtualStackIndex; 51114402Sru 52114402Sru public SSAMoveResolver(LinearScan allocator) { 53114402Sru super(allocator); 54114402Sru FrameMapBuilderTool frameMapBuilderTool = (FrameMapBuilderTool) allocator.getFrameMapBuilder(); 55114402Sru FrameMap frameMap = frameMapBuilderTool.getFrameMap(); 56114402Sru this.stackBlocked = new int[frameMapBuilderTool.getNumberOfStackSlots()]; 57114402Sru this.firstVirtualStackIndex = !frameMap.frameNeedsAllocating() ? 0 : frameMap.currentFrameSize() + 1; 58114402Sru } 59114402Sru 60114402Sru @Override 61114402Sru public boolean checkEmpty() { 62114402Sru for (int i = 0; i < stackBlocked.length; i++) { 63114402Sru assert stackBlocked[i] == 0 : "stack map must be empty before and after processing"; 64114402Sru } 65114402Sru return super.checkEmpty(); 66114402Sru } 67114402Sru 68114402Sru @Override 69114402Sru protected void checkMultipleReads() { 70114402Sru // multiple reads are allowed in SSA LSRA 71114402Sru } 72114402Sru 73114402Sru @Override 74114402Sru protected void verifyStackSlotMapping() { 75114402Sru // relax disjoint stack maps invariant 76114402Sru } 77114402Sru 78114402Sru @Override 79114402Sru protected boolean areMultipleReadsAllowed() { 80114402Sru return true; 81114402Sru } 82114402Sru 83114402Sru @Override 84114402Sru protected boolean mightBeBlocked(Value location) { 85114402Sru if (super.mightBeBlocked(location)) { 86114402Sru return true; 87114402Sru } 88114402Sru if (isStackSlotValue(location)) { 89114402Sru return true; 90114402Sru } 91114402Sru return false; 92114402Sru } 93114402Sru 94114402Sru private int getStackArrayIndex(Value stackSlotValue) { 95114402Sru if (isStackSlot(stackSlotValue)) { 96114402Sru return getStackArrayIndex(asStackSlot(stackSlotValue)); 97114402Sru } 98114402Sru if (isVirtualStackSlot(stackSlotValue)) { 99114402Sru return getStackArrayIndex(asVirtualStackSlot(stackSlotValue)); 100114402Sru } 101114402Sru throw GraalError.shouldNotReachHere("value is not a stack slot: " + stackSlotValue); 102114402Sru } 103114402Sru 104114402Sru private int getStackArrayIndex(StackSlot stackSlot) { 105114402Sru int stackIdx; 106114402Sru if (stackSlot.isInCallerFrame()) { 107114402Sru // incoming stack arguments can be ignored 108114402Sru stackIdx = STACK_SLOT_IN_CALLER_FRAME_IDX; 109114402Sru } else { 110114402Sru assert stackSlot.getRawAddFrameSize() : "Unexpected stack slot: " + stackSlot; 111114402Sru int offset = -stackSlot.getRawOffset(); 112114402Sru assert 0 <= offset && offset < firstVirtualStackIndex : String.format("Wrong stack slot offset: %d (first virtual stack slot index: %d", offset, firstVirtualStackIndex); 113114402Sru stackIdx = offset; 114114402Sru } 115114402Sru return stackIdx; 116114402Sru } 117114402Sru 118114402Sru private int getStackArrayIndex(VirtualStackSlot virtualStackSlot) { 119114402Sru return firstVirtualStackIndex + virtualStackSlot.getId(); 120114402Sru } 121114402Sru 122114402Sru @Override 123114402Sru protected void setValueBlocked(Value location, int direction) { 124114402Sru assert direction == 1 || direction == -1 : "out of bounds"; 125114402Sru if (isStackSlotValue(location)) { 126114402Sru int stackIdx = getStackArrayIndex(location); 127114402Sru if (stackIdx == STACK_SLOT_IN_CALLER_FRAME_IDX) { 128114402Sru // incoming stack arguments can be ignored 129114402Sru return; 130114402Sru } 131114402Sru if (stackIdx >= stackBlocked.length) { 132114402Sru stackBlocked = Arrays.copyOf(stackBlocked, stackIdx + 1); 133114402Sru } 134114402Sru stackBlocked[stackIdx] += direction; 135114402Sru } else { 136114402Sru super.setValueBlocked(location, direction); 137114402Sru } 138114402Sru } 139114402Sru 140114402Sru @Override 141114402Sru protected int valueBlocked(Value location) { 142114402Sru if (isStackSlotValue(location)) { 143114402Sru int stackIdx = getStackArrayIndex(location); 144114402Sru if (stackIdx == STACK_SLOT_IN_CALLER_FRAME_IDX) { 145114402Sru // incoming stack arguments are always blocked (aka they can not be written) 146114402Sru return 1; 147114402Sru } 148114402Sru if (stackIdx >= stackBlocked.length) { 149114402Sru return 0; 150114402Sru } 151114402Sru return stackBlocked[stackIdx]; 152114402Sru } 153114402Sru return super.valueBlocked(location); 154114402Sru } 155114402Sru 156114402Sru @Override 157114402Sru protected LIRInstruction createMove(AllocatableValue fromOpr, AllocatableValue toOpr, AllocatableValue fromLocation, AllocatableValue toLocation) { 158114402Sru if (isStackSlotValue(toLocation) && isStackSlotValue(fromLocation)) { 159114402Sru return getAllocator().getSpillMoveFactory().createStackMove(toOpr, fromOpr); 160114402Sru } 161114402Sru return super.createMove(fromOpr, toOpr, fromLocation, toLocation); 162114402Sru } 163114402Sru 164114402Sru @Override 165114402Sru protected void breakCycle(int spillCandidate) { 166114402Sru if (spillCandidate != -1) { 167114402Sru super.breakCycle(spillCandidate); 168114402Sru return; 169114402Sru } 170114402Sru assert mappingFromSize() > 1; 171114402Sru // Arbitrarily select the first entry for spilling. 172114402Sru int stackSpillCandidate = 0; 173114402Sru Interval fromInterval = getMappingFrom(stackSpillCandidate); 174114402Sru // allocate new stack slot 175114402Sru VirtualStackSlot spillSlot = getAllocator().getFrameMapBuilder().allocateSpillSlot(fromInterval.kind()); 176114402Sru spillInterval(stackSpillCandidate, fromInterval, spillSlot); 177114402Sru } 178114402Sru} 179114402Sru