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);
-    }
-}