changeset 17206:2d401b9ca70d

[SPARC] Improve the lookup for delayable candidates, renaming interfaces/methods
author Stefan Anzinger <stefan.anzinger@oracle.com>
date Tue, 23 Sep 2014 12:12:26 -0700
parents 6d8ae4c6725f
children 5a7b82c1514e
files graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEnterUnpackFramesStackFrameOp.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveCurrentStackFrameOp.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveDeoptimizedStackFrameOp.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPushInterpreterFrameOp.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/DelaySlotHolder.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCDelayedControlTransfer.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCJumpOp.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLIRInstruction.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCSaveRegistersOp.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTailDelayedLIRInstruction.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/TailDelayedLIRInstruction.java
diffstat 20 files changed, 363 insertions(+), 387 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Mon Sep 22 11:20:35 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Tue Sep 23 12:12:26 2014 -0700
@@ -53,7 +53,6 @@
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.lir.sparc.*;
-import com.oracle.graal.lir.sparc.SPARCCall.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.sparc.*;
@@ -209,7 +208,7 @@
 
     @Override
     public void emitCode(CompilationResultBuilder crb, LIR lir, ResolvedJavaMethod installedCodeOwner) {
-        fixupDelayedInstructions(lir);
+        stuffDelayedControlTransfers(lir);
         SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm;
         FrameMap frameMap = crb.frameMap;
         RegisterConfig regConfig = frameMap.registerConfig;
@@ -264,82 +263,105 @@
         }
     }
 
-    private static void fixupDelayedInstructions(LIR l) {
+    /**
+     * Fix-up over whole LIR.
+     *
+     * @see #stuffDelayedControlTransfers(LIR, AbstractBlock)
+     * @param l
+     */
+    private static void stuffDelayedControlTransfers(LIR l) {
         for (AbstractBlock<?> b : l.codeEmittingOrder()) {
-            fixupDelayedInstructions(l, b);
+            stuffDelayedControlTransfers(l, b);
         }
     }
 
-    private static void fixupDelayedInstructions(LIR l, AbstractBlock<?> block) {
-        TailDelayedLIRInstruction lastDelayable = null;
-        for (LIRInstruction inst : l.getLIRforBlock(block)) {
-            if (lastDelayable != null && inst instanceof DelaySlotHolder) {
-                if (isDelayable(inst, (LIRInstruction) lastDelayable)) {
-                    lastDelayable.setDelaySlotHolder((DelaySlotHolder) inst);
+    /**
+     * Tries to put DelayedControlTransfer instructions and DelayableLIRInstructions together. Also
+     * it tries to move the DelayedLIRInstruction to the DelayedControlTransfer instruction, if
+     * possible.
+     */
+    private static void stuffDelayedControlTransfers(LIR l, AbstractBlock<?> block) {
+        List<LIRInstruction> instructions = l.getLIRforBlock(block);
+        if (instructions.size() >= 2) {
+            LIRDependencyAccumulator acc = new LIRDependencyAccumulator();
+            SPARCDelayedControlTransfer delayedTransfer = null;
+            int delayTransferPosition = -1;
+            for (int i = instructions.size() - 1; i >= 0; i--) {
+                LIRInstruction inst = instructions.get(i);
+                boolean adjacent = delayTransferPosition - i == 1;
+
+                if ((!adjacent && inst.hasState()) || inst.destroysCallerSavedRegisters() || leavesRegisterWindow(inst)) {
+                    delayedTransfer = null;
                 }
-                lastDelayable = null; // We must not pull over other delay slot holder.
-            } else if (inst instanceof TailDelayedLIRInstruction) {
-                lastDelayable = (TailDelayedLIRInstruction) inst;
-            } else {
-                lastDelayable = null;
+                if (inst instanceof SPARCDelayedControlTransfer) {
+                    delayedTransfer = (SPARCDelayedControlTransfer) inst;
+                    acc.start(inst);
+                    delayTransferPosition = i;
+                } else if (delayedTransfer != null) {
+                    boolean overlap = acc.add(inst);
+                    if (inst instanceof SPARCTailDelayedLIRInstruction && !overlap) {
+                        // We have found a non overlapping LIR instruction which can be delayed
+                        ((SPARCTailDelayedLIRInstruction) inst).setDelayedControlTransfer(delayedTransfer);
+                        delayedTransfer = null;
+                        if (!adjacent) {
+                            // If not adjacent, we make it adjacent
+                            instructions.remove(i);
+                            instructions.add(delayTransferPosition - 1, inst);
+                        }
+                    }
+                }
             }
         }
     }
 
-    public static boolean isDelayable(final LIRInstruction delaySlotHolder, final LIRInstruction other) {
-        final Set<Value> delaySlotHolderInputs = new HashSet<>(2);
-        final Set<LIRFrameState> otherFrameStates = new HashSet<>(2);
-        other.forEachState(new InstructionStateProcedure() {
-            @Override
-            protected void doState(LIRInstruction instruction, LIRFrameState state) {
-                otherFrameStates.add(state);
-            }
-        });
-        int frameStatesBefore = otherFrameStates.size();
-        delaySlotHolder.forEachState(new InstructionStateProcedure() {
-            @Override
-            protected void doState(LIRInstruction instruction, LIRFrameState state) {
-                otherFrameStates.add(state);
-            }
-        });
-        if (frameStatesBefore != otherFrameStates.size() && otherFrameStates.size() >= 2) {
-            // both have framestates, the instruction is not delayable
-            return false;
-        }
-        // Direct calls do not have dependencies to data before
-        if (delaySlotHolder instanceof DirectCallOp) {
-            return true;
-        }
-        delaySlotHolder.visitEachInput(new InstructionValueConsumer() {
+    private static boolean leavesRegisterWindow(LIRInstruction inst) {
+        return inst instanceof SPARCLIRInstruction && ((SPARCLIRInstruction) inst).leavesRegisterWindow();
+    }
+
+    /**
+     * Accumulates inputs/outputs/temp/alive in a set along we walk back the LIRInstructions and
+     * detects, if there is any overlap. In this way LIRInstructions can be detected, which can be
+     * moved nearer to the DelayedControlTransfer instruction.
+     */
+    private static class LIRDependencyAccumulator {
+        private final Set<Object> inputs = new HashSet<>(10);
+        private boolean overlap = false;
+
+        private final InstructionValueConsumer valueConsumer = new InstructionValueConsumer() {
             @Override
             protected void visitValue(LIRInstruction instruction, Value value) {
-                delaySlotHolderInputs.add(value);
+                Object valueObject = value;
+                if (isRegister(value)) { // Canonicalize registers
+                    valueObject = asRegister(value);
+                }
+                if (!inputs.add(valueObject)) {
+                    overlap = true;
+                }
             }
-        });
-        delaySlotHolder.visitEachTemp(new InstructionValueConsumer() {
-            @Override
-            protected void visitValue(LIRInstruction instruction, Value value) {
-                delaySlotHolderInputs.add(value);
-            }
-        });
-        if (delaySlotHolderInputs.size() == 0) {
-            return true;
+        };
+
+        public void start(LIRInstruction initial) {
+            inputs.clear();
+            overlap = false;
+            initial.visitEachInput(valueConsumer);
+            initial.visitEachTemp(valueConsumer);
+            initial.visitEachAlive(valueConsumer);
         }
-        final Set<Value> otherOutputs = new HashSet<>();
-        other.visitEachOutput(new InstructionValueConsumer() {
-            @Override
-            protected void visitValue(LIRInstruction instruction, Value value) {
-                otherOutputs.add(value);
-            }
-        });
-        other.visitEachTemp(new InstructionValueConsumer() {
-            @Override
-            protected void visitValue(LIRInstruction instruction, Value value) {
-                otherOutputs.add(value);
-            }
-        });
-        int sizeBefore = otherOutputs.size();
-        otherOutputs.removeAll(delaySlotHolderInputs);
-        return otherOutputs.size() == sizeBefore;
+
+        /**
+         * Adds the inputs of lir instruction to the accumulator and returns, true if there was any
+         * overlap of parameters.
+         *
+         * @param inst
+         * @return true if an overlap was found
+         */
+        public boolean add(LIRInstruction inst) {
+            overlap = false;
+            inst.visitEachOutput(valueConsumer);
+            inst.visitEachTemp(valueConsumer);
+            inst.visitEachInput(valueConsumer);
+            inst.visitEachAlive(valueConsumer);
+            return overlap;
+        }
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java	Mon Sep 22 11:20:35 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java	Tue Sep 23 12:12:26 2014 -0700
@@ -55,7 +55,7 @@
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
 
         // Restore the thread register when coming back from the runtime.
-        SPARCMove.move(crb, masm, thread.asValue(LIRKind.value(Kind.Long)), threadTemp, DelaySlotHolder.DUMMY);
+        SPARCMove.move(crb, masm, thread.asValue(LIRKind.value(Kind.Long)), threadTemp, SPARCDelayedControlTransfer.DUMMY);
 
         // Reset last Java frame, last Java PC and flags.
         new Stx(g0, new SPARCAddress(thread, threadLastJavaSpOffset)).emit(masm);
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java	Mon Sep 22 11:20:35 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java	Tue Sep 23 12:12:26 2014 -0700
@@ -35,13 +35,12 @@
 import com.oracle.graal.lir.sparc.*;
 
 @Opcode("CRUNTIME_CALL_PROLOGUE")
-final class SPARCHotSpotCRuntimeCallPrologueOp extends SPARCLIRInstruction implements TailDelayedLIRInstruction {
+final class SPARCHotSpotCRuntimeCallPrologueOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction {
 
     private final int threadLastJavaSpOffset;
     private final Register thread;
     private final Register stackPointer;
     @Def({REG, STACK}) protected Value threadTemp;
-    private DelaySlotHolder delayHolder = DelaySlotHolder.DUMMY;
 
     public SPARCHotSpotCRuntimeCallPrologueOp(int threadLastJavaSpOffset, Register thread, Register stackPointer, Value threadTemp) {
         this.threadLastJavaSpOffset = threadLastJavaSpOffset;
@@ -57,10 +56,6 @@
         new Stx(g4, new SPARCAddress(thread, threadLastJavaSpOffset)).emit(masm);
 
         // Save the thread register when calling out to the runtime.
-        SPARCMove.move(crb, masm, threadTemp, thread.asValue(LIRKind.value(Kind.Long)), delayHolder);
-    }
-
-    public void setDelaySlotHolder(DelaySlotHolder holder) {
-        this.delayHolder = holder;
+        SPARCMove.move(crb, masm, threadTemp, thread.asValue(LIRKind.value(Kind.Long)), delayedControlTransfer);
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEnterUnpackFramesStackFrameOp.java	Mon Sep 22 11:20:35 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEnterUnpackFramesStackFrameOp.java	Tue Sep 23 12:12:26 2014 -0700
@@ -93,4 +93,9 @@
          */
         new Mov(thread, l7).emit(masm);
     }
+
+    @Override
+    public boolean leavesRegisterWindow() {
+        return true;
+    }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveCurrentStackFrameOp.java	Mon Sep 22 11:20:35 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveCurrentStackFrameOp.java	Tue Sep 23 12:12:26 2014 -0700
@@ -50,4 +50,9 @@
 
         crb.frameContext.leave(crb);
     }
+
+    @Override
+    public boolean leavesRegisterWindow() {
+        return true;
+    }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveDeoptimizedStackFrameOp.java	Mon Sep 22 11:20:35 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveDeoptimizedStackFrameOp.java	Tue Sep 23 12:12:26 2014 -0700
@@ -47,4 +47,9 @@
 
         new RestoreWindow().emit(masm);
     }
+
+    @Override
+    public boolean leavesRegisterWindow() {
+        return true;
+    }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPushInterpreterFrameOp.java	Mon Sep 22 11:20:35 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPushInterpreterFrameOp.java	Tue Sep 23 12:12:26 2014 -0700
@@ -75,4 +75,9 @@
         // Move frame's new PC into i7
         new Mov(framePcRegister, i7).emit(masm);
     }
+
+    @Override
+    public boolean leavesRegisterWindow() {
+        return true;
+    }
 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/DelaySlotHolder.java	Mon Sep 22 11:20:35 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2013, 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.lir.sparc;
-
-import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.asm.*;
-
-/**
- * This interface can be used for {@link LIRInstruction}s which may provide a delay slot. If a delay
- * slot for this LIRInstruction is requrested, the requester just calls the method
- * {@link #emitForDelay(CompilationResultBuilder, SPARCMacroAssembler)}.
- *
- * @see TailDelayedLIRInstruction
- */
-public interface DelaySlotHolder {
-
-    DelaySlotHolder DUMMY = new DelaySlotHolder() {
-        public void emitForDelay(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            // do nothing
-        }
-
-        @Override
-        public String toString() {
-            return "null";
-        }
-    };
-
-    public void emitForDelay(CompilationResultBuilder crb, SPARCMacroAssembler masm);
-
-}
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Mon Sep 22 11:20:35 2014 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Tue Sep 23 12:12:26 2014 -0700
@@ -51,12 +51,11 @@
     /**
      * Unary operation with separate source and destination operand.
      */
-    public static class Unary2Op extends SPARCLIRInstruction implements TailDelayedLIRInstruction {
+    public static class Unary2Op extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction {
 
         @Opcode private final SPARCArithmetic opcode;
         @Def({REG}) protected AllocatableValue result;
         @Use({REG}) protected AllocatableValue x;
-        private DelaySlotHolder delaySlotLir = DelaySlotHolder.DUMMY;
 
         public Unary2Op(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x) {
             this.opcode = opcode;
@@ -66,11 +65,7 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            emitUnary(crb, masm, opcode, result, x, null, delaySlotLir);
-        }
-
-        public void setDelaySlotHolder(DelaySlotHolder holder) {
-            this.delaySlotLir = holder;
+            emitUnary(crb, masm, opcode, result, x, null, delayedControlTransfer);
         }
     }
 
@@ -78,14 +73,13 @@
      * Binary operation with two operands. The first source operand is combined with the
      * destination. The second source operand must be a register.
      */
-    public static class BinaryRegReg extends SPARCLIRInstruction implements TailDelayedLIRInstruction {
+    public static class BinaryRegReg extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction {
 
         @Opcode private final SPARCArithmetic opcode;
         @Def({REG}) protected Value result;
         @Use({REG}) protected Value x;
         @Alive({REG}) protected Value y;
         @State LIRFrameState state;
-        private DelaySlotHolder delaySlotLir = DelaySlotHolder.DUMMY;
 
         public BinaryRegReg(SPARCArithmetic opcode, Value result, Value x, Value y) {
             this(opcode, result, x, y, null);
@@ -101,7 +95,7 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            emitRegReg(crb, masm, opcode, result, x, y, state, delaySlotLir);
+            emitRegReg(crb, masm, opcode, result, x, y, state, delayedControlTransfer);
         }
 
         @Override
@@ -109,23 +103,18 @@
             super.verify();
             verifyKind(opcode, result, x, y);
         }
-
-        public void setDelaySlotHolder(DelaySlotHolder holder) {
-            this.delaySlotLir = holder;
-        }
     }
 
     /**
      * Binary operation with single source/destination operand and one constant.
      */
-    public static class BinaryRegConst extends SPARCLIRInstruction implements TailDelayedLIRInstruction {
+    public static class BinaryRegConst extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction {
 
         @Opcode private final SPARCArithmetic opcode;
         @Def({REG}) protected AllocatableValue result;
         @Use({REG}) protected Value x;
         @State protected LIRFrameState state;
         protected Constant y;
-        private DelaySlotHolder delaySlotLir = DelaySlotHolder.DUMMY;
 
         public BinaryRegConst(SPARCArithmetic opcode, AllocatableValue result, Value x, Constant y) {
             this(opcode, result, x, y, null);
@@ -141,7 +130,7 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            emitRegConstant(crb, masm, opcode, result, x, y, null, delaySlotLir);
+            emitRegConstant(crb, masm, opcode, result, x, y, null, delayedControlTransfer);
         }
 
         @Override
@@ -149,16 +138,12 @@
             super.verify();
             verifyKind(opcode, result, x, y);
         }
-
-        public void setDelaySlotHolder(DelaySlotHolder holder) {
-            this.delaySlotLir = holder;
-        }
     }
 
     /**
      * Special LIR instruction as it requires a bunch of scratch registers.
      */
-    public static class RemOp extends SPARCLIRInstruction implements TailDelayedLIRInstruction {
+    public static class RemOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction {
 
         @Opcode private final SPARCArithmetic opcode;
         @Def({REG}) protected Value result;
@@ -167,7 +152,6 @@
         @Temp({REG}) protected Value scratch1;
         @Temp({REG}) protected Value scratch2;
         @State protected LIRFrameState state;
-        private DelaySlotHolder delaySlotLir = DelaySlotHolder.DUMMY;
 
         public RemOp(SPARCArithmetic opcode, Value result, Value x, Value y, LIRFrameState state, LIRGeneratorTool gen) {
             this.opcode = opcode;
@@ -181,7 +165,7 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            emitRem(crb, masm, opcode, result, x, y, scratch1, scratch2, state, delaySlotLir);
+            emitRem(crb, masm, opcode, result, x, y, scratch1, scratch2, state, delayedControlTransfer);
         }
 
         @Override
@@ -189,18 +173,14 @@
             super.verify();
             verifyKind(opcode, result, x, y);
         }
-
-        public void setDelaySlotHolder(DelaySlotHolder holder) {
-            this.delaySlotLir = holder;
-        }
     }
 
     private static void emitRegConstant(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, Constant src2, LIRFrameState info,
-                    DelaySlotHolder delaySlotLir) {
+                    SPARCDelayedControlTransfer delaySlotLir) {
         assert isSimm13(crb.asIntConst(src2)) : src2;
         int constant = crb.asIntConst(src2);
         int exceptionOffset = -1;
-        delaySlotLir.emitForDelay(crb, masm);
+        delaySlotLir.emitControlTransfer(crb, masm);
         switch (opcode) {
             case IADD:
                 new Add(asIntReg(src1), constant, asIntReg(dst)).emit(masm);
@@ -286,119 +266,119 @@
         }
     }
 
-    public static void emitRegReg(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, Value src2, LIRFrameState info, DelaySlotHolder delaySlotLir) {
+    public static void emitRegReg(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, Value src2, LIRFrameState info, SPARCDelayedControlTransfer delaySlotLir) {
         int exceptionOffset = -1;
         assert !isConstant(src1) : src1;
         assert !isConstant(src2) : src2;
         switch (opcode) {
             case IADD:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Add(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
                 break;
             case ISUB:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Sub(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
                 break;
             case IMUL:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Mulx(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
                 break;
             case IDIV:
                 new Signx(asIntReg(src1), asIntReg(src1)).emit(masm);
                 new Signx(asIntReg(src2), asIntReg(src2)).emit(masm);
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 exceptionOffset = masm.position();
                 new Sdivx(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
                 break;
             case IUDIV:
                 new Signx(asIntReg(src1), asIntReg(src1)).emit(masm);
                 new Signx(asIntReg(src2), asIntReg(src2)).emit(masm);
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 exceptionOffset = masm.position();
                 new Udivx(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
                 break;
             case IAND:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new And(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
                 break;
             case IOR:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Or(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
                 break;
             case IXOR:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Xor(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
                 break;
             case ISHL:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Sll(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
                 break;
             case ISHR:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Sra(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
                 break;
             case IUSHR:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Srl(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
                 break;
             case IREM:
                 throw GraalInternalError.unimplemented();
             case LADD:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Add(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm);
                 break;
             case LSUB:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Sub(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm);
                 break;
             case LMUL:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Mulx(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm);
                 break;
             case LDIV:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 exceptionOffset = masm.position();
                 new Sdivx(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm);
                 break;
             case LUDIV:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 exceptionOffset = masm.position();
                 new Udivx(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm);
                 break;
             case LAND:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new And(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm);
                 break;
             case LOR:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Or(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm);
                 break;
             case LXOR:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Xor(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm);
                 break;
             case LSHL:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Sllx(asLongReg(src1), asIntReg(src2), asLongReg(dst)).emit(masm);
                 break;
             case LSHR:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Srax(asLongReg(src1), asIntReg(src2), asLongReg(dst)).emit(masm);
                 break;
             case LUSHR:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Srlx(asLongReg(src1), asIntReg(src2), asLongReg(dst)).emit(masm);
                 break;
             case FADD:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Fadds(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)).emit(masm);
                 break;
             case FSUB:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Fsubs(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)).emit(masm);
                 break;
             case FMUL:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 if (dst.getPlatformKind() == Kind.Double) {
                     new Fsmuld(asFloatReg(src1), asFloatReg(src2), asDoubleReg(dst)).emit(masm);
                 } else if (dst.getPlatformKind() == Kind.Float) {
@@ -406,33 +386,33 @@
                 }
                 break;
             case FDIV:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 exceptionOffset = masm.position();
                 new Fdivs(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)).emit(masm);
                 break;
             case FREM:
                 throw GraalInternalError.unimplemented();
             case DADD:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Faddd(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)).emit(masm);
                 break;
             case DSUB:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Fsubd(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)).emit(masm);
                 break;
             case DMUL:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Fmuld(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)).emit(masm);
                 break;
             case DDIV:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 exceptionOffset = masm.position();
                 new Fdivd(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)).emit(masm);
                 break;
             case DREM:
                 throw GraalInternalError.unimplemented();
             case DAND:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Fandd(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)).emit(masm);
                 break;
             default:
@@ -445,7 +425,7 @@
     }
 
     public static void emitRem(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, Value src2, Value scratch1, Value scratch2, LIRFrameState info,
-                    DelaySlotHolder delaySlotLir) {
+                    SPARCDelayedControlTransfer delaySlotLir) {
         int exceptionOffset = -1;
         if (!isConstant(src1) && isConstant(src2)) {
             assert isSimm13(crb.asIntConst(src2));
@@ -458,21 +438,21 @@
                     exceptionOffset = masm.position();
                     new Sdivx(asIntReg(dst), crb.asIntConst(src2), asIntReg(scratch1)).emit(masm);
                     new Mulx(asIntReg(scratch1), crb.asIntConst(src2), asIntReg(scratch2)).emit(masm);
-                    delaySlotLir.emitForDelay(crb, masm);
+                    delaySlotLir.emitControlTransfer(crb, masm);
                     new Sub(asIntReg(dst), asIntReg(scratch2), asIntReg(dst)).emit(masm);
                     break;
                 case LREM:
                     exceptionOffset = masm.position();
                     new Sdivx(asLongReg(src1), crb.asIntConst(src2), asLongReg(scratch1)).emit(masm);
                     new Mulx(asLongReg(scratch1), crb.asIntConst(src2), asLongReg(scratch2)).emit(masm);
-                    delaySlotLir.emitForDelay(crb, masm);
+                    delaySlotLir.emitControlTransfer(crb, masm);
                     new Sub(asLongReg(src1), asLongReg(scratch2), asLongReg(dst)).emit(masm);
                     break;
                 case LUREM:
                     exceptionOffset = masm.position();
                     new Udivx(asLongReg(src1), crb.asIntConst(src2), asLongReg(scratch1)).emit(masm);
                     new Mulx(asLongReg(scratch1), crb.asIntConst(src2), asLongReg(scratch2)).emit(masm);
-                    delaySlotLir.emitForDelay(crb, masm);
+                    delaySlotLir.emitControlTransfer(crb, masm);
                     new Sub(asLongReg(src1), asLongReg(scratch2), asLongReg(dst)).emit(masm);
                     break;
                 case IUREM:
@@ -495,7 +475,7 @@
                     exceptionOffset = masm.position();
                     new Sdivx(asLongReg(srcLeft), asLongReg(src2), asLongReg(scratch1)).emit(masm);
                     new Mulx(asLongReg(scratch1), asLongReg(src2), asLongReg(scratch1)).emit(masm);
-                    delaySlotLir.emitForDelay(crb, masm);
+                    delaySlotLir.emitControlTransfer(crb, masm);
                     new Sub(asLongReg(srcLeft), asLongReg(scratch1), asLongReg(dst)).emit(masm);
                     break;
                 case LUREM:
@@ -508,7 +488,7 @@
                     exceptionOffset = masm.position();
                     new Udivx(asLongReg(srcLeft), asLongReg(src2), asLongReg(scratch1)).emit(masm);
                     new Mulx(asLongReg(scratch1), asLongReg(src2), asLongReg(scratch1)).emit(masm);
-                    delaySlotLir.emitForDelay(crb, masm);
+                    delaySlotLir.emitControlTransfer(crb, masm);
                     new Sub(asLongReg(srcLeft), asLongReg(scratch1), asLongReg(dst)).emit(masm);
                     break;
                 case IREM:
@@ -523,7 +503,7 @@
                     exceptionOffset = masm.position();
                     new Sdivx(asIntReg(scratch1), asIntReg(scratch2), asIntReg(dst)).emit(masm);
                     new Mulx(asIntReg(dst), asIntReg(scratch2), asIntReg(dst)).emit(masm);
-                    delaySlotLir.emitForDelay(crb, masm);
+                    delaySlotLir.emitControlTransfer(crb, masm);
                     new Sub(asIntReg(scratch1), asIntReg(dst), asIntReg(dst)).emit(masm);
                     break;
                 case IUREM:
@@ -534,7 +514,7 @@
                     exceptionOffset = masm.position();
                     new Udivx(asIntReg(scratch1), asIntReg(dst), asIntReg(scratch2)).emit(masm);
                     new Mulx(asIntReg(scratch2), asIntReg(dst), asIntReg(dst)).emit(masm);
-                    delaySlotLir.emitForDelay(crb, masm);
+                    delaySlotLir.emitControlTransfer(crb, masm);
                     new Sub(asIntReg(scratch1), asIntReg(dst), asIntReg(dst)).emit(masm);
                     break;
                 default:
@@ -549,76 +529,76 @@
         }
     }
 
-    public static void emitUnary(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCArithmetic opcode, Value dst, Value src, LIRFrameState info, DelaySlotHolder delaySlotLir) {
+    public static void emitUnary(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCArithmetic opcode, Value dst, Value src, LIRFrameState info, SPARCDelayedControlTransfer delaySlotLir) {
         int exceptionOffset = -1;
         Label notOrdered = new Label();
         switch (opcode) {
             case INEG:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Neg(asIntReg(src), asIntReg(dst)).emit(masm);
                 break;
             case LNEG:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Neg(asLongReg(src), asLongReg(dst)).emit(masm);
                 break;
             case INOT:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Not(asIntReg(src), asIntReg(dst)).emit(masm);
                 break;
             case LNOT:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Not(asLongReg(src), asLongReg(dst)).emit(masm);
                 break;
             case D2F:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Fdtos(asDoubleReg(src), asFloatReg(dst)).emit(masm);
                 break;
             case L2D:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Fxtod(asDoubleReg(src), asDoubleReg(dst)).emit(masm);
                 break;
             case L2F:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Fxtos(asDoubleReg(src), asFloatReg(dst)).emit(masm);
                 break;
             case I2D:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Fitod(asFloatReg(src), asDoubleReg(dst)).emit(masm);
                 break;
             case I2L:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Signx(asIntReg(src), asLongReg(dst)).emit(masm);
                 break;
             case L2I:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Signx(asLongReg(src), asIntReg(dst)).emit(masm);
                 break;
             case B2L:
                 new Sllx(asIntReg(src), 56, asLongReg(dst)).emit(masm);
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Srax(asLongReg(dst), 56, asLongReg(dst)).emit(masm);
                 break;
             case B2I:
                 new Sllx(asIntReg(src), 56, asIntReg(dst)).emit(masm);
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Srax(asIntReg(dst), 56, asIntReg(dst)).emit(masm);
                 break;
             case S2L:
                 new Sllx(asIntReg(src), 48, asLongReg(dst)).emit(masm);
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Srax(asLongReg(dst), 48, asLongReg(dst)).emit(masm);
                 break;
             case S2I:
                 new Sllx(asIntReg(src), 48, asIntReg(dst)).emit(masm);
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Srax(asIntReg(dst), 48, asIntReg(dst)).emit(masm);
                 break;
             case I2F:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Fitos(asFloatReg(src), asFloatReg(dst)).emit(masm);
                 break;
             case F2D:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Fstod(asFloatReg(src), asDoubleReg(dst)).emit(masm);
                 break;
             case F2L:
@@ -653,11 +633,11 @@
                 masm.bind(notOrdered);
                 break;
             case FNEG:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Fnegs(asFloatReg(src), asFloatReg(dst)).emit(masm);
                 break;
             case DNEG:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Fnegd(asDoubleReg(src), asDoubleReg(dst)).emit(masm);
                 break;
             default:
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java	Mon Sep 22 11:20:35 2014 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java	Tue Sep 23 12:12:26 2014 -0700
@@ -35,13 +35,12 @@
 import com.oracle.graal.lir.gen.*;
 
 @Opcode("BSWAP")
-public class SPARCByteSwapOp extends SPARCLIRInstruction implements TailDelayedLIRInstruction {
+public class SPARCByteSwapOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction {
 
     @Def({REG, HINT}) protected Value result;
     @Use({REG}) protected Value input;
     @Temp({REG}) protected Value tempIndex;
     @Use({STACK}) protected StackSlot tmpSlot;
-    private DelaySlotHolder delaySlotLir = DelaySlotHolder.DUMMY;
 
     public SPARCByteSwapOp(LIRGeneratorTool tool, Value result, Value input) {
         this.result = result;
@@ -52,14 +51,14 @@
 
     @Override
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-        SPARCMove.move(crb, masm, tmpSlot, input, DelaySlotHolder.DUMMY);
+        SPARCMove.move(crb, masm, tmpSlot, input, SPARCDelayedControlTransfer.DUMMY);
         SPARCAddress addr = (SPARCAddress) crb.asAddress(tmpSlot);
         if (addr.getIndex().equals(Register.None)) {
             Register tempReg = ValueUtil.asLongReg(tempIndex);
             new SPARCMacroAssembler.Setx(addr.getDisplacement(), tempReg, false).emit(masm);
             addr = new SPARCAddress(addr.getBase(), tempReg);
         }
-        delaySlotLir.emitForDelay(crb, masm);
+        delayedControlTransfer.emitControlTransfer(crb, masm);
         switch (input.getKind()) {
             case Int:
                 new SPARCAssembler.Lduwa(addr.getBase(), addr.getIndex(), asIntReg(result), Asi.ASI_PRIMARY_LITTLE).emit(masm);
@@ -71,8 +70,4 @@
                 throw GraalInternalError.shouldNotReachHere();
         }
     }
-
-    public void setDelaySlotHolder(DelaySlotHolder holder) {
-        this.delaySlotLir = holder;
-    }
 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java	Mon Sep 22 11:20:35 2014 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java	Tue Sep 23 12:12:26 2014 -0700
@@ -73,7 +73,7 @@
     }
 
     @Opcode("CALL_DIRECT")
-    public static class DirectCallOp extends MethodCallOp implements DelaySlotHolder {
+    public static class DirectCallOp extends MethodCallOp implements SPARCDelayedControlTransfer {
         private boolean emitted = false;
         private int before = -1;
 
@@ -107,7 +107,7 @@
             //
         }
 
-        public void emitForDelay(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+        public void emitControlTransfer(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             assert !emitted;
             emitCallPrefixCode(crb, masm);
             before = masm.position();
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Mon Sep 22 11:20:35 2014 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Tue Sep 23 12:12:26 2014 -0700
@@ -62,7 +62,7 @@
         }
     }
 
-    public static class CompareBranchOp extends SPARCLIRInstruction implements BlockEndOp, DelaySlotHolder {
+    public static class CompareBranchOp extends SPARCLIRInstruction implements BlockEndOp, SPARCDelayedControlTransfer {
 
         private final SPARCCompare opcode;
         @Use({REG}) protected Value x;
@@ -73,6 +73,7 @@
         protected final Kind kind;
         protected final boolean unorderedIsTrue;
         private boolean emitted = false;
+        private int delaySlotPosition = -1;
         private double trueDestinationProbability;
 
         public CompareBranchOp(SPARCCompare opcode, Value x, Value y, Condition condition, LabelRef trueDestination, LabelRef falseDestination, Kind kind, boolean unorderedIsTrue,
@@ -90,14 +91,18 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            if (emitted) { // Only if delayed control transfer is used we must check this
+                assert masm.position() - delaySlotPosition == 4 : "Only one instruction can be stuffed into the delay slot";
+            }
             if (!emitted) {
                 SPARCCompare.emit(crb, masm, opcode, x, y);
                 emitted = emitBranch(crb, masm, true);
             }
+
             assert emitted;
         }
 
-        public void emitForDelay(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+        public void emitControlTransfer(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             SPARCCompare.emit(crb, masm, opcode, x, y);
             emitted = emitBranch(crb, masm, false);
         }
@@ -132,6 +137,7 @@
                 assert actualCondition != null;
                 SPARCControlFlow.emitBranch(masm, actualTarget, actualCondition, cc, predictBranchTaken);
             }
+            delaySlotPosition = masm.position();
             if (withDelayedNop) {
                 new Nop().emit(masm);  // delay slot
             }
@@ -356,13 +362,13 @@
                             emitBranch(masm, target, condition, CC.Icc, false);
                             break;
                         case Long: {
-                            SPARCMove.move(crb, masm, scratch, keyConstants[index], DelaySlotHolder.DUMMY);
+                            SPARCMove.move(crb, masm, scratch, keyConstants[index], SPARCDelayedControlTransfer.DUMMY);
                             new Cmp(keyRegister, asLongReg(scratch)).emit(masm);
                             emitBranch(masm, target, condition, CC.Xcc, false);
                             break;
                         }
                         case Object: {
-                            SPARCMove.move(crb, masm, scratch, keyConstants[index], DelaySlotHolder.DUMMY);
+                            SPARCMove.move(crb, masm, scratch, keyConstants[index], SPARCDelayedControlTransfer.DUMMY);
                             new Cmp(keyRegister, asObjectReg(scratch)).emit(masm);
                             emitBranch(masm, target, condition, CC.Ptrcc, false);
                             break;
@@ -486,7 +492,7 @@
                     actualTrueValue = falseValue;
                     actualFalseValue = trueValue;
                 }
-                SPARCMove.move(crb, masm, result, actualFalseValue, DelaySlotHolder.DUMMY);
+                SPARCMove.move(crb, masm, result, actualFalseValue, SPARCDelayedControlTransfer.DUMMY);
                 cmove(masm, cc, kind, result, actualCondition, actualTrueValue);
             }
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCDelayedControlTransfer.java	Tue Sep 23 12:12:26 2014 -0700
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2013, 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.lir.sparc;
+
+import com.oracle.graal.asm.sparc.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.asm.*;
+
+/**
+ * This interface is used for {@link LIRInstruction}s which provide a delay slot for one instruction
+ * from another {@link LIRInstruction}.
+ *
+ * @see SPARCTailDelayedLIRInstruction
+ */
+public interface SPARCDelayedControlTransfer {
+
+    SPARCDelayedControlTransfer DUMMY = new SPARCDelayedControlTransfer() {
+        public void emitControlTransfer(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            // do nothing
+        }
+
+        @Override
+        public String toString() {
+            return "null";
+        }
+    };
+
+    /**
+     * This method must be called, to generate the control transfer, but without any Nop in the
+     * delay slot.
+     *
+     * @param crb
+     * @param masm
+     */
+    public void emitControlTransfer(CompilationResultBuilder crb, SPARCMacroAssembler masm);
+}
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCJumpOp.java	Mon Sep 22 11:20:35 2014 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCJumpOp.java	Tue Sep 23 12:12:26 2014 -0700
@@ -29,18 +29,20 @@
 import com.oracle.graal.lir.StandardOp.JumpOp;
 import com.oracle.graal.lir.asm.*;
 
-public class SPARCJumpOp extends JumpOp implements DelaySlotHolder {
+public class SPARCJumpOp extends JumpOp implements SPARCDelayedControlTransfer {
     private boolean emitDone = false;
+    private int delaySlotPosition = -1;
 
     public SPARCJumpOp(LabelRef destination) {
         super(destination);
     }
 
-    public void emitForDelay(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+    public void emitControlTransfer(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
         assert !emitDone;
         if (!crb.isSuccessorEdge(destination())) {
             new Bpa(destination().label()).emit(masm);
         }
+        delaySlotPosition = masm.position();
         emitDone = true;
     }
 
@@ -52,6 +54,8 @@
                 new Bpa(destination().label()).emit(masm);
                 new Nop().emit(masm);
             }
+        } else {
+            assert crb.asm.position() - delaySlotPosition == 4;
         }
     }
 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLIRInstruction.java	Mon Sep 22 11:20:35 2014 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLIRInstruction.java	Tue Sep 23 12:12:26 2014 -0700
@@ -30,6 +30,7 @@
  * Convenience class to provide SPARCMacroAssembler for the {@link #emitCode} method.
  */
 public abstract class SPARCLIRInstruction extends LIRInstruction {
+    protected SPARCDelayedControlTransfer delayedControlTransfer = SPARCDelayedControlTransfer.DUMMY;
 
     @Override
     public final void emitCode(CompilationResultBuilder crb) {
@@ -37,4 +38,12 @@
     }
 
     public abstract void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm);
+
+    public boolean leavesRegisterWindow() {
+        return false;
+    }
+
+    public void setDelayedControlTransfer(SPARCDelayedControlTransfer holder) {
+        this.delayedControlTransfer = holder;
+    }
 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java	Mon Sep 22 11:20:35 2014 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java	Tue Sep 23 12:12:26 2014 -0700
@@ -31,7 +31,7 @@
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 
-public class SPARCMathIntrinsicOp extends SPARCLIRInstruction implements TailDelayedLIRInstruction {
+public class SPARCMathIntrinsicOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction {
 
     public enum IntrinsicOpcode {
         SQRT,
@@ -46,7 +46,6 @@
     @Opcode private final IntrinsicOpcode opcode;
     @Def protected Value result;
     @Use protected Value input;
-    private DelaySlotHolder delaySlotHolder = DelaySlotHolder.DUMMY;
 
     public SPARCMathIntrinsicOp(IntrinsicOpcode opcode, Value result, Value input) {
         this.opcode = opcode;
@@ -57,7 +56,7 @@
     @Override
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
         Kind inputKind = (Kind) input.getLIRKind().getPlatformKind();
-        delaySlotHolder.emitForDelay(crb, masm);
+        delayedControlTransfer.emitControlTransfer(crb, masm);
         switch (opcode) {
             case SQRT:
                 switch (inputKind) {
@@ -93,8 +92,4 @@
         }
     }
 
-    public void setDelaySlotHolder(DelaySlotHolder holder) {
-        this.delaySlotHolder = holder;
-    }
-
 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Mon Sep 22 11:20:35 2014 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Tue Sep 23 12:12:26 2014 -0700
@@ -43,11 +43,10 @@
 public class SPARCMove {
 
     @Opcode("MOVE_TOREG")
-    public static class MoveToRegOp extends SPARCLIRInstruction implements MoveOp, TailDelayedLIRInstruction {
+    public static class MoveToRegOp extends SPARCLIRInstruction implements MoveOp, SPARCTailDelayedLIRInstruction {
 
         @Def({REG, HINT}) protected AllocatableValue result;
         @Use({REG, STACK, CONST}) protected Value input;
-        private DelaySlotHolder delaySlotLir = DelaySlotHolder.DUMMY;
 
         public MoveToRegOp(AllocatableValue result, Value input) {
             this.result = result;
@@ -56,12 +55,7 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            move(crb, masm, getResult(), getInput(), delaySlotLir);
-        }
-
-        public void setDelaySlotHolder(DelaySlotHolder holder) {
-            assert delaySlotLir == DelaySlotHolder.DUMMY : "Should be set only once";
-            this.delaySlotLir = holder;
+            move(crb, masm, getResult(), getInput(), delayedControlTransfer);
         }
 
         @Override
@@ -76,11 +70,10 @@
     }
 
     @Opcode("MOVE_FROMREG")
-    public static class MoveFromRegOp extends SPARCLIRInstruction implements MoveOp, TailDelayedLIRInstruction {
+    public static class MoveFromRegOp extends SPARCLIRInstruction implements MoveOp, SPARCTailDelayedLIRInstruction {
 
         @Def({REG, STACK}) protected AllocatableValue result;
         @Use({REG, CONST, HINT}) protected Value input;
-        private DelaySlotHolder delaySlotLir = DelaySlotHolder.DUMMY;
 
         public MoveFromRegOp(AllocatableValue result, Value input) {
             this.result = result;
@@ -89,11 +82,7 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            move(crb, masm, getResult(), getInput(), delaySlotLir);
-        }
-
-        public void setDelaySlotHolder(DelaySlotHolder holder) {
-            this.delaySlotLir = holder;
+            move(crb, masm, getResult(), getInput(), delayedControlTransfer);
         }
 
         @Override
@@ -111,12 +100,11 @@
      * Move between floating-point and general purpose register domain (WITHOUT VIS3)
      */
     @Opcode("MOVE")
-    public static class MoveFpGp extends SPARCLIRInstruction implements MoveOp, TailDelayedLIRInstruction {
+    public static class MoveFpGp extends SPARCLIRInstruction implements MoveOp, SPARCTailDelayedLIRInstruction {
 
         @Def({REG}) protected AllocatableValue result;
         @Use({REG}) protected AllocatableValue input;
         @Use({STACK}) protected StackSlot temp;
-        private DelaySlotHolder delaySlotLir = DelaySlotHolder.DUMMY;
 
         public MoveFpGp(AllocatableValue result, AllocatableValue input, StackSlot temp) {
             super();
@@ -134,10 +122,6 @@
             return result;
         }
 
-        public void setDelaySlotHolder(DelaySlotHolder holder) {
-            this.delaySlotLir = holder;
-        }
-
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             Kind inputKind = (Kind) input.getPlatformKind();
@@ -175,7 +159,7 @@
                     default:
                         GraalInternalError.shouldNotReachHere();
                 }
-                delaySlotLir.emitForDelay(crb, masm);
+                delayedControlTransfer.emitControlTransfer(crb, masm);
                 switch (resultKind) {
                     case Long:
                         new Ldx(tempAddress, asLongReg(result)).emit(masm);
@@ -210,11 +194,10 @@
      * Move between floating-point and general purpose register domain (WITH VIS3)
      */
     @Opcode("MOVE")
-    public static class MoveFpGpVIS3 extends SPARCLIRInstruction implements MoveOp, TailDelayedLIRInstruction {
+    public static class MoveFpGpVIS3 extends SPARCLIRInstruction implements MoveOp, SPARCTailDelayedLIRInstruction {
 
         @Def({REG}) protected AllocatableValue result;
         @Use({REG}) protected AllocatableValue input;
-        private DelaySlotHolder delayHolder = DelaySlotHolder.DUMMY;
 
         public MoveFpGpVIS3(AllocatableValue result, AllocatableValue input) {
             super();
@@ -234,7 +217,7 @@
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             Kind inputKind = (Kind) input.getPlatformKind();
             Kind resultKind = (Kind) result.getPlatformKind();
-            delayHolder.emitForDelay(crb, masm);
+            delayedControlTransfer.emitControlTransfer(crb, masm);
             if (resultKind == Float) {
                 if (inputKind == Int || inputKind == Short || inputKind == Char || inputKind == Byte) {
                     new Movwtos(asIntReg(input), asFloatReg(result)).emit(masm);
@@ -261,10 +244,6 @@
                 }
             }
         }
-
-        public void setDelaySlotHolder(DelaySlotHolder holder) {
-            this.delayHolder = holder;
-        }
     }
 
     public abstract static class MemOp extends SPARCLIRInstruction implements ImplicitNullCheck {
@@ -295,10 +274,9 @@
         }
     }
 
-    public static class LoadOp extends MemOp implements TailDelayedLIRInstruction {
+    public static class LoadOp extends MemOp implements SPARCTailDelayedLIRInstruction {
 
         @Def({REG}) protected AllocatableValue result;
-        DelaySlotHolder delaySlotHolder = DelaySlotHolder.DUMMY;
 
         public LoadOp(Kind kind, AllocatableValue result, SPARCAddressValue address, LIRFrameState state) {
             super(kind, address, state);
@@ -311,7 +289,7 @@
                 Register scratch = sc.getRegister();
                 final SPARCAddress addr = generateSimm13OffsetLoad(address.toAddress(), masm, scratch);
                 final Register dst = asRegister(result);
-                delaySlotHolder.emitForDelay(crb, masm);
+                delayedControlTransfer.emitControlTransfer(crb, masm);
                 if (state != null) {
                     crb.recordImplicitException(masm.position(), state);
                 }
@@ -346,17 +324,12 @@
                 }
             }
         }
-
-        public void setDelaySlotHolder(DelaySlotHolder holder) {
-            this.delaySlotHolder = holder;
-        }
     }
 
-    public static class LoadAddressOp extends SPARCLIRInstruction implements TailDelayedLIRInstruction {
+    public static class LoadAddressOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction {
 
         @Def({REG}) protected AllocatableValue result;
         @Use({COMPOSITE, UNINITIALIZED}) protected SPARCAddressValue addressValue;
-        private DelaySlotHolder delaySlotHolder = DelaySlotHolder.DUMMY;
 
         public LoadAddressOp(AllocatableValue result, SPARCAddressValue address) {
             this.result = result;
@@ -366,11 +339,7 @@
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             SPARCAddress address = addressValue.toAddress();
-            loadEffectiveAddress(crb, masm, address, asLongReg(result), delaySlotHolder);
-        }
-
-        public void setDelaySlotHolder(DelaySlotHolder holder) {
-            this.delaySlotHolder = holder;
+            loadEffectiveAddress(crb, masm, address, asLongReg(result), delayedControlTransfer);
         }
     }
 
@@ -409,11 +378,10 @@
         }
     }
 
-    public static class NullCheckOp extends SPARCLIRInstruction implements NullCheck, TailDelayedLIRInstruction {
+    public static class NullCheckOp extends SPARCLIRInstruction implements NullCheck, SPARCTailDelayedLIRInstruction {
 
         @Use({REG}) protected AllocatableValue input;
         @State protected LIRFrameState state;
-        private DelaySlotHolder delaySlotHolder = DelaySlotHolder.DUMMY;
 
         public NullCheckOp(Variable input, LIRFrameState state) {
             this.input = input;
@@ -422,7 +390,7 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            delaySlotHolder.emitForDelay(crb, masm);
+            delayedControlTransfer.emitControlTransfer(crb, masm);
             crb.recordImplicitException(masm.position(), state);
             new Ldx(new SPARCAddress(asRegister(input), 0), r0).emit(masm);
         }
@@ -434,10 +402,6 @@
         public LIRFrameState getState() {
             return state;
         }
-
-        public void setDelaySlotHolder(DelaySlotHolder holder) {
-            this.delaySlotHolder = holder;
-        }
     }
 
     @Opcode("CAS")
@@ -460,11 +424,10 @@
         }
     }
 
-    public static class StackLoadAddressOp extends SPARCLIRInstruction implements TailDelayedLIRInstruction {
+    public static class StackLoadAddressOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction {
 
         @Def({REG}) protected AllocatableValue result;
         @Use({STACK, UNINITIALIZED}) protected StackSlot slot;
-        private DelaySlotHolder delaySlotHolder = DelaySlotHolder.DUMMY;
 
         public StackLoadAddressOp(AllocatableValue result, StackSlot slot) {
             this.result = result;
@@ -474,36 +437,31 @@
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             SPARCAddress address = (SPARCAddress) crb.asAddress(slot);
-            loadEffectiveAddress(crb, masm, address, asLongReg(result), delaySlotHolder);
-        }
-
-        public void setDelaySlotHolder(DelaySlotHolder holder) {
-            this.delaySlotHolder = holder;
+            loadEffectiveAddress(crb, masm, address, asLongReg(result), delayedControlTransfer);
         }
     }
 
-    private static void loadEffectiveAddress(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCAddress address, Register result, DelaySlotHolder delaySlotHolder) {
+    private static void loadEffectiveAddress(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCAddress address, Register result, SPARCDelayedControlTransfer delaySlotHolder) {
         if (address.getIndex().equals(Register.None)) {
             if (isSimm13(address.getDisplacement())) {
-                delaySlotHolder.emitForDelay(crb, masm);
+                delaySlotHolder.emitControlTransfer(crb, masm);
                 new Add(address.getBase(), address.getDisplacement(), result).emit(masm);
             } else {
                 assert result.encoding() != address.getBase().encoding();
                 new Setx(address.getDisplacement(), result).emit(masm);
                 // No relocation, therefore, the add can be delayed as well
-                delaySlotHolder.emitForDelay(crb, masm);
+                delaySlotHolder.emitControlTransfer(crb, masm);
                 new Add(address.getBase(), result, result).emit(masm);
             }
         } else {
-            delaySlotHolder.emitForDelay(crb, masm);
+            delaySlotHolder.emitControlTransfer(crb, masm);
             new Add(address.getBase(), address.getIndex(), result).emit(masm);
         }
     }
 
-    public static class StoreOp extends MemOp implements TailDelayedLIRInstruction {
+    public static class StoreOp extends MemOp implements SPARCTailDelayedLIRInstruction {
 
         @Use({REG}) protected AllocatableValue input;
-        DelaySlotHolder delaySlotHolder = DelaySlotHolder.DUMMY;
 
         public StoreOp(Kind kind, SPARCAddressValue address, AllocatableValue input, LIRFrameState state) {
             super(kind, address, state);
@@ -516,7 +474,7 @@
             try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
                 Register scratch = sc.getRegister();
                 SPARCAddress addr = generateSimm13OffsetLoad(address.toAddress(), masm, scratch);
-                delaySlotHolder.emitForDelay(crb, masm);
+                delayedControlTransfer.emitControlTransfer(crb, masm);
                 if (state != null) {
                     crb.recordImplicitException(masm.position(), state);
                 }
@@ -549,16 +507,11 @@
                 }
             }
         }
-
-        public void setDelaySlotHolder(DelaySlotHolder holder) {
-            this.delaySlotHolder = holder;
-        }
     }
 
-    public static class StoreConstantOp extends MemOp implements TailDelayedLIRInstruction {
+    public static class StoreConstantOp extends MemOp implements SPARCTailDelayedLIRInstruction {
 
         protected final Constant input;
-        DelaySlotHolder delaySlotHolder = DelaySlotHolder.DUMMY;
 
         public StoreConstantOp(Kind kind, SPARCAddressValue address, Constant input, LIRFrameState state) {
             super(kind, address, state);
@@ -573,7 +526,7 @@
             try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
                 Register scratch = sc.getRegister();
                 SPARCAddress addr = generateSimm13OffsetLoad(address.toAddress(), masm, scratch);
-                delaySlotHolder.emitForDelay(crb, masm);
+                delayedControlTransfer.emitControlTransfer(crb, masm);
                 if (state != null) {
                     crb.recordImplicitException(masm.position(), state);
                 }
@@ -601,13 +554,9 @@
                 }
             }
         }
-
-        public void setDelaySlotHolder(DelaySlotHolder holder) {
-            this.delaySlotHolder = holder;
-        }
     }
 
-    public static void move(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, DelaySlotHolder delaySlotLir) {
+    public static void move(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, SPARCDelayedControlTransfer delaySlotLir) {
         if (isRegister(input)) {
             if (isRegister(result)) {
                 reg2reg(crb, masm, result, input, delaySlotLir);
@@ -649,7 +598,7 @@
         }
     }
 
-    private static void reg2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, DelaySlotHolder delaySlotLir) {
+    private static void reg2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, SPARCDelayedControlTransfer delaySlotLir) {
         final Register src = asRegister(input);
         final Register dst = asRegister(result);
         if (src.equals(dst)) {
@@ -663,7 +612,7 @@
             case Int:
             case Long:
             case Object:
-                delaySlotLir.emitForDelay(crb, masm);
+                delaySlotLir.emitControlTransfer(crb, masm);
                 new Mov(src, dst).emit(masm);
                 break;
             case Float:
@@ -705,13 +654,13 @@
         }
     }
 
-    private static void reg2stack(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, DelaySlotHolder delaySlotLir) {
+    private static void reg2stack(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, SPARCDelayedControlTransfer delaySlotLir) {
         SPARCAddress dst = (SPARCAddress) crb.asAddress(result);
         try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
             Register scratch = sc.getRegister();
             dst = generateSimm13OffsetLoad(dst, masm, scratch);
             Register src = asRegister(input);
-            delaySlotLir.emitForDelay(crb, masm);
+            delaySlotLir.emitControlTransfer(crb, masm);
             switch (input.getKind()) {
                 case Byte:
                 case Boolean:
@@ -740,13 +689,13 @@
         }
     }
 
-    private static void stack2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, DelaySlotHolder delaySlotLir) {
+    private static void stack2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, SPARCDelayedControlTransfer delaySlotLir) {
         SPARCAddress src = (SPARCAddress) crb.asAddress(input);
         try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
             Register scratch = sc.getRegister();
             src = generateSimm13OffsetLoad(src, masm, scratch);
             Register dst = asRegister(result);
-            delaySlotLir.emitForDelay(crb, masm);
+            delaySlotLir.emitControlTransfer(crb, masm);
             switch (input.getKind()) {
                 case Boolean:
                 case Byte:
@@ -777,36 +726,36 @@
         }
     }
 
-    private static void const2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Constant input, DelaySlotHolder delaySlotLir) {
+    private static void const2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Constant input, SPARCDelayedControlTransfer delaySlotLir) {
         try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
             Register scratch = sc.getRegister();
             boolean hasVIS3 = ((SPARC) masm.target.arch).getFeatures().contains(CPUFeature.VIS3);
             switch (input.getKind().getStackKind()) {
                 case Int:
                     if (input.isDefaultForKind()) {
-                        delaySlotLir.emitForDelay(crb, masm);
+                        delaySlotLir.emitControlTransfer(crb, masm);
                         new Clr(asIntReg(result)).emit(masm);
                     } else if (isSimm13(input.asLong())) {
-                        delaySlotLir.emitForDelay(crb, masm);
+                        delaySlotLir.emitControlTransfer(crb, masm);
                         new Or(g0, input.asInt(), asIntReg(result)).emit(masm);
                     } else {
                         Setx set = new Setx(input.asLong(), asIntReg(result), false, true);
                         set.emitFirstPartOfDelayed(masm);
-                        delaySlotLir.emitForDelay(crb, masm);
+                        delaySlotLir.emitControlTransfer(crb, masm);
                         set.emitSecondPartOfDelayed(masm);
                     }
                     break;
                 case Long:
                     if (input.isDefaultForKind()) {
-                        delaySlotLir.emitForDelay(crb, masm);
+                        delaySlotLir.emitControlTransfer(crb, masm);
                         new Clr(asLongReg(result)).emit(masm);
                     } else if (isSimm13(input.asLong())) {
-                        delaySlotLir.emitForDelay(crb, masm);
+                        delaySlotLir.emitControlTransfer(crb, masm);
                         new Or(g0, (int) input.asLong(), asLongReg(result)).emit(masm);
                     } else {
                         Setx setx = new Setx(input.asLong(), asLongReg(result), false, true);
                         setx.emitFirstPartOfDelayed(masm);
-                        delaySlotLir.emitForDelay(crb, masm);
+                        delaySlotLir.emitControlTransfer(crb, masm);
                         setx.emitSecondPartOfDelayed(masm);
                     }
                     break;
@@ -814,7 +763,7 @@
                     float constant = input.asFloat();
                     int constantBits = java.lang.Float.floatToIntBits(constant);
                     if (constantBits == 0) {
-                        delaySlotLir.emitForDelay(crb, masm);
+                        delaySlotLir.emitControlTransfer(crb, masm);
                         new Fzeros(asFloatReg(result)).emit(masm);
                     } else {
                         if (hasVIS3) {
@@ -823,7 +772,7 @@
                             } else {
                                 new Setx(constantBits, scratch, false).emit(masm);
                             }
-                            delaySlotLir.emitForDelay(crb, masm);
+                            delaySlotLir.emitControlTransfer(crb, masm);
                             // Now load the float value
                             new Movwtos(scratch, asFloatReg(result)).emit(masm);
                         } else {
@@ -831,7 +780,7 @@
                             // First load the address into the scratch register
                             new Setx(0, scratch, true).emit(masm);
                             // Now load the float value
-                            delaySlotLir.emitForDelay(crb, masm);
+                            delaySlotLir.emitControlTransfer(crb, masm);
                             new Ldf(scratch, asFloatReg(result)).emit(masm);
                         }
                     }
@@ -841,7 +790,7 @@
                     double constant = input.asDouble();
                     long constantBits = java.lang.Double.doubleToLongBits(constant);
                     if (constantBits == 0) {
-                        delaySlotLir.emitForDelay(crb, masm);
+                        delaySlotLir.emitControlTransfer(crb, masm);
                         new Fzerod(asDoubleReg(result)).emit(masm);
                     } else {
                         if (hasVIS3) {
@@ -850,14 +799,14 @@
                             } else {
                                 new Setx(constantBits, scratch, false).emit(masm);
                             }
-                            delaySlotLir.emitForDelay(crb, masm);
+                            delaySlotLir.emitControlTransfer(crb, masm);
                             // Now load the float value
                             new Movxtod(scratch, asDoubleReg(result)).emit(masm);
                         } else {
                             crb.asDoubleConstRef(input);
                             // First load the address into the scratch register
                             new Setx(0, scratch, true).emit(masm);
-                            delaySlotLir.emitForDelay(crb, masm);
+                            delaySlotLir.emitControlTransfer(crb, masm);
                             // Now load the float value
                             new Lddf(scratch, asDoubleReg(result)).emit(masm);
                         }
@@ -866,7 +815,7 @@
                 }
                 case Object:
                     if (input.isNull()) {
-                        delaySlotLir.emitForDelay(crb, masm);
+                        delaySlotLir.emitControlTransfer(crb, masm);
                         new Clr(asRegister(result)).emit(masm);
                     } else if (crb.target.inlineObjects) {
                         crb.recordInlineDataInCode(input); // relocatable cannot be delayed
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCSaveRegistersOp.java	Mon Sep 22 11:20:35 2014 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCSaveRegistersOp.java	Tue Sep 23 12:12:26 2014 -0700
@@ -70,7 +70,7 @@
 
     private static void saveRegister(CompilationResultBuilder crb, SPARCMacroAssembler masm, StackSlot result, Register register) {
         RegisterValue input = register.asValue(result.getLIRKind());
-        SPARCMove.move(crb, masm, result, input, DelaySlotHolder.DUMMY);
+        SPARCMove.move(crb, masm, result, input, SPARCDelayedControlTransfer.DUMMY);
     }
 
     @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTailDelayedLIRInstruction.java	Tue Sep 23 12:12:26 2014 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013, 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.lir.sparc;
+
+import com.oracle.graal.lir.*;
+
+/**
+ * Implementors of this interface are able to place its last instruction into the delay slot of a
+ * {@link SPARCDelayedControlTransfer} instruction.
+ *
+ * The implementor has to do following steps to emit code into the delay slot for the
+ * DelayedControlTransfer instruction:
+ * <ol>
+ * <li>Emit everything up to the second last instruction.</li>
+ * <li>Call
+ * {@link SPARCDelayedControlTransfer#emitControlTransfer(com.oracle.graal.lir.asm.CompilationResultBuilder, com.oracle.graal.asm.sparc.SPARCMacroAssembler)}
+ * to let the DelayedControlTransfer instruction emit its own code (But must not stuff the delay
+ * slot with Nop)</li>
+ * <li>emit the last instruction for this {@link LIRInstruction}</li>
+ * </ol>
+ *
+ * Note: If this instruction decides not to use the delay slot, it can skip the call of
+ * {@link SPARCDelayedControlTransfer#emitControlTransfer(com.oracle.graal.lir.asm.CompilationResultBuilder, com.oracle.graal.asm.sparc.SPARCMacroAssembler)}
+ * . The DelayedControlTransfer instruction will emit the code just with Nop in the delay slot.
+ */
+public interface SPARCTailDelayedLIRInstruction {
+    public void setDelayedControlTransfer(SPARCDelayedControlTransfer holder);
+}
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/TailDelayedLIRInstruction.java	Mon Sep 22 11:20:35 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2013, 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.lir.sparc;
-
-import com.oracle.graal.lir.*;
-
-/**
- * Implementors of this interface are able to place the last instruction to the delay slot of the
- * given {@link DelaySlotHolder}.
- *
- * This LIR instruction is still emitted in the usual way. But when emitting code for this LIR
- * instruction before the last instruction, it can transfer control over to the delay slot holder
- * LIR instruction, which then can emit code in order to get to the delay slot.
- *
- * Steps for emit delayed code
- * <ol>
- * <li>If this instruction contains more than one instruction, emit everything up to the second last
- * instruction.</li>
- * <li>Then call the
- * {@link DelaySlotHolder#emitForDelay(com.oracle.graal.lir.asm.CompilationResultBuilder, com.oracle.graal.asm.sparc.SPARCMacroAssembler)}
- * to let the delay-slot holder emit its code.</li>
- * <li>emit the last instruction for this {@link LIRInstruction}</li>
- * </ol>
- *
- * Note: If this instruction decides not to use the delay slot, it can skip the call of
- * {@link DelaySlotHolder#emitForDelay(com.oracle.graal.lir.asm.CompilationResultBuilder, com.oracle.graal.asm.sparc.SPARCMacroAssembler)}
- * and the code generation will continue without using the delay slot. Nothing other steps are
- * required.
- */
-public interface TailDelayedLIRInstruction {
-    public void setDelaySlotHolder(DelaySlotHolder holder);
-}