changeset 22311:24db9b5a9f04

Introduce AbstractBlockEndOp and add methods to BlockEndOp.
author Josef Eisl <josef.eisl@jku.at>
date Fri, 03 Jul 2015 10:35:09 +0200
parents d769b9ccc2b5
children 6fd6cf960c72
files graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizeOp.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotDeoptimizeCallerOp.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueBlockEndOp.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueOp.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEpilogueOp.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BlockEndOp.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBlockEndOp.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java
diffstat 14 files changed, 310 insertions(+), 108 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizeOp.java	Thu Jul 23 12:12:45 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizeOp.java	Fri Jul 03 10:35:09 2015 +0200
@@ -31,7 +31,7 @@
 import com.oracle.graal.lir.asm.*;
 
 @Opcode("DEOPT")
-final class AMD64DeoptimizeOp extends AMD64LIRInstruction implements BlockEndOp {
+final class AMD64DeoptimizeOp extends AMD64BlockEndOp implements BlockEndOp {
     public static final LIRInstructionClass<AMD64DeoptimizeOp> TYPE = LIRInstructionClass.create(AMD64DeoptimizeOp.class);
 
     @State private LIRFrameState info;
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotDeoptimizeCallerOp.java	Thu Jul 23 12:12:45 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotDeoptimizeCallerOp.java	Fri Jul 03 10:35:09 2015 +0200
@@ -23,19 +23,19 @@
 package com.oracle.graal.hotspot.amd64;
 
 import static com.oracle.graal.hotspot.HotSpotHostBackend.*;
-import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.BlockEndOp;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.asm.*;
 
+import jdk.internal.jvmci.meta.*;
+
 /**
  * Removes the current frame and tail calls the uncommon trap routine.
  */
 @Opcode("DEOPT_CALLER")
-final class AMD64HotSpotDeoptimizeCallerOp extends AMD64HotSpotEpilogueOp implements BlockEndOp {
+final class AMD64HotSpotDeoptimizeCallerOp extends AMD64HotSpotEpilogueBlockEndOp {
 
     public static final LIRInstructionClass<AMD64HotSpotDeoptimizeCallerOp> TYPE = LIRInstructionClass.create(AMD64HotSpotDeoptimizeCallerOp.class);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueBlockEndOp.java	Fri Jul 03 10:35:09 2015 +0200
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012, 2014, 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.hotspot.amd64;
+
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+
+import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.amd64.*;
+import com.oracle.graal.lir.asm.*;
+
+import jdk.internal.jvmci.meta.*;
+
+/**
+ * @see AMD64HotSpotEpilogueOp
+ */
+abstract class AMD64HotSpotEpilogueBlockEndOp extends AMD64BlockEndOp {
+
+    protected AMD64HotSpotEpilogueBlockEndOp(LIRInstructionClass<? extends AMD64HotSpotEpilogueBlockEndOp> c, AllocatableValue savedRbp) {
+        super(c);
+        this.savedRbp = savedRbp;
+    }
+
+    @Use({REG, STACK}) private AllocatableValue savedRbp;
+
+    protected void leaveFrameAndRestoreRbp(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+        AMD64HotSpotEpilogueOp.leaveFrameAndRestoreRbp(savedRbp, crb, masm);
+    }
+
+}
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueOp.java	Thu Jul 23 12:12:45 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueOp.java	Fri Jul 03 10:35:09 2015 +0200
@@ -46,6 +46,10 @@
     @Use({REG, STACK}) private AllocatableValue savedRbp;
 
     protected void leaveFrameAndRestoreRbp(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+        leaveFrameAndRestoreRbp(savedRbp, crb, masm);
+    }
+
+    static void leaveFrameAndRestoreRbp(AllocatableValue savedRbp, CompilationResultBuilder crb, AMD64MacroAssembler masm) {
         if (isStackSlot(savedRbp)) {
             // Restoring RBP from the stack must be done before the frame is removed
             masm.movq(rbp, (AMD64Address) crb.asAddress(savedRbp));
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java	Thu Jul 23 12:12:45 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java	Fri Jul 03 10:35:09 2015 +0200
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.hotspot.amd64;
 
-import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.meta.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 import static jdk.internal.jvmci.amd64.AMD64.*;
 import static jdk.internal.jvmci.code.ValueUtil.*;
@@ -31,15 +29,17 @@
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.asm.amd64.AMD64Assembler.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.BlockEndOp;
 import com.oracle.graal.lir.asm.*;
 
+import jdk.internal.jvmci.code.*;
+import jdk.internal.jvmci.meta.*;
+
 /**
  * Sets up the arguments for an exception handler in the callers frame, removes the current frame
  * and jumps to the handler.
  */
 @Opcode("JUMP_TO_EXCEPTION_HANDLER_IN_CALLER")
-final class AMD64HotSpotJumpToExceptionHandlerInCallerOp extends AMD64HotSpotEpilogueOp implements BlockEndOp {
+final class AMD64HotSpotJumpToExceptionHandlerInCallerOp extends AMD64HotSpotEpilogueBlockEndOp {
 
     public static final LIRInstructionClass<AMD64HotSpotJumpToExceptionHandlerInCallerOp> TYPE = LIRInstructionClass.create(AMD64HotSpotJumpToExceptionHandlerInCallerOp.class);
 
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java	Thu Jul 23 12:12:45 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java	Fri Jul 03 10:35:09 2015 +0200
@@ -23,20 +23,20 @@
 package com.oracle.graal.hotspot.amd64;
 
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+
+import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.asm.*;
+
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.hotspot.*;
 import jdk.internal.jvmci.meta.*;
 
-import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.BlockEndOp;
-import com.oracle.graal.lir.asm.*;
-
 /**
  * Returns from a function.
  */
 @Opcode("RETURN")
-final class AMD64HotSpotReturnOp extends AMD64HotSpotEpilogueOp implements BlockEndOp {
+final class AMD64HotSpotReturnOp extends AMD64HotSpotEpilogueBlockEndOp {
 
     public static final LIRInstructionClass<AMD64HotSpotReturnOp> TYPE = LIRInstructionClass.create(AMD64HotSpotReturnOp.class);
     @Use({REG, ILLEGAL}) protected Value value;
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java	Thu Jul 23 12:12:45 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java	Fri Jul 03 10:35:09 2015 +0200
@@ -26,21 +26,21 @@
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 import static jdk.internal.jvmci.amd64.AMD64.*;
 import static jdk.internal.jvmci.code.ValueUtil.*;
-import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.BlockEndOp;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.asm.*;
 
+import jdk.internal.jvmci.code.*;
+import jdk.internal.jvmci.meta.*;
+
 /**
  * Removes the current frame and jumps to the {@link UnwindExceptionToCallerStub}.
  */
 @Opcode("UNWIND")
-final class AMD64HotSpotUnwindOp extends AMD64HotSpotEpilogueOp implements BlockEndOp {
+final class AMD64HotSpotUnwindOp extends AMD64HotSpotEpilogueBlockEndOp {
     public static final LIRInstructionClass<AMD64HotSpotUnwindOp> TYPE = LIRInstructionClass.create(AMD64HotSpotUnwindOp.class);
 
     @Use({REG}) protected RegisterValue exception;
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java	Thu Jul 23 12:12:45 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java	Fri Jul 03 10:35:09 2015 +0200
@@ -28,12 +28,11 @@
 
 import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.BlockEndOp;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.sparc.*;
 
 @Opcode("DEOPT")
-final class SPARCDeoptimizeOp extends SPARCLIRInstruction implements BlockEndOp {
+final class SPARCDeoptimizeOp extends SPARCBlockEndOp {
     public static final LIRInstructionClass<SPARCDeoptimizeOp> TYPE = LIRInstructionClass.create(SPARCDeoptimizeOp.class);
     public static final SizeEstimate SIZE = SizeEstimate.create(1);
     @Temp AllocatableValue pcRegister;
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEpilogueOp.java	Thu Jul 23 12:12:45 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEpilogueOp.java	Fri Jul 03 10:35:09 2015 +0200
@@ -23,17 +23,16 @@
 package com.oracle.graal.hotspot.sparc;
 
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.BlockEndOp;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.sparc.*;
 
 /**
  * Superclass for operations that leave a method's frame.
  */
-abstract class SPARCHotSpotEpilogueOp extends SPARCLIRInstruction implements BlockEndOp {
+abstract class SPARCHotSpotEpilogueOp extends SPARCBlockEndOp {
     public static final LIRInstructionClass<SPARCHotSpotEpilogueOp> TYPE = LIRInstructionClass.create(SPARCHotSpotEpilogueOp.class);
 
-    protected SPARCHotSpotEpilogueOp(LIRInstructionClass<? extends LIRInstruction> c, SizeEstimate size) {
+    protected SPARCHotSpotEpilogueOp(LIRInstructionClass<? extends SPARCHotSpotEpilogueOp> c, SizeEstimate size) {
         super(c, size);
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BlockEndOp.java	Fri Jul 03 10:35:09 2015 +0200
@@ -0,0 +1,44 @@
+/*
+ * 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.amd64;
+
+import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.StandardOp.*;
+import com.oracle.graal.lir.asm.*;
+
+public abstract class AMD64BlockEndOp extends AbstractBlockEndOp {
+
+    public static final LIRInstructionClass<AMD64BlockEndOp> TYPE = LIRInstructionClass.create(AMD64BlockEndOp.class);
+
+    protected AMD64BlockEndOp(LIRInstructionClass<? extends AMD64BlockEndOp> c) {
+        super(c);
+    }
+
+    @Override
+    public final void emitCode(CompilationResultBuilder crb) {
+        emitCode(crb, (AMD64MacroAssembler) crb.asm);
+    }
+
+    public abstract void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm);
+}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java	Thu Jul 23 12:12:45 2015 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java	Fri Jul 03 10:35:09 2015 +0200
@@ -42,7 +42,7 @@
 
 public class AMD64ControlFlow {
 
-    public static final class ReturnOp extends AMD64LIRInstruction implements BlockEndOp {
+    public static final class ReturnOp extends AMD64BlockEndOp implements BlockEndOp {
         public static final LIRInstructionClass<ReturnOp> TYPE = LIRInstructionClass.create(ReturnOp.class);
         @Use({REG, ILLEGAL}) protected Value x;
 
@@ -58,7 +58,7 @@
         }
     }
 
-    public static class BranchOp extends AMD64LIRInstruction implements StandardOp.BranchOp {
+    public static class BranchOp extends AMD64BlockEndOp implements StandardOp.BranchOp {
         public static final LIRInstructionClass<BranchOp> TYPE = LIRInstructionClass.create(BranchOp.class);
         protected final ConditionFlag condition;
         protected final LabelRef trueDestination;
@@ -125,7 +125,7 @@
         }
     }
 
-    public static final class StrategySwitchOp extends AMD64LIRInstruction implements BlockEndOp {
+    public static final class StrategySwitchOp extends AMD64BlockEndOp {
         public static final LIRInstructionClass<StrategySwitchOp> TYPE = LIRInstructionClass.create(StrategySwitchOp.class);
         @Use({CONST}) protected JavaConstant[] keyConstants;
         private final LabelRef[] keyTargets;
@@ -181,7 +181,7 @@
         }
     }
 
-    public static final class TableSwitchOp extends AMD64LIRInstruction implements BlockEndOp {
+    public static final class TableSwitchOp extends AMD64BlockEndOp {
         public static final LIRInstructionClass<TableSwitchOp> TYPE = LIRInstructionClass.create(TableSwitchOp.class);
         private final int lowKey;
         private final LabelRef defaultTarget;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBlockEndOp.java	Fri Jul 03 10:35:09 2015 +0200
@@ -0,0 +1,86 @@
+/*
+ * 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.sparc;
+
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.StandardOp.*;
+
+import jdk.internal.jvmci.meta.*;
+
+public abstract class SPARCBlockEndOp extends SPARCLIRInstruction implements BlockEndOp {
+    public static final LIRInstructionClass<SPARCBlockEndOp> TYPE = LIRInstructionClass.create(SPARCBlockEndOp.class);
+
+    @Alive({REG, STACK, CONST}) private Value[] outgoingValues;
+    private int size;
+
+    protected SPARCBlockEndOp(LIRInstructionClass<? extends SPARCBlockEndOp> c) {
+        this(c, null);
+    }
+
+    protected SPARCBlockEndOp(LIRInstructionClass<? extends SPARCBlockEndOp> c, SizeEstimate sizeEstimate) {
+        super(c, sizeEstimate);
+        this.outgoingValues = Value.NO_VALUES;
+        this.size = 0;
+    }
+
+    public void setOutgoingValues(Value[] values) {
+        assert outgoingValues.length == 0;
+        assert values != null;
+        outgoingValues = values;
+        size = values.length;
+    }
+
+    public int getOutgoingSize() {
+        return size;
+    }
+
+    public Value getOutgoingValue(int idx) {
+        assert checkRange(idx);
+        return outgoingValues[idx];
+    }
+
+    private boolean checkRange(int idx) {
+        return idx < size;
+    }
+
+    public void clearOutgoingValues() {
+        outgoingValues = Value.NO_VALUES;
+        size = 0;
+    }
+
+    public int addOutgoingValues(Value[] v) {
+
+        int t = size + v.length;
+        if (t >= outgoingValues.length) {
+            Value[] newArray = new Value[t];
+            System.arraycopy(outgoingValues, 0, newArray, 0, size);
+            outgoingValues = newArray;
+        }
+        System.arraycopy(v, 0, outgoingValues, size, v.length);
+        size = t;
+        return t;
+
+    }
+}
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Thu Jul 23 12:12:45 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Fri Jul 03 10:35:09 2015 +0200
@@ -38,7 +38,6 @@
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
 import jdk.internal.jvmci.meta.*;
-import jdk.internal.jvmci.sparc.*;
 import jdk.internal.jvmci.sparc.SPARC.CPUFeature;
 
 import com.oracle.graal.asm.*;
@@ -51,7 +50,6 @@
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx;
 import com.oracle.graal.compiler.common.calc.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.BlockEndOp;
 import com.oracle.graal.lir.SwitchStrategy.BaseSwitchClosure;
 import com.oracle.graal.lir.asm.*;
 
@@ -60,7 +58,7 @@
     // if does not fit into simm5 of cbcond) instruction and the final branch instruction
     private static final int maximumSelfOffsetInstructions = 2;
 
-    public static final class ReturnOp extends SPARCLIRInstruction implements BlockEndOp {
+    public static final class ReturnOp extends SPARCBlockEndOp {
         public static final LIRInstructionClass<ReturnOp> TYPE = LIRInstructionClass.create(ReturnOp.class);
         public static final SizeEstimate SIZE = SizeEstimate.create(2);
 
@@ -83,7 +81,7 @@
         }
     }
 
-    public static final class CompareBranchOp extends SPARCLIRInstruction implements BlockEndOp, SPARCDelayedControlTransfer {
+    public static final class CompareBranchOp extends SPARCBlockEndOp implements SPARCDelayedControlTransfer {
         public static final LIRInstructionClass<CompareBranchOp> TYPE = LIRInstructionClass.create(CompareBranchOp.class);
         public static final SizeEstimate SIZE = SizeEstimate.create(3);
         static final EnumSet<Kind> SUPPORTED_KINDS = EnumSet.of(Kind.Long, Kind.Int, Kind.Object, Kind.Float, Kind.Double);
@@ -312,15 +310,12 @@
 
     private static boolean isShortBranch(SPARCAssembler asm, int position, LabelHint hint, Label label) {
         int disp = 0;
-        boolean dispValid = true;
         if (label.isBound()) {
             disp = label.position() - position;
         } else if (hint != null && hint.isValid()) {
             disp = hint.getTarget() - hint.getPosition();
-        } else {
-            dispValid = false;
         }
-        if (dispValid) {
+        if (disp != 0) {
             if (disp < 0) {
                 disp -= maximumSelfOffsetInstructions * asm.target.wordSize;
             } else {
@@ -333,7 +328,7 @@
         return false;
     }
 
-    public static final class BranchOp extends SPARCLIRInstruction implements StandardOp.BranchOp {
+    public static final class BranchOp extends SPARCBlockEndOp implements StandardOp.BranchOp {
         public static final LIRInstructionClass<BranchOp> TYPE = LIRInstructionClass.create(BranchOp.class);
         public static final SizeEstimate SIZE = SizeEstimate.create(2);
         protected final ConditionFlag conditionFlag;
@@ -398,7 +393,7 @@
         return true;
     }
 
-    public static final class StrategySwitchOp extends SPARCLIRInstruction implements BlockEndOp {
+    public static final class StrategySwitchOp extends SPARCBlockEndOp {
         public static final LIRInstructionClass<StrategySwitchOp> TYPE = LIRInstructionClass.create(StrategySwitchOp.class);
         @Use({CONST}) protected JavaConstant[] keyConstants;
         private final LabelRef[] keyTargets;
@@ -407,8 +402,7 @@
         @Alive({REG, ILLEGAL}) protected Value constantTableBase;
         @Temp({REG}) protected Value scratch;
         private final SwitchStrategy strategy;
-        private final Map<Label, LabelHint> labelHints;
-        private final List<Label> conditionalLabels = new ArrayList<>();
+        private final LabelHint[] labelHints;
 
         public StrategySwitchOp(Value constantTableBase, SwitchStrategy strategy, LabelRef[] keyTargets, LabelRef defaultTarget, Value key, Value scratch) {
             super(TYPE);
@@ -419,7 +413,7 @@
             this.constantTableBase = constantTableBase;
             this.key = key;
             this.scratch = scratch;
-            this.labelHints = new HashMap<>();
+            this.labelHints = new LabelHint[keyTargets.length];
             assert keyConstants.length == keyTargets.length;
             assert keyConstants.length == strategy.keyProbabilities.length;
         }
@@ -429,31 +423,9 @@
             final Register keyRegister = asRegister(key);
             final Register constantBaseRegister = AllocatableValue.ILLEGAL.equals(constantTableBase) ? g0 : asRegister(constantTableBase);
             BaseSwitchClosure closure = new BaseSwitchClosure(crb, masm, keyTargets, defaultTarget) {
-                int conditionalLabelPointer = 0;
-
-                /**
-                 * This method caches the generated labels over two assembly passes to get
-                 * information about branch lengths.
-                 */
-                @Override
-                public Label conditionalJump(int index, Condition condition) {
-                    Label label;
-                    if (conditionalLabelPointer <= conditionalLabels.size()) {
-                        label = new Label();
-                        conditionalLabels.add(label);
-                        conditionalLabelPointer = conditionalLabels.size();
-                    } else {
-                        // TODO: (sa) We rely here on the order how the labels are generated during
-                        // code generation; if the order is not stable ower two assembly passes, the
-                        // result can be wrong
-                        label = conditionalLabels.get(conditionalLabelPointer++);
-                    }
-                    conditionalJump(index, condition, label);
-                    return label;
-                }
-
                 @Override
                 protected void conditionalJump(int index, Condition condition, Label target) {
+                    requestHint(masm, index);
                     JavaConstant constant = keyConstants[index];
                     CC conditionCode;
                     Long bits;
@@ -479,15 +451,10 @@
                             throw new JVMCIError("switch only supported for int, long and object");
                     }
                     ConditionFlag conditionFlag = fromCondition(conditionCode, condition, false);
-                    LabelHint hint = requestHint(masm, target);
-                    boolean isShortConstant = isSimm5(constant);
-                    int cbCondPosition = masm.position();
-                    if (!isShortConstant) { // Load constant takes one instruction
-                        cbCondPosition += SPARC.INSTRUCTION_SIZE;
-                    }
-                    boolean canUseShortBranch = masm.hasFeature(CBCOND) && isShortBranch(masm, cbCondPosition, hint, target);
+                    LabelHint hint = labelHints[index];
+                    boolean canUseShortBranch = masm.hasFeature(CBCOND) && hint.isValid() && isShortBranch(masm, masm.position(), hint, target);
                     if (bits != null && canUseShortBranch) {
-                        if (isShortConstant) {
+                        if (isSimm5(constant)) {
                             if (conditionCode == Icc) {
                                 masm.cbcondw(conditionFlag, keyRegister, (int) (long) bits, target);
                             } else {
@@ -518,13 +485,8 @@
             strategy.run(closure);
         }
 
-        private LabelHint requestHint(SPARCMacroAssembler masm, Label label) {
-            LabelHint hint = labelHints.get(label);
-            if (hint == null) {
-                hint = masm.requestLabelHint(label);
-                labelHints.put(label, hint);
-            }
-            return hint;
+        private void requestHint(SPARCMacroAssembler masm, int index) {
+            labelHints[index] = masm.requestLabelHint(keyTargets[index].label());
         }
 
         @Override
@@ -539,7 +501,7 @@
         }
     }
 
-    public static final class TableSwitchOp extends SPARCLIRInstruction implements BlockEndOp {
+    public static final class TableSwitchOp extends SPARCBlockEndOp {
         public static final LIRInstructionClass<TableSwitchOp> TYPE = LIRInstructionClass.create(TableSwitchOp.class);
 
         private final int lowKey;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java	Thu Jul 23 12:12:45 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java	Fri Jul 03 10:35:09 2015 +0200
@@ -27,15 +27,15 @@
 
 import java.util.*;
 
-import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.meta.*;
-
 import com.oracle.graal.asm.*;
 import com.oracle.graal.compiler.common.cfg.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.framemap.*;
 
+import jdk.internal.jvmci.code.*;
+import jdk.internal.jvmci.common.*;
+import jdk.internal.jvmci.meta.*;
+
 /**
  * A collection of machine-independent LIR operations, as well as interfaces to be implemented for
  * specific kinds or LIR operations.
@@ -47,6 +47,15 @@
      * must be the last operation in the block.
      */
     public interface BlockEndOp {
+        void setOutgoingValues(Value[] values);
+
+        int getOutgoingSize();
+
+        Value getOutgoingValue(int idx);
+
+        int addOutgoingValues(Value[] values);
+
+        void clearOutgoingValues();
     }
 
     public interface NullCheck {
@@ -74,6 +83,7 @@
          * instruction of a block, the registers are defined here in the label.
          */
         @Def({REG, STACK}) private Value[] incomingValues;
+        private int size;
 
         private final Label label;
         private final boolean align;
@@ -83,24 +93,43 @@
             this.label = label;
             this.align = align;
             this.incomingValues = Value.NO_VALUES;
+            size = 0;
         }
 
         public void setIncomingValues(Value[] values) {
-            assert incomingValues.length == 0;
+            assert this.incomingValues.length == 0;
             assert values != null;
-            incomingValues = values;
+            this.incomingValues = values;
+            size = values.length;
         }
 
         public int getIncomingSize() {
-            return incomingValues.length;
+            return size;
         }
 
         public Value getIncomingValue(int idx) {
+            assert checkRange(idx);
             return incomingValues[idx];
         }
 
         public void clearIncomingValues() {
             incomingValues = Value.NO_VALUES;
+            size = 0;
+        }
+
+        public void addIncomingValues(Value[] values) {
+            int t = size + values.length;
+            if (t >= incomingValues.length) {
+                Value[] newArray = new Value[t];
+                System.arraycopy(incomingValues, 0, newArray, 0, size);
+                incomingValues = newArray;
+            }
+            System.arraycopy(values, 0, incomingValues, size, values.length);
+            size = t;
+        }
+
+        private boolean checkRange(int idx) {
+            return idx < size;
         }
 
         @Override
@@ -123,14 +152,62 @@
         }
     }
 
+    public abstract static class AbstractBlockEndOp extends LIRInstruction implements BlockEndOp {
+        public static final LIRInstructionClass<AbstractBlockEndOp> TYPE = LIRInstructionClass.create(AbstractBlockEndOp.class);
+
+        @Alive({REG, STACK, CONST}) private Value[] outgoingValues;
+        private int size;
+
+        protected AbstractBlockEndOp(LIRInstructionClass<? extends AbstractBlockEndOp> c) {
+            super(c);
+            this.outgoingValues = Value.NO_VALUES;
+            size = 0;
+        }
+
+        public void setOutgoingValues(Value[] values) {
+            assert this.outgoingValues.length == 0;
+            assert values != null;
+            this.outgoingValues = values;
+            size = values.length;
+        }
+
+        public int getOutgoingSize() {
+            return size;
+        }
+
+        public Value getOutgoingValue(int idx) {
+            assert checkRange(idx);
+            return outgoingValues[idx];
+        }
+
+        public void clearOutgoingValues() {
+            outgoingValues = Value.NO_VALUES;
+            size = 0;
+        }
+
+        public int addOutgoingValues(Value[] values) {
+            int t = size + values.length;
+            if (t >= outgoingValues.length) {
+                Value[] newArray = new Value[t];
+                System.arraycopy(outgoingValues, 0, newArray, 0, size);
+                outgoingValues = newArray;
+            }
+            System.arraycopy(values, 0, outgoingValues, size, values.length);
+            size = t;
+            return t;
+        }
+
+        private boolean checkRange(int idx) {
+            return idx < size;
+        }
+    }
+
     /**
      * LIR operation that is an unconditional jump to a {@link #destination()}.
      */
-    public static class JumpOp extends LIRInstruction implements BlockEndOp {
+    public static class JumpOp extends AbstractBlockEndOp {
         public static final LIRInstructionClass<JumpOp> TYPE = LIRInstructionClass.create(JumpOp.class);
 
-        @Alive({REG, STACK, CONST}) private Value[] outgoingValues;
-
         private final LabelRef destination;
 
         public JumpOp(LabelRef destination) {
@@ -140,25 +217,6 @@
         protected JumpOp(LIRInstructionClass<? extends JumpOp> c, LabelRef destination) {
             super(c);
             this.destination = destination;
-            this.outgoingValues = Value.NO_VALUES;
-        }
-
-        public void setOutgoingValues(Value[] values) {
-            assert outgoingValues.length == 0;
-            assert values != null;
-            outgoingValues = values;
-        }
-
-        public int getOutgoingSize() {
-            return outgoingValues.length;
-        }
-
-        public Value getOutgoingValue(int idx) {
-            return outgoingValues[idx];
-        }
-
-        public void clearOutgoingValues() {
-            outgoingValues = Value.NO_VALUES;
         }
 
         @Override