changeset 22927:526b102d5a20

Move creation of move instructions into separate factory.
author Roland Schatz <roland.schatz@oracle.com>
date Mon, 02 Nov 2015 15:55:00 +0100
parents 321ae5145865
children de89e36eaec6
files graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64MoveFactory.java graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64MoveFactoryBase.java graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCArithmeticLIRGenerator.java graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCMoveFactory.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMoveFactory.java 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/SPARCHotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotMoveFactory.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScan.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanAssignLocationsPhase.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanEliminateSpillMovePhase.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanOptimizeSpillPositionPhase.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanPhase.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanRegisterAllocationPhase.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanResolveDataFlowPhase.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/ssa/SSALinearScan.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/ssi/SSILinearScan.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceAllocationPhase.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceGlobalMoveResolutionPhase.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceGlobalMoveResolver.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScan.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanAllocationPhase.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanAssignLocationsPhase.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanEliminateSpillMovePhase.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanLifetimeAnalysisPhase.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanRegisterAllocationPhase.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanResolveDataFlowPhase.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceRegisterAllocationPhase.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceTrivialAllocator.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/dfa/LocationMarkerPhase.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/dfa/MarkBasePointersPhase.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/PhiResolver.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/SpillMoveFactoryBase.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/VerifyingMoveFactory.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/AllocationPhase.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/LSStackSlotAllocator.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/SimpleStackSlotAllocator.java
diffstat 44 files changed, 773 insertions(+), 565 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Mon Nov 02 15:55:00 2015 +0100
@@ -42,23 +42,13 @@
 import static com.oracle.graal.lir.LIRValueUtil.asConstantValue;
 import static com.oracle.graal.lir.LIRValueUtil.asJavaConstant;
 import static com.oracle.graal.lir.LIRValueUtil.isJavaConstant;
-import static com.oracle.graal.lir.LIRValueUtil.isStackSlotValue;
 import static jdk.vm.ci.code.ValueUtil.isAllocatableValue;
-import static jdk.vm.ci.code.ValueUtil.isRegister;
-
-import java.util.HashMap;
-import java.util.Map;
-
 import jdk.vm.ci.amd64.AMD64;
 import jdk.vm.ci.amd64.AMD64Kind;
-import jdk.vm.ci.code.Architecture;
 import jdk.vm.ci.code.CallingConvention;
-import jdk.vm.ci.code.Register;
-import jdk.vm.ci.code.RegisterConfig;
 import jdk.vm.ci.code.RegisterValue;
 import jdk.vm.ci.common.JVMCIError;
 import jdk.vm.ci.meta.AllocatableValue;
-import jdk.vm.ci.meta.Constant;
 import jdk.vm.ci.meta.JavaConstant;
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.LIRKind;
@@ -78,13 +68,11 @@
 import com.oracle.graal.compiler.common.util.Util;
 import com.oracle.graal.lir.ConstantValue;
 import com.oracle.graal.lir.LIRFrameState;
-import com.oracle.graal.lir.LIRInstruction;
 import com.oracle.graal.lir.LIRValueUtil;
 import com.oracle.graal.lir.LabelRef;
 import com.oracle.graal.lir.StandardOp.JumpOp;
 import com.oracle.graal.lir.SwitchStrategy;
 import com.oracle.graal.lir.Variable;
-import com.oracle.graal.lir.VirtualStackSlot;
 import com.oracle.graal.lir.amd64.AMD64AddressValue;
 import com.oracle.graal.lir.amd64.AMD64ArrayEqualsOp;
 import com.oracle.graal.lir.amd64.AMD64BinaryConsumer;
@@ -97,23 +85,14 @@
 import com.oracle.graal.lir.amd64.AMD64ControlFlow.ReturnOp;
 import com.oracle.graal.lir.amd64.AMD64ControlFlow.StrategySwitchOp;
 import com.oracle.graal.lir.amd64.AMD64ControlFlow.TableSwitchOp;
-import com.oracle.graal.lir.amd64.AMD64LIRInstruction;
 import com.oracle.graal.lir.amd64.AMD64Move;
-import com.oracle.graal.lir.amd64.AMD64Move.AMD64PushPopStackMove;
-import com.oracle.graal.lir.amd64.AMD64Move.AMD64StackMove;
 import com.oracle.graal.lir.amd64.AMD64Move.CompareAndSwapOp;
 import com.oracle.graal.lir.amd64.AMD64Move.LeaDataOp;
-import com.oracle.graal.lir.amd64.AMD64Move.LeaOp;
 import com.oracle.graal.lir.amd64.AMD64Move.MembarOp;
-import com.oracle.graal.lir.amd64.AMD64Move.MoveFromConstOp;
-import com.oracle.graal.lir.amd64.AMD64Move.MoveFromRegOp;
-import com.oracle.graal.lir.amd64.AMD64Move.MoveToRegOp;
 import com.oracle.graal.lir.amd64.AMD64Move.StackLeaOp;
 import com.oracle.graal.lir.amd64.AMD64Unary;
-import com.oracle.graal.lir.framemap.FrameMapBuilder;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
 import com.oracle.graal.lir.gen.LIRGenerator;
-import com.oracle.graal.lir.gen.SpillMoveFactoryBase;
 import com.oracle.graal.phases.util.Providers;
 
 /**
@@ -121,58 +100,8 @@
  */
 public abstract class AMD64LIRGenerator extends LIRGenerator {
 
-    private AMD64SpillMoveFactory moveFactory;
-    private Map<PlatformKind.Key, RegisterBackupPair> categorized;
-
-    private static class RegisterBackupPair {
-        public final Register register;
-        public final VirtualStackSlot backupSlot;
-
-        RegisterBackupPair(Register register, VirtualStackSlot backupSlot) {
-            this.register = register;
-            this.backupSlot = backupSlot;
-        }
-    }
-
-    private class AMD64SpillMoveFactory extends SpillMoveFactoryBase {
-
-        @Override
-        protected LIRInstruction createMoveIntern(AllocatableValue result, Value input) {
-            return AMD64LIRGenerator.this.createMove(result, input);
-        }
-
-        @Override
-        protected LIRInstruction createStackMoveIntern(AllocatableValue result, AllocatableValue input) {
-            return AMD64LIRGenerator.this.createStackMove(result, input);
-        }
-
-        @Override
-        protected LIRInstruction createLoadIntern(AllocatableValue result, Constant input) {
-            return AMD64LIRGenerator.this.createMoveConstant(result, input);
-        }
-    }
-
-    public AMD64LIRGenerator(LIRKindTool lirKindTool, AMD64ArithmeticLIRGenerator arithmeticLIRGen, Providers providers, CallingConvention cc, LIRGenerationResult lirGenRes) {
-        super(lirKindTool, arithmeticLIRGen, providers, cc, lirGenRes);
-    }
-
-    public SpillMoveFactory getSpillMoveFactory() {
-        if (moveFactory == null) {
-            moveFactory = new AMD64SpillMoveFactory();
-        }
-        return moveFactory;
-    }
-
-    @Override
-    public boolean canInlineConstant(JavaConstant c) {
-        switch (c.getJavaKind()) {
-            case Long:
-                return NumUtil.isInt(c.asLong()) && !getCodeCache().needsDataPatch(c);
-            case Object:
-                return c.isNull();
-            default:
-                return true;
-        }
+    public AMD64LIRGenerator(LIRKindTool lirKindTool, AMD64ArithmeticLIRGenerator arithmeticLIRGen, MoveFactory moveFactory, Providers providers, CallingConvention cc, LIRGenerationResult lirGenRes) {
+        super(lirKindTool, arithmeticLIRGen, moveFactory, providers, cc, lirGenRes);
     }
 
     /**
@@ -217,80 +146,6 @@
         }
     }
 
-    protected AMD64LIRInstruction createMove(AllocatableValue dst, Value src) {
-        if (src instanceof AMD64AddressValue) {
-            return new LeaOp(dst, (AMD64AddressValue) src);
-        } else if (isJavaConstant(src)) {
-            return createMoveConstant(dst, asJavaConstant(src));
-        } else if (isRegister(src) || isStackSlotValue(dst)) {
-            return new MoveFromRegOp((AMD64Kind) dst.getPlatformKind(), dst, (AllocatableValue) src);
-        } else {
-            return new MoveToRegOp((AMD64Kind) dst.getPlatformKind(), dst, (AllocatableValue) src);
-        }
-    }
-
-    protected AMD64LIRInstruction createMoveConstant(AllocatableValue dst, Constant src) {
-        return new MoveFromConstOp(dst, (JavaConstant) src);
-    }
-
-    protected LIRInstruction createStackMove(AllocatableValue result, AllocatableValue input) {
-        AMD64Kind kind = (AMD64Kind) result.getPlatformKind();
-        switch (kind.getSizeInBytes()) {
-            case 2:
-                return new AMD64PushPopStackMove(WORD, result, input);
-            case 8:
-                return new AMD64PushPopStackMove(QWORD, result, input);
-            default:
-                RegisterBackupPair backup = getScratchRegister(input.getPlatformKind());
-                Register scratchRegister = backup.register;
-                VirtualStackSlot backupSlot = backup.backupSlot;
-                return createStackMove(result, input, scratchRegister, backupSlot);
-        }
-    }
-
-    protected LIRInstruction createStackMove(AllocatableValue result, AllocatableValue input, Register scratchRegister, AllocatableValue backupSlot) {
-        return new AMD64StackMove(result, input, scratchRegister, backupSlot);
-    }
-
-    protected RegisterBackupPair getScratchRegister(PlatformKind kind) {
-        PlatformKind.Key key = kind.getKey();
-        if (categorized == null) {
-            categorized = new HashMap<>();
-        } else if (categorized.containsKey(key)) {
-            return categorized.get(key);
-        }
-
-        FrameMapBuilder frameMapBuilder = getResult().getFrameMapBuilder();
-        RegisterConfig registerConfig = frameMapBuilder.getRegisterConfig();
-
-        Register[] availableRegister = registerConfig.filterAllocatableRegisters(kind, registerConfig.getAllocatableRegisters());
-        assert availableRegister != null && availableRegister.length > 1;
-        Register scratchRegister = availableRegister[0];
-
-        Architecture arch = frameMapBuilder.getCodeCache().getTarget().arch;
-        LIRKind largestKind = LIRKind.value(arch.getLargestStorableKind(scratchRegister.getRegisterCategory()));
-        VirtualStackSlot backupSlot = frameMapBuilder.allocateSpillSlot(largestKind);
-
-        RegisterBackupPair value = new RegisterBackupPair(scratchRegister, backupSlot);
-        categorized.put(key, value);
-
-        return value;
-    }
-
-    @Override
-    public void emitMove(AllocatableValue dst, Value src) {
-        if (src instanceof ConstantValue) {
-            emitMoveConstant(dst, ((ConstantValue) src).getConstant());
-        } else {
-            append(createMove(dst, src));
-        }
-    }
-
-    @Override
-    public void emitMoveConstant(AllocatableValue dst, Constant src) {
-        append(createMoveConstant(dst, src));
-    }
-
     public void emitData(AllocatableValue dst, byte[] data) {
         append(new LeaDataOp(dst, data));
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64MoveFactory.java	Mon Nov 02 15:55:00 2015 +0100
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 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.compiler.amd64;
+
+import static com.oracle.graal.lir.LIRValueUtil.asConstant;
+import static com.oracle.graal.lir.LIRValueUtil.isConstantValue;
+import static com.oracle.graal.lir.LIRValueUtil.isStackSlotValue;
+import static jdk.vm.ci.code.ValueUtil.isRegister;
+import jdk.vm.ci.amd64.AMD64Kind;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.Value;
+
+import com.oracle.graal.asm.NumUtil;
+import com.oracle.graal.lir.amd64.AMD64AddressValue;
+import com.oracle.graal.lir.amd64.AMD64LIRInstruction;
+import com.oracle.graal.lir.amd64.AMD64Move.AMD64StackMove;
+import com.oracle.graal.lir.amd64.AMD64Move.LeaOp;
+import com.oracle.graal.lir.amd64.AMD64Move.MoveFromConstOp;
+import com.oracle.graal.lir.amd64.AMD64Move.MoveFromRegOp;
+import com.oracle.graal.lir.amd64.AMD64Move.MoveToRegOp;
+import com.oracle.graal.lir.framemap.FrameMapBuilder;
+
+public class AMD64MoveFactory extends AMD64MoveFactoryBase {
+
+    private final FrameMapBuilder frameMapBuilder;
+
+    public AMD64MoveFactory(BackupSlotProvider backupSlotProvider, FrameMapBuilder frameMapBuilder) {
+        super(backupSlotProvider);
+        this.frameMapBuilder = frameMapBuilder;
+    }
+
+    @Override
+    public boolean canInlineConstant(JavaConstant c) {
+        switch (c.getJavaKind()) {
+            case Long:
+                return NumUtil.isInt(c.asLong()) && !frameMapBuilder.getCodeCache().needsDataPatch(c);
+            case Object:
+                return c.isNull();
+            default:
+                return true;
+        }
+    }
+
+    @Override
+    public AMD64LIRInstruction createMove(AllocatableValue dst, Value src) {
+        if (src instanceof AMD64AddressValue) {
+            return new LeaOp(dst, (AMD64AddressValue) src);
+        } else if (isConstantValue(src)) {
+            return createLoad(dst, asConstant(src));
+        } else if (isRegister(src) || isStackSlotValue(dst)) {
+            return new MoveFromRegOp((AMD64Kind) dst.getPlatformKind(), dst, (AllocatableValue) src);
+        } else {
+            return new MoveToRegOp((AMD64Kind) dst.getPlatformKind(), dst, (AllocatableValue) src);
+        }
+    }
+
+    @Override
+    public AMD64LIRInstruction createStackMove(AllocatableValue result, AllocatableValue input, Register scratchRegister, AllocatableValue backupSlot) {
+        return new AMD64StackMove(result, input, scratchRegister, backupSlot);
+    }
+
+    @Override
+    public AMD64LIRInstruction createLoad(AllocatableValue dst, Constant src) {
+        return new MoveFromConstOp(dst, (JavaConstant) src);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64MoveFactoryBase.java	Mon Nov 02 15:55:00 2015 +0100
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 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.compiler.amd64;
+
+import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.QWORD;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.WORD;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import jdk.vm.ci.amd64.AMD64Kind;
+import jdk.vm.ci.code.Architecture;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.code.RegisterConfig;
+import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.LIRKind;
+import jdk.vm.ci.meta.PlatformKind;
+
+import com.oracle.graal.lir.VirtualStackSlot;
+import com.oracle.graal.lir.amd64.AMD64LIRInstruction;
+import com.oracle.graal.lir.amd64.AMD64Move.AMD64PushPopStackMove;
+import com.oracle.graal.lir.framemap.FrameMapBuilder;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
+
+public abstract class AMD64MoveFactoryBase implements MoveFactory {
+
+    private final BackupSlotProvider backupSlotProvider;
+
+    private static class RegisterBackupPair {
+        public final Register register;
+        public final VirtualStackSlot backupSlot;
+
+        RegisterBackupPair(Register register, VirtualStackSlot backupSlot) {
+            this.register = register;
+            this.backupSlot = backupSlot;
+        }
+    }
+
+    public static final class BackupSlotProvider {
+
+        private final FrameMapBuilder frameMapBuilder;
+        private Map<PlatformKind.Key, RegisterBackupPair> categorized;
+
+        public BackupSlotProvider(FrameMapBuilder frameMapBuilder) {
+            this.frameMapBuilder = frameMapBuilder;
+        }
+
+        protected RegisterBackupPair getScratchRegister(PlatformKind kind) {
+            PlatformKind.Key key = kind.getKey();
+            if (categorized == null) {
+                categorized = new HashMap<>();
+            } else if (categorized.containsKey(key)) {
+                return categorized.get(key);
+            }
+
+            RegisterConfig registerConfig = frameMapBuilder.getRegisterConfig();
+
+            Register[] availableRegister = registerConfig.filterAllocatableRegisters(kind, registerConfig.getAllocatableRegisters());
+            assert availableRegister != null && availableRegister.length > 1;
+            Register scratchRegister = availableRegister[0];
+
+            Architecture arch = frameMapBuilder.getCodeCache().getTarget().arch;
+            LIRKind largestKind = LIRKind.value(arch.getLargestStorableKind(scratchRegister.getRegisterCategory()));
+            VirtualStackSlot backupSlot = frameMapBuilder.allocateSpillSlot(largestKind);
+
+            RegisterBackupPair value = new RegisterBackupPair(scratchRegister, backupSlot);
+            categorized.put(key, value);
+
+            return value;
+        }
+    }
+
+    public AMD64MoveFactoryBase(BackupSlotProvider backupSlotProvider) {
+        this.backupSlotProvider = backupSlotProvider;
+    }
+
+    @Override
+    public final AMD64LIRInstruction createStackMove(AllocatableValue result, AllocatableValue input) {
+        AMD64Kind kind = (AMD64Kind) result.getPlatformKind();
+        switch (kind.getSizeInBytes()) {
+            case 2:
+                return new AMD64PushPopStackMove(WORD, result, input);
+            case 8:
+                return new AMD64PushPopStackMove(QWORD, result, input);
+            default:
+                RegisterBackupPair backup = backupSlotProvider.getScratchRegister(input.getPlatformKind());
+                Register scratchRegister = backup.register;
+                VirtualStackSlot backupSlot = backup.backupSlot;
+                return createStackMove(result, input, scratchRegister, backupSlot);
+        }
+    }
+
+    public abstract AMD64LIRInstruction createStackMove(AllocatableValue result, AllocatableValue input, Register scratchRegister, AllocatableValue backupSlot);
+}
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCArithmeticLIRGenerator.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCArithmeticLIRGenerator.java	Mon Nov 02 15:55:00 2015 +0100
@@ -203,7 +203,7 @@
 
     private Variable emitBinary(LIRKind resultKind, Opfs opf, Value a, Value b, LIRFrameState state) {
         Variable result = getLIRGen().newVariable(resultKind);
-        if (opf.isCommutative() && isJavaConstant(a) && getLIRGen().canInlineConstant(asJavaConstant(a))) {
+        if (opf.isCommutative() && isJavaConstant(a) && getLIRGen().getMoveFactory().canInlineConstant(asJavaConstant(a))) {
             getLIRGen().append(new SPARCOPFOp(opf, b, a, result, state));
         } else {
             getLIRGen().append(new SPARCOPFOp(opf, a, b, result, state));
@@ -221,7 +221,7 @@
 
     private Variable emitBinary(LIRKind resultKind, Op3s op3, Value a, Value b, LIRFrameState state) {
         Variable result = getLIRGen().newVariable(resultKind);
-        if (op3.isCommutative() && isJavaConstant(a) && getLIRGen().canInlineConstant(asJavaConstant(a))) {
+        if (op3.isCommutative() && isJavaConstant(a) && getLIRGen().getMoveFactory().canInlineConstant(asJavaConstant(a))) {
             getLIRGen().append(new SPARCOP3Op(op3, getLIRGen().load(b), a, result, state));
         } else {
             getLIRGen().append(new SPARCOP3Op(op3, getLIRGen().load(a), b, result, state));
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Mon Nov 02 15:55:00 2015 +0100
@@ -32,7 +32,6 @@
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fcmps;
 import static com.oracle.graal.lir.LIRValueUtil.asJavaConstant;
 import static com.oracle.graal.lir.LIRValueUtil.isJavaConstant;
-import static com.oracle.graal.lir.LIRValueUtil.isStackSlotValue;
 import static jdk.vm.ci.sparc.SPARCKind.SINGLE;
 import static jdk.vm.ci.sparc.SPARCKind.XWORD;
 import jdk.vm.ci.code.CallingConvention;
@@ -59,7 +58,6 @@
 import com.oracle.graal.lir.ConstantValue;
 import com.oracle.graal.lir.LIR;
 import com.oracle.graal.lir.LIRFrameState;
-import com.oracle.graal.lir.LIRInstruction;
 import com.oracle.graal.lir.LIRValueUtil;
 import com.oracle.graal.lir.LabelRef;
 import com.oracle.graal.lir.StandardOp.NoOp;
@@ -68,7 +66,6 @@
 import com.oracle.graal.lir.VirtualStackSlot;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
 import com.oracle.graal.lir.gen.LIRGenerator;
-import com.oracle.graal.lir.gen.SpillMoveFactoryBase;
 import com.oracle.graal.lir.sparc.SPARCAddressValue;
 import com.oracle.graal.lir.sparc.SPARCArrayEqualsOp;
 import com.oracle.graal.lir.sparc.SPARCByteSwapOp;
@@ -83,12 +80,9 @@
 import com.oracle.graal.lir.sparc.SPARCImmediateAddressValue;
 import com.oracle.graal.lir.sparc.SPARCJumpOp;
 import com.oracle.graal.lir.sparc.SPARCLoadConstantTableBaseOp;
-import com.oracle.graal.lir.sparc.SPARCMove;
-import com.oracle.graal.lir.sparc.SPARCMove.LoadAddressOp;
 import com.oracle.graal.lir.sparc.SPARCMove.LoadDataAddressOp;
 import com.oracle.graal.lir.sparc.SPARCMove.LoadOp;
 import com.oracle.graal.lir.sparc.SPARCMove.MembarOp;
-import com.oracle.graal.lir.sparc.SPARCMove.Move;
 import com.oracle.graal.lir.sparc.SPARCMove.NullCheckOp;
 import com.oracle.graal.lir.sparc.SPARCMove.StackLoadAddressOp;
 import com.oracle.graal.lir.sparc.SPARCOP3Op;
@@ -99,55 +93,23 @@
  */
 public abstract class SPARCLIRGenerator extends LIRGenerator {
 
-    private SPARCSpillMoveFactory moveFactory;
-    private Variable constantTableBase;
     private SPARCLoadConstantTableBaseOp loadConstantTableBaseOp;
-
-    private class SPARCSpillMoveFactory extends SpillMoveFactoryBase {
+    private final ConstantTableBaseProvider constantTableBaseProvider;
 
-        @Override
-        protected LIRInstruction createMoveIntern(AllocatableValue result, Value input) {
-            return SPARCLIRGenerator.this.createMove(result, input);
-        }
+    public static final class ConstantTableBaseProvider {
+        private Variable constantTableBase;
+        private boolean useConstantTableBase = false;
 
-        @Override
-        protected LIRInstruction createStackMoveIntern(AllocatableValue result, AllocatableValue input) {
-            return SPARCLIRGenerator.this.createStackMove(result, input);
-        }
-
-        @Override
-        protected LIRInstruction createLoadIntern(AllocatableValue result, Constant input) {
-            return SPARCLIRGenerator.this.createMoveConstant(result, input);
+        public Variable getConstantTableBase() {
+            useConstantTableBase = true;
+            return constantTableBase;
         }
     }
 
-    public SPARCLIRGenerator(LIRKindTool lirKindTool, SPARCArithmeticLIRGenerator arithmeticLIRGen, Providers providers, CallingConvention cc, LIRGenerationResult lirGenRes) {
-        super(lirKindTool, arithmeticLIRGen, providers, cc, lirGenRes);
-    }
-
-    public SpillMoveFactory getSpillMoveFactory() {
-        if (moveFactory == null) {
-            moveFactory = new SPARCSpillMoveFactory();
-        }
-        return moveFactory;
-    }
-
-    @Override
-    public boolean canInlineConstant(JavaConstant c) {
-        switch (c.getJavaKind()) {
-            case Boolean:
-            case Byte:
-            case Char:
-            case Short:
-            case Int:
-                return SPARCAssembler.isSimm13(c.asInt()) && !getCodeCache().needsDataPatch(c);
-            case Long:
-                return SPARCAssembler.isSimm13(c.asLong()) && !getCodeCache().needsDataPatch(c);
-            case Object:
-                return c.isNull();
-            default:
-                return false;
-        }
+    public SPARCLIRGenerator(LIRKindTool lirKindTool, SPARCArithmeticLIRGenerator arithmeticLIRGen, MoveFactory moveFactory, Providers providers, CallingConvention cc, LIRGenerationResult lirGenRes,
+                    ConstantTableBaseProvider constantTableBaseProvider) {
+        super(lirKindTool, arithmeticLIRGen, moveFactory, providers, cc, lirGenRes);
+        this.constantTableBaseProvider = constantTableBaseProvider;
     }
 
     @Override
@@ -176,36 +138,6 @@
         }
     }
 
-    protected LIRInstruction createMove(AllocatableValue dst, Value src) {
-        boolean srcIsSlot = isStackSlotValue(src);
-        boolean dstIsSlot = isStackSlotValue(dst);
-        if (src instanceof ConstantValue) {
-            return createMoveConstant(dst, ((ConstantValue) src).getConstant());
-        } else if (src instanceof SPARCAddressValue) {
-            return new LoadAddressOp(dst, (SPARCAddressValue) src);
-        } else {
-            assert src instanceof AllocatableValue;
-            if (srcIsSlot && dstIsSlot) {
-                throw JVMCIError.shouldNotReachHere(src.getClass() + " " + dst.getClass());
-            } else {
-                return new Move(dst, (AllocatableValue) src);
-            }
-        }
-    }
-
-    protected LIRInstruction createMoveConstant(AllocatableValue dst, Constant src) {
-        if (src instanceof JavaConstant) {
-            JavaConstant javaConstant = (JavaConstant) src;
-            if (canInlineConstant(javaConstant)) {
-                return new SPARCMove.LoadInlineConstant(javaConstant, dst);
-            } else {
-                return new SPARCMove.LoadConstantFromTable(javaConstant, getConstantTableBase(), dst);
-            }
-        } else {
-            throw JVMCIError.shouldNotReachHere(src.getClass().toString());
-        }
-    }
-
     /**
      * The SPARC backend only uses WORD and DWORD values in registers because except to the ld/st
      * instructions no instruction deals either with 32 or 64 bits. This function converts small
@@ -222,20 +154,6 @@
         }
     }
 
-    protected LIRInstruction createStackMove(AllocatableValue result, AllocatableValue input) {
-        return new SPARCMove.Move(result, input);
-    }
-
-    @Override
-    public void emitMove(AllocatableValue dst, Value src) {
-        append(createMove(dst, src));
-    }
-
-    @Override
-    public void emitMoveConstant(AllocatableValue dst, Constant src) {
-        append(createMoveConstant(dst, src));
-    }
-
     @Override
     public void emitData(AllocatableValue dst, byte[] data) {
         append(new LoadDataAddressOp(dst, data));
@@ -480,8 +398,8 @@
         AllocatableValue scratchValue = newVariable(key.getLIRKind());
         AllocatableValue base = AllocatableValue.ILLEGAL;
         for (Constant c : strategy.getKeyConstants()) {
-            if (!(c instanceof JavaConstant) || !canInlineConstant((JavaConstant) c)) {
-                base = getConstantTableBase();
+            if (!(c instanceof JavaConstant) || !getMoveFactory().canInlineConstant((JavaConstant) c)) {
+                base = constantTableBaseProvider.getConstantTableBase();
                 break;
             }
         }
@@ -550,22 +468,15 @@
     }
 
     public void emitLoadConstantTableBase() {
-        constantTableBase = newVariable(LIRKind.value(XWORD));
+        constantTableBaseProvider.constantTableBase = newVariable(LIRKind.value(XWORD));
         int nextPosition = getResult().getLIR().getLIRforBlock(getCurrentBlock()).size();
         NoOp placeHolder = append(new NoOp(getCurrentBlock(), nextPosition));
-        loadConstantTableBaseOp = new SPARCLoadConstantTableBaseOp(constantTableBase, placeHolder);
-    }
-
-    boolean useConstantTableBase = false;
-
-    protected Variable getConstantTableBase() {
-        useConstantTableBase = true;
-        return constantTableBase;
+        loadConstantTableBaseOp = new SPARCLoadConstantTableBaseOp(constantTableBaseProvider.constantTableBase, placeHolder);
     }
 
     @Override
     public void beforeRegisterAllocation() {
         LIR lir = getResult().getLIR();
-        loadConstantTableBaseOp.setAlive(lir, useConstantTableBase);
+        loadConstantTableBaseOp.setAlive(lir, constantTableBaseProvider.useConstantTableBase);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCMoveFactory.java	Mon Nov 02 15:55:00 2015 +0100
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 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.compiler.sparc;
+
+import static com.oracle.graal.lir.LIRValueUtil.asConstant;
+import static com.oracle.graal.lir.LIRValueUtil.isConstantValue;
+import static com.oracle.graal.lir.LIRValueUtil.isStackSlotValue;
+import jdk.vm.ci.code.CodeCacheProvider;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.Value;
+
+import com.oracle.graal.asm.sparc.SPARCAssembler;
+import com.oracle.graal.compiler.sparc.SPARCLIRGenerator.ConstantTableBaseProvider;
+import com.oracle.graal.lir.LIRInstruction;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
+import com.oracle.graal.lir.sparc.SPARCAddressValue;
+import com.oracle.graal.lir.sparc.SPARCMove;
+import com.oracle.graal.lir.sparc.SPARCMove.LoadAddressOp;
+import com.oracle.graal.lir.sparc.SPARCMove.Move;
+
+public class SPARCMoveFactory implements MoveFactory {
+
+    private final CodeCacheProvider codeCache;
+    protected final ConstantTableBaseProvider constantTableBaseProvider;
+
+    public SPARCMoveFactory(CodeCacheProvider codeCache, ConstantTableBaseProvider constantTableBaseProvider) {
+        this.codeCache = codeCache;
+        this.constantTableBaseProvider = constantTableBaseProvider;
+    }
+
+    @Override
+    public LIRInstruction createMove(AllocatableValue dst, Value src) {
+        boolean srcIsSlot = isStackSlotValue(src);
+        boolean dstIsSlot = isStackSlotValue(dst);
+        if (isConstantValue(src)) {
+            return createLoad(dst, asConstant(src));
+        } else if (src instanceof SPARCAddressValue) {
+            return new LoadAddressOp(dst, (SPARCAddressValue) src);
+        } else {
+            assert src instanceof AllocatableValue;
+            if (srcIsSlot && dstIsSlot) {
+                throw JVMCIError.shouldNotReachHere(src.getClass() + " " + dst.getClass());
+            } else {
+                return new Move(dst, (AllocatableValue) src);
+            }
+        }
+    }
+
+    @Override
+    public LIRInstruction createStackMove(AllocatableValue result, AllocatableValue input) {
+        return new SPARCMove.Move(result, input);
+    }
+
+    @Override
+    public LIRInstruction createLoad(AllocatableValue dst, Constant src) {
+        if (src instanceof JavaConstant) {
+            JavaConstant javaConstant = (JavaConstant) src;
+            if (canInlineConstant(javaConstant)) {
+                return new SPARCMove.LoadInlineConstant(javaConstant, dst);
+            } else {
+                return new SPARCMove.LoadConstantFromTable(javaConstant, constantTableBaseProvider.getConstantTableBase(), dst);
+            }
+        } else {
+            throw JVMCIError.shouldNotReachHere(src.getClass().toString());
+        }
+    }
+
+    @Override
+    public boolean canInlineConstant(JavaConstant c) {
+        switch (c.getJavaKind()) {
+            case Boolean:
+            case Byte:
+            case Char:
+            case Short:
+            case Int:
+                return SPARCAssembler.isSimm13(c.asInt()) && !codeCache.needsDataPatch(c);
+            case Long:
+                return SPARCAssembler.isSimm13(c.asLong()) && !codeCache.needsDataPatch(c);
+            case Object:
+                return c.isNull();
+            default:
+                return false;
+        }
+    }
+}
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Mon Nov 02 15:55:00 2015 +0100
@@ -50,7 +50,6 @@
 import com.oracle.graal.asm.amd64.AMD64Address;
 import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag;
 import com.oracle.graal.asm.amd64.AMD64MacroAssembler;
-import com.oracle.graal.compiler.amd64.AMD64ArithmeticLIRGenerator;
 import com.oracle.graal.compiler.amd64.AMD64NodeMatchRules;
 import com.oracle.graal.compiler.common.alloc.RegisterAllocationConfig;
 import com.oracle.graal.compiler.gen.BytecodeLIRBuilder;
@@ -97,7 +96,7 @@
 
     @Override
     public LIRGeneratorTool newLIRGenerator(CallingConvention cc, LIRGenerationResult lirGenRes) {
-        return new AMD64HotSpotLIRGenerator(new AMD64ArithmeticLIRGenerator(), getProviders(), config(), cc, lirGenRes);
+        return new AMD64HotSpotLIRGenerator(getProviders(), config(), cc, lirGenRes);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Mon Nov 02 15:55:00 2015 +0100
@@ -46,7 +46,6 @@
 import jdk.vm.ci.common.JVMCIError;
 import jdk.vm.ci.hotspot.HotSpotCompressedNullConstant;
 import jdk.vm.ci.hotspot.HotSpotConstant;
-import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
 import jdk.vm.ci.hotspot.HotSpotObjectConstant;
 import jdk.vm.ci.hotspot.HotSpotVMConfig;
 import jdk.vm.ci.hotspot.HotSpotVMConfig.CompressEncoding;
@@ -66,6 +65,7 @@
 import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize;
 import com.oracle.graal.compiler.amd64.AMD64ArithmeticLIRGenerator;
 import com.oracle.graal.compiler.amd64.AMD64LIRGenerator;
+import com.oracle.graal.compiler.amd64.AMD64MoveFactoryBase.BackupSlotProvider;
 import com.oracle.graal.compiler.common.GraalOptions;
 import com.oracle.graal.compiler.common.spi.ForeignCallLinkage;
 import com.oracle.graal.compiler.common.spi.LIRKindTool;
@@ -93,7 +93,6 @@
 import com.oracle.graal.lir.amd64.AMD64CCall;
 import com.oracle.graal.lir.amd64.AMD64ControlFlow.StrategySwitchOp;
 import com.oracle.graal.lir.amd64.AMD64FrameMapBuilder;
-import com.oracle.graal.lir.amd64.AMD64LIRInstruction;
 import com.oracle.graal.lir.amd64.AMD64Move;
 import com.oracle.graal.lir.amd64.AMD64Move.MoveFromRegOp;
 import com.oracle.graal.lir.amd64.AMD64RestoreRegistersOp;
@@ -111,13 +110,17 @@
     final HotSpotVMConfig config;
     private HotSpotLockStack lockStack;
 
-    protected AMD64HotSpotLIRGenerator(AMD64ArithmeticLIRGenerator arithmeticLIRGen, HotSpotProviders providers, HotSpotVMConfig config, CallingConvention cc, LIRGenerationResult lirGenRes) {
-        this(new AMD64HotSpotLIRKindTool(), arithmeticLIRGen, providers, config, cc, lirGenRes);
+    protected AMD64HotSpotLIRGenerator(HotSpotProviders providers, HotSpotVMConfig config, CallingConvention cc, LIRGenerationResult lirGenRes) {
+        this(providers, config, cc, lirGenRes, new BackupSlotProvider(lirGenRes.getFrameMapBuilder()));
     }
 
-    protected AMD64HotSpotLIRGenerator(LIRKindTool lirKindTool, AMD64ArithmeticLIRGenerator arithmeticLIRGen, HotSpotProviders providers, HotSpotVMConfig config, CallingConvention cc,
-                    LIRGenerationResult lirGenRes) {
-        super(lirKindTool, arithmeticLIRGen, providers, cc, lirGenRes);
+    private AMD64HotSpotLIRGenerator(HotSpotProviders providers, HotSpotVMConfig config, CallingConvention cc, LIRGenerationResult lirGenRes, BackupSlotProvider backupSlotProvider) {
+        this(new AMD64HotSpotLIRKindTool(), new AMD64ArithmeticLIRGenerator(), new AMD64HotSpotMoveFactory(backupSlotProvider, lirGenRes.getFrameMapBuilder()), providers, config, cc, lirGenRes);
+    }
+
+    protected AMD64HotSpotLIRGenerator(LIRKindTool lirKindTool, AMD64ArithmeticLIRGenerator arithmeticLIRGen, MoveFactory moveFactory, HotSpotProviders providers, HotSpotVMConfig config,
+                    CallingConvention cc, LIRGenerationResult lirGenRes) {
+        super(lirKindTool, arithmeticLIRGen, moveFactory, providers, cc, lirGenRes);
         assert config.basicLockSize == 8;
         this.config = config;
     }
@@ -624,19 +627,6 @@
     }
 
     @Override
-    protected AMD64LIRInstruction createMoveConstant(AllocatableValue dst, Constant src) {
-        if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(src)) {
-            return super.createMoveConstant(dst, JavaConstant.INT_0);
-        } else if (src instanceof HotSpotObjectConstant) {
-            return new AMD64HotSpotMove.HotSpotLoadObjectConstantOp(dst, (HotSpotObjectConstant) src);
-        } else if (src instanceof HotSpotMetaspaceConstant) {
-            return new AMD64HotSpotMove.HotSpotLoadMetaspaceConstantOp(dst, (HotSpotMetaspaceConstant) src);
-        } else {
-            return super.createMoveConstant(dst, src);
-        }
-    }
-
-    @Override
     public void emitNullCheck(Value address, LIRFrameState state) {
         if (address.getLIRKind().getPlatformKind() == AMD64Kind.DWORD) {
             CompressEncoding encoding = config.getOopEncoding();
@@ -694,17 +684,6 @@
     }
 
     @Override
-    public boolean canInlineConstant(JavaConstant c) {
-        if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(c)) {
-            return true;
-        } else if (c instanceof HotSpotObjectConstant) {
-            return ((HotSpotObjectConstant) c).isCompressed();
-        } else {
-            return super.canInlineConstant(c);
-        }
-    }
-
-    @Override
     public LIRInstruction createBenchmarkCounter(String name, String group, Value increment) {
         if (BenchmarkCounters.enabled) {
             return new AMD64HotSpotCounterOp(name, group, increment, getProviders().getRegisters(), config, getOrInitRescueSlot());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMoveFactory.java	Mon Nov 02 15:55:00 2015 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 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.hotspot.amd64;
+
+import jdk.vm.ci.hotspot.HotSpotCompressedNullConstant;
+import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
+import jdk.vm.ci.hotspot.HotSpotObjectConstant;
+import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.JavaConstant;
+
+import com.oracle.graal.compiler.amd64.AMD64MoveFactory;
+import com.oracle.graal.lir.amd64.AMD64LIRInstruction;
+import com.oracle.graal.lir.framemap.FrameMapBuilder;
+
+public class AMD64HotSpotMoveFactory extends AMD64MoveFactory {
+
+    public AMD64HotSpotMoveFactory(BackupSlotProvider backupSlotProvider, FrameMapBuilder frameMapBuilder) {
+        super(backupSlotProvider, frameMapBuilder);
+    }
+
+    @Override
+    public boolean canInlineConstant(JavaConstant c) {
+        if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(c)) {
+            return true;
+        } else if (c instanceof HotSpotObjectConstant) {
+            return ((HotSpotObjectConstant) c).isCompressed();
+        } else {
+            return super.canInlineConstant(c);
+        }
+    }
+
+    @Override
+    public AMD64LIRInstruction createLoad(AllocatableValue dst, Constant src) {
+        if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(src)) {
+            return super.createLoad(dst, JavaConstant.INT_0);
+        } else if (src instanceof HotSpotObjectConstant) {
+            return new AMD64HotSpotMove.HotSpotLoadObjectConstantOp(dst, (HotSpotObjectConstant) src);
+        } else if (src instanceof HotSpotMetaspaceConstant) {
+            return new AMD64HotSpotMove.HotSpotLoadMetaspaceConstantOp(dst, (HotSpotMetaspaceConstant) src);
+        } else {
+            return super.createLoad(dst, src);
+        }
+    }
+}
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Mon Nov 02 15:55:00 2015 +0100
@@ -63,7 +63,6 @@
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.ScratchRegister;
 import com.oracle.graal.compiler.common.alloc.RegisterAllocationConfig;
 import com.oracle.graal.compiler.common.cfg.AbstractBlockBase;
-import com.oracle.graal.compiler.sparc.SPARCArithmeticLIRGenerator;
 import com.oracle.graal.compiler.sparc.SPARCNodeMatchRules;
 import com.oracle.graal.debug.Debug;
 import com.oracle.graal.debug.DebugMetric;
@@ -135,7 +134,7 @@
 
     @Override
     public LIRGeneratorTool newLIRGenerator(CallingConvention cc, LIRGenerationResult lirGenRes) {
-        return new SPARCHotSpotLIRGenerator(new SPARCArithmeticLIRGenerator(), getProviders(), config(), cc, lirGenRes);
+        return new SPARCHotSpotLIRGenerator(getProviders(), config(), cc, lirGenRes);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Mon Nov 02 15:55:00 2015 +0100
@@ -28,9 +28,6 @@
 import static com.oracle.graal.lir.LIRValueUtil.asJavaConstant;
 import static com.oracle.graal.lir.LIRValueUtil.isConstantValue;
 import static com.oracle.graal.lir.LIRValueUtil.isJavaConstant;
-import static jdk.vm.ci.hotspot.HotSpotCompressedNullConstant.COMPRESSED_NULL;
-import static jdk.vm.ci.meta.JavaConstant.INT_0;
-import static jdk.vm.ci.meta.JavaConstant.LONG_0;
 import static jdk.vm.ci.sparc.SPARC.d32;
 import static jdk.vm.ci.sparc.SPARC.d34;
 import static jdk.vm.ci.sparc.SPARC.d36;
@@ -78,7 +75,6 @@
 import jdk.vm.ci.code.StackSlot;
 import jdk.vm.ci.common.JVMCIError;
 import jdk.vm.ci.hotspot.HotSpotCompressedNullConstant;
-import jdk.vm.ci.hotspot.HotSpotConstant;
 import jdk.vm.ci.hotspot.HotSpotObjectConstant;
 import jdk.vm.ci.hotspot.HotSpotVMConfig;
 import jdk.vm.ci.hotspot.HotSpotVMConfig.CompressEncoding;
@@ -132,13 +128,18 @@
     private HotSpotLockStack lockStack;
     private LIRFrameState currentRuntimeCallInfo;
 
-    public SPARCHotSpotLIRGenerator(SPARCArithmeticLIRGenerator arithmeticLIRGen, HotSpotProviders providers, HotSpotVMConfig config, CallingConvention cc, LIRGenerationResult lirGenRes) {
-        this(new SPARCHotSpotLIRKindTool(), arithmeticLIRGen, providers, config, cc, lirGenRes);
+    public SPARCHotSpotLIRGenerator(HotSpotProviders providers, HotSpotVMConfig config, CallingConvention cc, LIRGenerationResult lirGenRes) {
+        this(providers, config, cc, lirGenRes, new ConstantTableBaseProvider());
     }
 
-    protected SPARCHotSpotLIRGenerator(LIRKindTool lirKindTool, SPARCArithmeticLIRGenerator arithmeticLIRGen, HotSpotProviders providers, HotSpotVMConfig config, CallingConvention cc,
-                    LIRGenerationResult lirGenRes) {
-        super(lirKindTool, arithmeticLIRGen, providers, cc, lirGenRes);
+    private SPARCHotSpotLIRGenerator(HotSpotProviders providers, HotSpotVMConfig config, CallingConvention cc, LIRGenerationResult lirGenRes, ConstantTableBaseProvider constantTableBaseProvider) {
+        this(new SPARCHotSpotLIRKindTool(), new SPARCArithmeticLIRGenerator(), new SPARCHotSpotMoveFactory(providers.getCodeCache(), constantTableBaseProvider), providers, config, cc, lirGenRes,
+                        constantTableBaseProvider);
+    }
+
+    protected SPARCHotSpotLIRGenerator(LIRKindTool lirKindTool, SPARCArithmeticLIRGenerator arithmeticLIRGen, MoveFactory moveFactory, HotSpotProviders providers, HotSpotVMConfig config,
+                    CallingConvention cc, LIRGenerationResult lirGenRes, ConstantTableBaseProvider constantTableBaseProvider) {
+        super(lirKindTool, arithmeticLIRGen, moveFactory, providers, cc, lirGenRes, constantTableBaseProvider);
         assert config.basicLockSize == 8;
         this.config = config;
     }
@@ -286,17 +287,6 @@
     }
 
     @Override
-    public boolean canInlineConstant(JavaConstant c) {
-        if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(c)) {
-            return true;
-        } else if (c instanceof HotSpotObjectConstant) {
-            return false;
-        } else {
-            return super.canInlineConstant(c);
-        }
-    }
-
-    @Override
     public void emitStore(LIRKind kind, Value address, Value inputVal, LIRFrameState state) {
         SPARCAddressValue storeAddress = asAddressValue(address);
         if (isJavaConstant(inputVal)) {
@@ -329,28 +319,6 @@
     }
 
     @Override
-    protected LIRInstruction createMoveConstant(AllocatableValue dst, Constant src) {
-        Constant usedSource;
-        if (COMPRESSED_NULL.equals(src)) {
-            usedSource = INT_0;
-        } else if (src instanceof HotSpotObjectConstant && ((HotSpotObjectConstant) src).isNull()) {
-            usedSource = LONG_0;
-        } else {
-            usedSource = src;
-        }
-        if (usedSource instanceof HotSpotConstant) {
-            HotSpotConstant constant = (HotSpotConstant) usedSource;
-            if (constant.isCompressed()) {
-                return new SPARCHotSpotMove.LoadHotSpotObjectConstantInline(constant, dst);
-            } else {
-                return new SPARCHotSpotMove.LoadHotSpotObjectConstantFromTable(constant, dst, getConstantTableBase());
-            }
-        } else {
-            return super.createMoveConstant(dst, usedSource);
-        }
-    }
-
-    @Override
     public void emitCompareBranch(PlatformKind cmpKind, Value x, Value y, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination,
                     double trueDestinationProbability) {
         Value localX = x;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotMoveFactory.java	Mon Nov 02 15:55:00 2015 +0100
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 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.hotspot.sparc;
+
+import static jdk.vm.ci.hotspot.HotSpotCompressedNullConstant.COMPRESSED_NULL;
+import static jdk.vm.ci.meta.JavaConstant.INT_0;
+import static jdk.vm.ci.meta.JavaConstant.LONG_0;
+import jdk.vm.ci.code.CodeCacheProvider;
+import jdk.vm.ci.hotspot.HotSpotCompressedNullConstant;
+import jdk.vm.ci.hotspot.HotSpotConstant;
+import jdk.vm.ci.hotspot.HotSpotObjectConstant;
+import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.JavaConstant;
+
+import com.oracle.graal.compiler.sparc.SPARCLIRGenerator.ConstantTableBaseProvider;
+import com.oracle.graal.compiler.sparc.SPARCMoveFactory;
+import com.oracle.graal.lir.LIRInstruction;
+
+public class SPARCHotSpotMoveFactory extends SPARCMoveFactory {
+
+    public SPARCHotSpotMoveFactory(CodeCacheProvider codeCache, ConstantTableBaseProvider constantTableBaseProvider) {
+        super(codeCache, constantTableBaseProvider);
+    }
+
+    @Override
+    public boolean canInlineConstant(JavaConstant c) {
+        if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(c)) {
+            return true;
+        } else if (c instanceof HotSpotObjectConstant) {
+            return false;
+        } else {
+            return super.canInlineConstant(c);
+        }
+    }
+
+    @Override
+    public LIRInstruction createLoad(AllocatableValue dst, Constant src) {
+        Constant usedSource;
+        if (COMPRESSED_NULL.equals(src)) {
+            usedSource = INT_0;
+        } else if (src instanceof HotSpotObjectConstant && ((HotSpotObjectConstant) src).isNull()) {
+            usedSource = LONG_0;
+        } else {
+            usedSource = src;
+        }
+        if (usedSource instanceof HotSpotConstant) {
+            HotSpotConstant constant = (HotSpotConstant) usedSource;
+            if (constant.isCompressed()) {
+                return new SPARCHotSpotMove.LoadHotSpotObjectConstantInline(constant, dst);
+            } else {
+                return new SPARCHotSpotMove.LoadHotSpotObjectConstantFromTable(constant, dst, constantTableBaseProvider.getConstantTableBase());
+            }
+        } else {
+            return super.createLoad(dst, usedSource);
+        }
+    }
+}
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScan.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScan.java	Mon Nov 02 15:55:00 2015 +0100
@@ -66,7 +66,7 @@
 import com.oracle.graal.lir.alloc.lsra.Interval.RegisterBinding;
 import com.oracle.graal.lir.framemap.FrameMapBuilder;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
 import com.oracle.graal.lir.phases.AllocationPhase.AllocationContext;
 
 /**
@@ -124,7 +124,7 @@
     private final RegisterAttributes[] registerAttributes;
     private final Register[] registers;
     private final RegisterAllocationConfig regAllocConfig;
-    private final SpillMoveFactory moveFactory;
+    private final MoveFactory moveFactory;
 
     private final BlockMap<BlockData> blockData;
 
@@ -172,8 +172,8 @@
     private final int firstVariableNumber;
     private final boolean neverSpillConstants;
 
-    protected LinearScan(TargetDescription target, LIRGenerationResult res, SpillMoveFactory spillMoveFactory, RegisterAllocationConfig regAllocConfig,
-                    List<? extends AbstractBlockBase<?>> sortedBlocks, boolean neverSpillConstants) {
+    protected LinearScan(TargetDescription target, LIRGenerationResult res, MoveFactory spillMoveFactory, RegisterAllocationConfig regAllocConfig, List<? extends AbstractBlockBase<?>> sortedBlocks,
+                    boolean neverSpillConstants) {
         this.ir = res.getLIR();
         this.moveFactory = spillMoveFactory;
         this.frameMapBuilder = res.getFrameMapBuilder();
@@ -200,7 +200,7 @@
         return result;
     }
 
-    public SpillMoveFactory getSpillMoveFactory() {
+    public MoveFactory getSpillMoveFactory() {
         return moveFactory;
     }
 
@@ -638,8 +638,8 @@
     }
 
     @SuppressWarnings("try")
-    protected <B extends AbstractBlockBase<B>> void allocate(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder,
-                    SpillMoveFactory spillMoveFactory, RegisterAllocationConfig registerAllocationConfig) {
+    protected <B extends AbstractBlockBase<B>> void allocate(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, MoveFactory spillMoveFactory,
+                    RegisterAllocationConfig registerAllocationConfig) {
 
         /*
          * This is the point to enable debug logging for the whole register allocation.
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanAssignLocationsPhase.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanAssignLocationsPhase.java	Mon Nov 02 15:55:00 2015 +0100
@@ -52,7 +52,7 @@
 import com.oracle.graal.lir.StandardOp.ValueMoveOp;
 import com.oracle.graal.lir.Variable;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
 import com.oracle.graal.lir.phases.AllocationPhase;
 
 /**
@@ -67,7 +67,7 @@
     }
 
     @Override
-    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, SpillMoveFactory spillMoveFactory,
+    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, MoveFactory spillMoveFactory,
                     RegisterAllocationConfig registerAllocationConfig) {
         assignLocations();
     }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanEliminateSpillMovePhase.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanEliminateSpillMovePhase.java	Mon Nov 02 15:55:00 2015 +0100
@@ -49,7 +49,7 @@
 import com.oracle.graal.lir.alloc.lsra.Interval.SpillState;
 import com.oracle.graal.lir.alloc.lsra.LinearScan.IntervalPredicate;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
 import com.oracle.graal.lir.phases.AllocationPhase;
 
 public class LinearScanEliminateSpillMovePhase extends AllocationPhase {
@@ -76,7 +76,7 @@
     }
 
     @Override
-    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, SpillMoveFactory spillMoveFactory,
+    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, MoveFactory spillMoveFactory,
                     RegisterAllocationConfig registerAllocationConfig) {
         eliminateSpillMoves();
     }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase.java	Mon Nov 02 15:55:00 2015 +0100
@@ -66,7 +66,7 @@
 import com.oracle.graal.lir.alloc.lsra.Interval.SpillState;
 import com.oracle.graal.lir.alloc.lsra.LinearScan.BlockData;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
 import com.oracle.graal.lir.phases.AllocationPhase;
 
 public class LinearScanLifetimeAnalysisPhase extends AllocationPhase {
@@ -81,7 +81,7 @@
     }
 
     @Override
-    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, SpillMoveFactory spillMoveFactory,
+    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, MoveFactory spillMoveFactory,
                     RegisterAllocationConfig registerAllocationConfig) {
         numberInstructions();
         allocator.printLir("Before register allocation", true);
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanOptimizeSpillPositionPhase.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanOptimizeSpillPositionPhase.java	Mon Nov 02 15:55:00 2015 +0100
@@ -42,7 +42,7 @@
 import com.oracle.graal.lir.LIRInstruction.OperandMode;
 import com.oracle.graal.lir.alloc.lsra.Interval.SpillState;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
 import com.oracle.graal.lir.phases.AllocationPhase;
 
 public final class LinearScanOptimizeSpillPositionPhase extends AllocationPhase {
@@ -57,7 +57,7 @@
     }
 
     @Override
-    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, SpillMoveFactory spillMoveFactory,
+    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, MoveFactory spillMoveFactory,
                     RegisterAllocationConfig registerAllocationConfig) {
         optimizeSpillPosition();
         allocator.printIntervals("After optimize spill position");
@@ -125,7 +125,7 @@
             /*
              * The spill block is the begin of the first split child (aka the value is on the
              * stack).
-             * 
+             *
              * The problem is that if spill block has more than one predecessor, the values at the
              * end of the predecessors might differ. Therefore, we would need a spill move in all
              * predecessors. To avoid this we spill in the dominator.
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanPhase.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanPhase.java	Mon Nov 02 15:55:00 2015 +0100
@@ -34,7 +34,7 @@
 import com.oracle.graal.lir.alloc.lsra.ssa.SSALinearScan;
 import com.oracle.graal.lir.alloc.lsra.ssi.SSILinearScan;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
 import com.oracle.graal.lir.phases.AllocationPhase;
 
 public final class LinearScanPhase extends AllocationPhase {
@@ -46,7 +46,7 @@
     }
 
     @Override
-    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, SpillMoveFactory spillMoveFactory,
+    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, MoveFactory spillMoveFactory,
                     RegisterAllocationConfig registerAllocationConfig) {
         final LinearScan allocator;
         switch (LinearScanVariant.getValue()) {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanRegisterAllocationPhase.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanRegisterAllocationPhase.java	Mon Nov 02 15:55:00 2015 +0100
@@ -31,7 +31,7 @@
 import com.oracle.graal.debug.Debug;
 import com.oracle.graal.debug.Indent;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
 import com.oracle.graal.lir.phases.AllocationPhase;
 
 public final class LinearScanRegisterAllocationPhase extends AllocationPhase {
@@ -43,7 +43,7 @@
     }
 
     @Override
-    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, SpillMoveFactory spillMoveFactory,
+    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, MoveFactory spillMoveFactory,
                     RegisterAllocationConfig registerAllocationConfig) {
         allocator.printIntervals("Before register allocation");
         allocateRegisters();
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanResolveDataFlowPhase.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanResolveDataFlowPhase.java	Mon Nov 02 15:55:00 2015 +0100
@@ -36,7 +36,7 @@
 import com.oracle.graal.lir.LIRInstruction;
 import com.oracle.graal.lir.StandardOp;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
 import com.oracle.graal.lir.phases.AllocationPhase;
 
 /**
@@ -53,7 +53,7 @@
     }
 
     @Override
-    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, SpillMoveFactory spillMoveFactory,
+    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, MoveFactory spillMoveFactory,
                     RegisterAllocationConfig registerAllocationConfig) {
         resolveDataFlow();
     }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/ssa/SSALinearScan.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/ssa/SSALinearScan.java	Mon Nov 02 15:55:00 2015 +0100
@@ -36,13 +36,13 @@
 import com.oracle.graal.lir.alloc.lsra.LinearScanResolveDataFlowPhase;
 import com.oracle.graal.lir.alloc.lsra.MoveResolver;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
 import com.oracle.graal.lir.ssa.SSAUtil;
 
 public final class SSALinearScan extends LinearScan {
 
-    public SSALinearScan(TargetDescription target, LIRGenerationResult res, SpillMoveFactory spillMoveFactory, RegisterAllocationConfig regAllocConfig,
-                    List<? extends AbstractBlockBase<?>> sortedBlocks, boolean neverSpillConstants) {
+    public SSALinearScan(TargetDescription target, LIRGenerationResult res, MoveFactory spillMoveFactory, RegisterAllocationConfig regAllocConfig, List<? extends AbstractBlockBase<?>> sortedBlocks,
+                    boolean neverSpillConstants) {
         super(target, res, spillMoveFactory, regAllocConfig, sortedBlocks, neverSpillConstants);
     }
 
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/ssi/SSILinearScan.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/ssi/SSILinearScan.java	Mon Nov 02 15:55:00 2015 +0100
@@ -35,19 +35,19 @@
 import com.oracle.graal.lir.alloc.lsra.MoveResolver;
 import com.oracle.graal.lir.alloc.lsra.ssa.SSAMoveResolver;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
 import com.oracle.graal.lir.ssi.SSIVerifier;
 
 public final class SSILinearScan extends LinearScan {
 
-    public SSILinearScan(TargetDescription target, LIRGenerationResult res, SpillMoveFactory spillMoveFactory, RegisterAllocationConfig regAllocConfig,
-                    List<? extends AbstractBlockBase<?>> sortedBlocks, boolean neverSpillConstants) {
+    public SSILinearScan(TargetDescription target, LIRGenerationResult res, MoveFactory spillMoveFactory, RegisterAllocationConfig regAllocConfig, List<? extends AbstractBlockBase<?>> sortedBlocks,
+                    boolean neverSpillConstants) {
         super(target, res, spillMoveFactory, regAllocConfig, sortedBlocks, neverSpillConstants);
     }
 
     @Override
-    protected <B extends AbstractBlockBase<B>> void allocate(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder,
-                    SpillMoveFactory spillMoveFactory, RegisterAllocationConfig registerAllocationConfig) {
+    protected <B extends AbstractBlockBase<B>> void allocate(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, MoveFactory spillMoveFactory,
+                    RegisterAllocationConfig registerAllocationConfig) {
         assert SSIVerifier.verify(lirGenRes.getLIR()) : "LIR not in SSI form.";
         super.allocate(target, lirGenRes, codeEmittingOrder, linearScanOrder, spillMoveFactory, registerAllocationConfig);
     }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceAllocationPhase.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceAllocationPhase.java	Mon Nov 02 15:55:00 2015 +0100
@@ -29,16 +29,16 @@
 import com.oracle.graal.compiler.common.alloc.RegisterAllocationConfig;
 import com.oracle.graal.compiler.common.cfg.AbstractBlockBase;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
 import com.oracle.graal.lir.phases.LIRPhase;
 
 public abstract class TraceAllocationPhase extends LIRPhase<TraceAllocationPhase.TraceAllocationContext> {
 
     public static final class TraceAllocationContext {
-        private final SpillMoveFactory spillMoveFactory;
+        private final MoveFactory spillMoveFactory;
         private final RegisterAllocationConfig registerAllocationConfig;
 
-        public TraceAllocationContext(SpillMoveFactory spillMoveFactory, RegisterAllocationConfig registerAllocationConfig) {
+        public TraceAllocationContext(MoveFactory spillMoveFactory, RegisterAllocationConfig registerAllocationConfig) {
             this.spillMoveFactory = spillMoveFactory;
             this.registerAllocationConfig = registerAllocationConfig;
         }
@@ -51,6 +51,6 @@
     }
 
     protected abstract <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder,
-                    SpillMoveFactory spillMoveFactory, RegisterAllocationConfig registerAllocationConfig);
+                    MoveFactory spillMoveFactory, RegisterAllocationConfig registerAllocationConfig);
 
 }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceGlobalMoveResolutionPhase.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceGlobalMoveResolutionPhase.java	Mon Nov 02 15:55:00 2015 +0100
@@ -41,7 +41,7 @@
 import com.oracle.graal.lir.LIR;
 import com.oracle.graal.lir.LIRInstruction;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
 import com.oracle.graal.lir.ssa.SSAUtil.PhiValueVisitor;
 import com.oracle.graal.lir.ssi.SSIUtil;
 
@@ -54,13 +54,13 @@
     }
 
     @Override
-    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, SpillMoveFactory spillMoveFactory,
+    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, MoveFactory spillMoveFactory,
                     RegisterAllocationConfig registerAllocationConfig) {
         resolveGlobalDataFlow(resultTraces, lirGenRes, spillMoveFactory, target.arch);
     }
 
     @SuppressWarnings("try")
-    private static <B extends AbstractBlockBase<B>> void resolveGlobalDataFlow(TraceBuilderResult<B> resultTraces, LIRGenerationResult lirGenRes, SpillMoveFactory spillMoveFactory, Architecture arch) {
+    private static <B extends AbstractBlockBase<B>> void resolveGlobalDataFlow(TraceBuilderResult<B> resultTraces, LIRGenerationResult lirGenRes, MoveFactory spillMoveFactory, Architecture arch) {
         LIR lir = lirGenRes.getLIR();
         /* Resolve trace global data-flow mismatch. */
         TraceGlobalMoveResolver moveResolver = new TraceGlobalMoveResolver(lirGenRes, spillMoveFactory, arch);
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceGlobalMoveResolver.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceGlobalMoveResolver.java	Mon Nov 02 15:55:00 2015 +0100
@@ -56,7 +56,7 @@
 import com.oracle.graal.lir.framemap.FrameMapBuilder;
 import com.oracle.graal.lir.framemap.FrameMapBuilderTool;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
 
 /**
  */
@@ -71,7 +71,7 @@
     private static final int STACK_SLOT_IN_CALLER_FRAME_IDX = -1;
     private int[] stackBlocked;
     private final int firstVirtualStackIndex;
-    private final SpillMoveFactory spillMoveFactory;
+    private final MoveFactory spillMoveFactory;
     private final FrameMapBuilder frameMapBuilder;
 
     private void setValueBlocked(Value location, int direction) {
@@ -122,7 +122,7 @@
         return mappingFrom.size() > 0;
     }
 
-    private SpillMoveFactory getSpillMoveFactory() {
+    private MoveFactory getSpillMoveFactory() {
         return spillMoveFactory;
     }
 
@@ -130,7 +130,7 @@
         return frameMapBuilder.getRegisterConfig().getAllocatableRegisters();
     }
 
-    public TraceGlobalMoveResolver(LIRGenerationResult res, SpillMoveFactory spillMoveFactory, Architecture arch) {
+    public TraceGlobalMoveResolver(LIRGenerationResult res, MoveFactory spillMoveFactory, Architecture arch) {
 
         this.mappingFrom = new ArrayList<>(8);
         this.mappingTo = new ArrayList<>(8);
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScan.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScan.java	Mon Nov 02 15:55:00 2015 +0100
@@ -63,7 +63,7 @@
 import com.oracle.graal.lir.alloc.trace.TraceLinearScanAllocationPhase.TraceLinearScanAllocationContext;
 import com.oracle.graal.lir.framemap.FrameMapBuilder;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
 
 /**
  * An implementation of the linear scan register allocator algorithm described in <a
@@ -120,7 +120,7 @@
     private final RegisterAttributes[] registerAttributes;
     private final Register[] registers;
     private final RegisterAllocationConfig regAllocConfig;
-    private final SpillMoveFactory moveFactory;
+    private final MoveFactory moveFactory;
 
     private final BlockMap<BlockData> blockData;
 
@@ -173,7 +173,7 @@
     protected final TraceBuilderResult<?> traceBuilderResult;
     private final boolean neverSpillConstants;
 
-    protected TraceLinearScan(TargetDescription target, LIRGenerationResult res, SpillMoveFactory spillMoveFactory, RegisterAllocationConfig regAllocConfig,
+    protected TraceLinearScan(TargetDescription target, LIRGenerationResult res, MoveFactory spillMoveFactory, RegisterAllocationConfig regAllocConfig,
                     List<? extends AbstractBlockBase<?>> sortedBlocks, TraceBuilderResult<?> traceBuilderResult, boolean neverSpillConstants) {
         this.ir = res.getLIR();
         this.moveFactory = spillMoveFactory;
@@ -202,7 +202,7 @@
         return result;
     }
 
-    public SpillMoveFactory getSpillMoveFactory() {
+    public MoveFactory getSpillMoveFactory() {
         return moveFactory;
     }
 
@@ -715,8 +715,8 @@
     }
 
     @SuppressWarnings("try")
-    protected <B extends AbstractBlockBase<B>> void allocate(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder,
-                    SpillMoveFactory spillMoveFactory, RegisterAllocationConfig registerAllocationConfig) {
+    protected <B extends AbstractBlockBase<B>> void allocate(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, MoveFactory spillMoveFactory,
+                    RegisterAllocationConfig registerAllocationConfig) {
 
         /*
          * This is the point to enable debug logging for the whole register allocation.
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanAllocationPhase.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanAllocationPhase.java	Mon Nov 02 15:55:00 2015 +0100
@@ -30,19 +30,18 @@
 import com.oracle.graal.compiler.common.alloc.TraceBuilder.TraceBuilderResult;
 import com.oracle.graal.compiler.common.cfg.AbstractBlockBase;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
 import com.oracle.graal.lir.phases.LIRPhase;
 
 public abstract class TraceLinearScanAllocationPhase extends LIRPhase<TraceLinearScanAllocationPhase.TraceLinearScanAllocationContext> {
 
     public static final class TraceLinearScanAllocationContext {
-        private final SpillMoveFactory spillMoveFactory;
+        private final MoveFactory spillMoveFactory;
         private final RegisterAllocationConfig registerAllocationConfig;
         private final TraceBuilderResult<?> traceBuilderResult;
         private final TraceLinearScan allocator;
 
-        public TraceLinearScanAllocationContext(SpillMoveFactory spillMoveFactory, RegisterAllocationConfig registerAllocationConfig, TraceBuilderResult<?> traceBuilderResult,
-                        TraceLinearScan allocator) {
+        public TraceLinearScanAllocationContext(MoveFactory spillMoveFactory, RegisterAllocationConfig registerAllocationConfig, TraceBuilderResult<?> traceBuilderResult, TraceLinearScan allocator) {
             this.spillMoveFactory = spillMoveFactory;
             this.registerAllocationConfig = registerAllocationConfig;
             this.traceBuilderResult = traceBuilderResult;
@@ -57,6 +56,6 @@
     }
 
     protected abstract <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder,
-                    SpillMoveFactory spillMoveFactory, RegisterAllocationConfig registerAllocationConfig, TraceBuilderResult<?> traceBuilderResult, TraceLinearScan allocator);
+                    MoveFactory spillMoveFactory, RegisterAllocationConfig registerAllocationConfig, TraceBuilderResult<?> traceBuilderResult, TraceLinearScan allocator);
 
 }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanAssignLocationsPhase.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanAssignLocationsPhase.java	Mon Nov 02 15:55:00 2015 +0100
@@ -58,7 +58,7 @@
 import com.oracle.graal.lir.StandardOp.ValueMoveOp;
 import com.oracle.graal.lir.Variable;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
 
 /**
  * Specialization of {@link com.oracle.graal.lir.alloc.lsra.LinearScanAssignLocationsPhase} that
@@ -68,7 +68,7 @@
 final class TraceLinearScanAssignLocationsPhase extends TraceLinearScanAllocationPhase {
 
     @Override
-    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, SpillMoveFactory spillMoveFactory,
+    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, MoveFactory spillMoveFactory,
                     RegisterAllocationConfig registerAllocationConfig, TraceBuilderResult<?> traceBuilderResult, TraceLinearScan allocator) {
         new Assigner(allocator, traceBuilderResult).assignLocations();
     }
@@ -149,7 +149,7 @@
                  * instruction is a branch, spill moves are inserted before this branch and so the
                  * wrong operand would be returned (spill moves at block boundaries are not
                  * considered in the live ranges of intervals).
-                 * 
+                 *
                  * Solution: use the first opId of the branch target block instead.
                  */
                 final LIRInstruction instr = allocator.getLIR().getLIRforBlock(block).get(allocator.getLIR().getLIRforBlock(block).size() - 1);
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanEliminateSpillMovePhase.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanEliminateSpillMovePhase.java	Mon Nov 02 15:55:00 2015 +0100
@@ -44,7 +44,7 @@
 import com.oracle.graal.lir.alloc.trace.TraceInterval.SpillState;
 import com.oracle.graal.lir.alloc.trace.TraceLinearScan.IntervalPredicate;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
 
 final class TraceLinearScanEliminateSpillMovePhase extends TraceLinearScanAllocationPhase {
 
@@ -57,7 +57,7 @@
     };
 
     @Override
-    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, SpillMoveFactory spillMoveFactory,
+    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, MoveFactory spillMoveFactory,
                     RegisterAllocationConfig registerAllocationConfig, TraceBuilderResult<?> traceBuilderResult, TraceLinearScan allocator) {
         eliminateSpillMoves(allocator);
     }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanLifetimeAnalysisPhase.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanLifetimeAnalysisPhase.java	Mon Nov 02 15:55:00 2015 +0100
@@ -66,13 +66,13 @@
 import com.oracle.graal.lir.alloc.trace.TraceInterval.RegisterPriority;
 import com.oracle.graal.lir.alloc.trace.TraceInterval.SpillState;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
 import com.oracle.graal.lir.ssi.SSIUtil;
 
 final class TraceLinearScanLifetimeAnalysisPhase extends TraceLinearScanAllocationPhase {
 
     @Override
-    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, SpillMoveFactory spillMoveFactory,
+    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, MoveFactory spillMoveFactory,
                     RegisterAllocationConfig registerAllocationConfig, TraceBuilderResult<?> traceBuilderResult, TraceLinearScan allocator) {
         new Analyser(allocator, traceBuilderResult).analyze();
     }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanRegisterAllocationPhase.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanRegisterAllocationPhase.java	Mon Nov 02 15:55:00 2015 +0100
@@ -32,12 +32,12 @@
 import com.oracle.graal.debug.Debug;
 import com.oracle.graal.debug.Indent;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
 
 final class TraceLinearScanRegisterAllocationPhase extends TraceLinearScanAllocationPhase {
 
     @Override
-    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, SpillMoveFactory spillMoveFactory,
+    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, MoveFactory spillMoveFactory,
                     RegisterAllocationConfig registerAllocationConfig, TraceBuilderResult<?> traceBuilderResult, TraceLinearScan allocator) {
         allocator.printIntervals("Before register allocation");
         allocateRegisters(allocator);
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanResolveDataFlowPhase.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanResolveDataFlowPhase.java	Mon Nov 02 15:55:00 2015 +0100
@@ -45,7 +45,7 @@
 import com.oracle.graal.lir.LIRInstruction;
 import com.oracle.graal.lir.StandardOp;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
 import com.oracle.graal.lir.ssa.SSAUtil.PhiValueVisitor;
 import com.oracle.graal.lir.ssi.SSIUtil;
 
@@ -57,7 +57,7 @@
 final class TraceLinearScanResolveDataFlowPhase extends TraceLinearScanAllocationPhase {
 
     @Override
-    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, SpillMoveFactory spillMoveFactory,
+    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, MoveFactory spillMoveFactory,
                     RegisterAllocationConfig registerAllocationConfig, TraceBuilderResult<?> traceBuilderResult, TraceLinearScan allocator) {
         new Resolver(allocator, traceBuilderResult).resolveDataFlow(allocator.sortedBlocks());
     }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceRegisterAllocationPhase.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceRegisterAllocationPhase.java	Mon Nov 02 15:55:00 2015 +0100
@@ -47,7 +47,7 @@
 import com.oracle.graal.lir.StandardOp.ValueMoveOp;
 import com.oracle.graal.lir.alloc.trace.TraceAllocationPhase.TraceAllocationContext;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
 import com.oracle.graal.lir.phases.AllocationPhase;
 import com.oracle.graal.lir.ssi.SSIUtil;
 import com.oracle.graal.lir.ssi.SSIVerifier;
@@ -70,7 +70,7 @@
 
     @Override
     @SuppressWarnings("try")
-    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, SpillMoveFactory spillMoveFactory,
+    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, MoveFactory spillMoveFactory,
                     RegisterAllocationConfig registerAllocationConfig) {
         LIR lir = lirGenRes.getLIR();
         assert SSIVerifier.verify(lir) : "LIR not in SSI form.";
@@ -148,7 +148,7 @@
      *
      * TODO (je) find a better solution.
      */
-    private static boolean replaceStackToStackMoves(LIR lir, SpillMoveFactory spillMoveFactory) {
+    private static boolean replaceStackToStackMoves(LIR lir, MoveFactory spillMoveFactory) {
         boolean changed = false;
         for (AbstractBlockBase<?> block : lir.getControlFlowGraph().getBlocks()) {
             List<LIRInstruction> instructions = lir.getLIRforBlock(block);
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceTrivialAllocator.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceTrivialAllocator.java	Mon Nov 02 15:55:00 2015 +0100
@@ -42,7 +42,7 @@
 import com.oracle.graal.lir.ValueProcedure;
 import com.oracle.graal.lir.Variable;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
 import com.oracle.graal.lir.ssi.SSIUtil;
 import com.oracle.graal.lir.util.VariableVirtualStackValueMap;
 
@@ -59,7 +59,7 @@
     }
 
     @Override
-    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> trace, SpillMoveFactory spillMoveFactory,
+    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> trace, MoveFactory spillMoveFactory,
                     RegisterAllocationConfig registerAllocationConfig) {
         LIR lir = lirGenRes.getLIR();
         assert isTrivialTrace(lir, trace) : "Not a trivial trace! " + trace;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/dfa/LocationMarkerPhase.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/dfa/LocationMarkerPhase.java	Mon Nov 02 15:55:00 2015 +0100
@@ -42,7 +42,7 @@
 import com.oracle.graal.lir.framemap.FrameMap;
 import com.oracle.graal.lir.framemap.ReferenceMapBuilder;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
 import com.oracle.graal.lir.phases.AllocationPhase;
 
 /**
@@ -52,7 +52,7 @@
 public final class LocationMarkerPhase extends AllocationPhase {
 
     @Override
-    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, SpillMoveFactory spillMoveFactory,
+    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, MoveFactory spillMoveFactory,
                     RegisterAllocationConfig registerAllocationConfig) {
         new Marker<B>(lirGenRes.getLIR(), lirGenRes.getFrameMap()).build();
     }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/dfa/MarkBasePointersPhase.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/dfa/MarkBasePointersPhase.java	Mon Nov 02 15:55:00 2015 +0100
@@ -35,7 +35,7 @@
 import com.oracle.graal.lir.Variable;
 import com.oracle.graal.lir.framemap.FrameMap;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
 import com.oracle.graal.lir.phases.AllocationPhase;
 import com.oracle.graal.lir.util.IndexedValueMap;
 import com.oracle.graal.lir.util.ValueSet;
@@ -46,7 +46,7 @@
 public final class MarkBasePointersPhase extends AllocationPhase {
 
     @Override
-    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, SpillMoveFactory spillMoveFactory,
+    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, MoveFactory spillMoveFactory,
                     RegisterAllocationConfig registerAllocationConfig) {
         new Marker<B>(lirGenRes.getLIR(), null).build();
     }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java	Mon Nov 02 15:55:00 2015 +0100
@@ -96,8 +96,9 @@
     private LIRGenerationResult res;
 
     protected final ArithmeticLIRGenerator arithmeticLIRGen;
+    private final MoveFactory moveFactory;
 
-    public LIRGenerator(LIRKindTool lirKindTool, ArithmeticLIRGenerator arithmeticLIRGen, CodeGenProviders providers, CallingConvention cc, LIRGenerationResult res) {
+    public LIRGenerator(LIRKindTool lirKindTool, ArithmeticLIRGenerator arithmeticLIRGen, MoveFactory moveFactory, CodeGenProviders providers, CallingConvention cc, LIRGenerationResult res) {
         this.lirKindTool = lirKindTool;
         this.arithmeticLIRGen = arithmeticLIRGen;
         this.res = res;
@@ -106,6 +107,7 @@
 
         assert arithmeticLIRGen.lirGen == null;
         arithmeticLIRGen.lirGen = this;
+        this.moveFactory = moveFactory;
     }
 
     @Override
@@ -114,6 +116,26 @@
     }
 
     @Override
+    public MoveFactory getMoveFactory() {
+        return moveFactory;
+    }
+
+    private MoveFactory spillMoveFactory;
+
+    public MoveFactory getSpillMoveFactory() {
+        if (spillMoveFactory == null) {
+            boolean verify = false;
+            assert (verify = true) == true;
+            if (verify) {
+                spillMoveFactory = new VerifyingMoveFactory(moveFactory);
+            } else {
+                spillMoveFactory = moveFactory;
+            }
+        }
+        return spillMoveFactory;
+    }
+
+    @Override
     public TargetDescription target() {
         return getCodeCache().getTarget();
     }
@@ -160,8 +182,18 @@
     }
 
     @Override
+    public void emitMove(AllocatableValue dst, Value src) {
+        append(moveFactory.createMove(dst, src));
+    }
+
+    @Override
+    public void emitMoveConstant(AllocatableValue dst, Constant src) {
+        append(moveFactory.createLoad(dst, src));
+    }
+
+    @Override
     public Value emitConstant(LIRKind kind, Constant constant) {
-        if (constant instanceof JavaConstant && canInlineConstant((JavaConstant) constant)) {
+        if (constant instanceof JavaConstant && moveFactory.canInlineConstant((JavaConstant) constant)) {
             return new ConstantValue(toRegisterKind(kind), constant);
         } else {
             return emitLoadConstant(kind, constant);
@@ -197,18 +229,8 @@
         return (Variable) value;
     }
 
-    /**
-     * Checks whether the supplied constant can be used without loading it into a register for most
-     * operations, i.e., for commonly used arithmetic, logical, and comparison operations.
-     *
-     * @param c The constant to check.
-     * @return True if the constant can be used directly, false if the constant needs to be in a
-     *         register.
-     */
-    public abstract boolean canInlineConstant(JavaConstant c);
-
     public Value loadNonConst(Value value) {
-        if (isJavaConstant(value) && !canInlineConstant(asJavaConstant(value))) {
+        if (isJavaConstant(value) && !moveFactory.canInlineConstant(asJavaConstant(value))) {
             return emitMove(value);
         }
         return value;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java	Mon Nov 02 15:55:00 2015 +0100
@@ -52,12 +52,19 @@
 public interface LIRGeneratorTool extends BenchmarkCounterFactory {
 
     /**
-     * Factory for creating spill moves.
-     *
-     * The instructions returned by the methods must only depend on the input values. References to
-     * values that require interaction with register allocation are strictly forbidden.
+     * Factory for creating moves.
      */
-    public interface SpillMoveFactory {
+    public interface MoveFactory {
+
+        /**
+         * Checks whether the supplied constant can be used without loading it into a register for
+         * most operations, i.e., for commonly used arithmetic, logical, and comparison operations.
+         *
+         * @param c The constant to check.
+         * @return True if the constant can be used directly, false if the constant needs to be in a
+         *         register.
+         */
+        boolean canInlineConstant(JavaConstant c);
 
         LIRInstruction createMove(AllocatableValue result, Value input);
 
@@ -92,7 +99,15 @@
 
     boolean hasBlockEnd(AbstractBlockBase<?> block);
 
-    SpillMoveFactory getSpillMoveFactory();
+    MoveFactory getMoveFactory();
+
+    /**
+     * Get a special {@link MoveFactory} for spill moves.
+     *
+     * The instructions returned by this factory must only depend on the input values. References to
+     * values that require interaction with register allocation are strictly forbidden.
+     */
+    MoveFactory getSpillMoveFactory();
 
     BlockScope getBlockScope(AbstractBlockBase<?> block);
 
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/PhiResolver.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/PhiResolver.java	Mon Nov 02 15:55:00 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -38,7 +38,7 @@
 import com.oracle.graal.compiler.common.cfg.AbstractBlockBase;
 import com.oracle.graal.lir.LIRInsertionBuffer;
 import com.oracle.graal.lir.LIRInstruction;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
 
 /**
  * Converts phi instructions into moves.
@@ -113,7 +113,7 @@
     }
 
     private final LIRGeneratorTool gen;
-    private final SpillMoveFactory moveFactory;
+    private final MoveFactory moveFactory;
     private final LIRInsertionBuffer buffer;
     private final int insertBefore;
 
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/SpillMoveFactoryBase.java	Mon Nov 02 13:33:14 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-/*
- * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.lir.gen;
-
-import static com.oracle.graal.lir.LIRValueUtil.isJavaConstant;
-import static com.oracle.graal.lir.LIRValueUtil.isVariable;
-
-import java.util.EnumSet;
-
-import jdk.vm.ci.meta.AllocatableValue;
-import jdk.vm.ci.meta.Constant;
-import jdk.vm.ci.meta.Value;
-
-import com.oracle.graal.lir.LIRInstruction;
-import com.oracle.graal.lir.LIRInstruction.OperandFlag;
-import com.oracle.graal.lir.LIRInstruction.OperandMode;
-import com.oracle.graal.lir.StandardOp.LoadConstantOp;
-import com.oracle.graal.lir.StandardOp.StackMove;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
-
-/**
- * Base class for {@link SpillMoveFactory} that checks that the instructions created adhere to the
- * contract of {@link SpillMoveFactory}.
- */
-public abstract class SpillMoveFactoryBase implements SpillMoveFactory {
-
-    public final LIRInstruction createMove(AllocatableValue result, Value input) {
-        LIRInstruction inst = createMoveIntern(result, input);
-        assert checkResult(inst, result, input);
-        return inst;
-    }
-
-    public final LIRInstruction createStackMove(AllocatableValue result, AllocatableValue input) {
-        LIRInstruction inst = createStackMoveIntern(result, input);
-        assert checkResult(inst, result, input);
-        return inst;
-    }
-
-    public LIRInstruction createLoad(AllocatableValue result, Constant input) {
-        LIRInstruction inst = createLoadIntern(result, input);
-        assert inst instanceof LoadConstantOp && checkResult(inst, result, null);
-        return inst;
-    }
-
-    protected abstract LIRInstruction createMoveIntern(AllocatableValue result, Value input);
-
-    protected abstract LIRInstruction createLoadIntern(AllocatableValue result, Constant input);
-
-    protected LIRInstruction createStackMoveIntern(AllocatableValue result, AllocatableValue input) {
-        return new StackMove(result, input);
-    }
-
-    /** Closure for {@link SpillMoveFactoryBase#checkResult}. */
-    @SuppressWarnings("unused")
-    private static class CheckClosure {
-
-        private final AllocatableValue result;
-        private final Value input;
-
-        private int tempCount = 0;
-        private int aliveCount = 0;
-        private int stateCount = 0;
-        private int inputCount = 0;
-        private int outputCount = 0;
-
-        CheckClosure(AllocatableValue result, Value input) {
-            this.result = result;
-            this.input = input;
-        }
-
-        void tempProc(LIRInstruction op, Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
-            assert false : String.format("SpillMoveFactory: Instruction %s is not allowed to contain operand %s of mode %s", op, value, mode);
-            tempCount++;
-        }
-
-        void stateProc(LIRInstruction op, Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
-            assert false : String.format("SpillMoveFactory: Instruction %s is not allowed to contain operand %s of mode %s", op, value, mode);
-            stateCount++;
-        }
-
-        void aliveProc(LIRInstruction op, Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
-            assert !isVariable(value) && flags.contains(OperandFlag.UNINITIALIZED) : String.format("SpillMoveFactory: Instruction %s is not allowed to contain operand %s of mode %s", op, value, mode);
-            aliveCount++;
-        }
-
-        void inputProc(LIRInstruction op, Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
-            assert value.equals(input) || isJavaConstant(value) : String.format("SpillMoveFactory: Instruction %s can only have %s as input, got %s", op, input, value);
-            inputCount++;
-        }
-
-        void outputProc(LIRInstruction op, Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
-            assert value.equals(result) : String.format("SpillMoveFactory: Instruction %s can only have %s as input, got %s", op, input, value);
-            outputCount++;
-        }
-    }
-
-    /** Checks that the instructions adheres to the contract of {@link SpillMoveFactory}. */
-    private static boolean checkResult(LIRInstruction inst, AllocatableValue result, Value input) {
-
-        SpillMoveFactoryBase.CheckClosure c = new CheckClosure(result, input);
-        inst.visitEachInput(c::inputProc);
-        inst.visitEachOutput(c::outputProc);
-        inst.visitEachAlive(c::aliveProc);
-        inst.visitEachTemp(c::tempProc);
-        inst.visitEachState(c::stateProc);
-
-        assert c.outputCount >= 1 : "no output produced" + inst;
-        assert c.stateCount == 0 : "SpillMoveFactory: instruction must not have a state: " + inst;
-        return true;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/VerifyingMoveFactory.java	Mon Nov 02 15:55:00 2015 +0100
@@ -0,0 +1,135 @@
+/*
+ * 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.gen;
+
+import static com.oracle.graal.lir.LIRValueUtil.isJavaConstant;
+import static com.oracle.graal.lir.LIRValueUtil.isVariable;
+
+import java.util.EnumSet;
+
+import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.Value;
+
+import com.oracle.graal.lir.LIRInstruction;
+import com.oracle.graal.lir.LIRInstruction.OperandFlag;
+import com.oracle.graal.lir.LIRInstruction.OperandMode;
+import com.oracle.graal.lir.StandardOp.LoadConstantOp;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
+
+/**
+ * Wrapper for {@link MoveFactory} that checks that the instructions created adhere to the contract
+ * of {@link MoveFactory}.
+ */
+public final class VerifyingMoveFactory implements MoveFactory {
+
+    private final MoveFactory inner;
+
+    public VerifyingMoveFactory(MoveFactory inner) {
+        this.inner = inner;
+    }
+
+    public boolean canInlineConstant(JavaConstant c) {
+        return inner.canInlineConstant(c);
+    }
+
+    public LIRInstruction createMove(AllocatableValue result, Value input) {
+        LIRInstruction inst = inner.createMove(result, input);
+        assert checkResult(inst, result, input);
+        return inst;
+    }
+
+    public LIRInstruction createStackMove(AllocatableValue result, AllocatableValue input) {
+        LIRInstruction inst = inner.createStackMove(result, input);
+        assert checkResult(inst, result, input);
+        return inst;
+    }
+
+    public LIRInstruction createLoad(AllocatableValue result, Constant input) {
+        LIRInstruction inst = inner.createLoad(result, input);
+        assert inst instanceof LoadConstantOp && checkResult(inst, result, null);
+        return inst;
+    }
+
+    /** Closure for {@link VerifyingMoveFactory#checkResult}. */
+    @SuppressWarnings("unused")
+    private static class CheckClosure {
+
+        private final AllocatableValue result;
+        private final Value input;
+
+        private int tempCount = 0;
+        private int aliveCount = 0;
+        private int stateCount = 0;
+        private int inputCount = 0;
+        private int outputCount = 0;
+
+        CheckClosure(AllocatableValue result, Value input) {
+            this.result = result;
+            this.input = input;
+        }
+
+        void tempProc(LIRInstruction op, Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
+            assert false : String.format("SpillMoveFactory: Instruction %s is not allowed to contain operand %s of mode %s", op, value, mode);
+            tempCount++;
+        }
+
+        void stateProc(LIRInstruction op, Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
+            assert false : String.format("SpillMoveFactory: Instruction %s is not allowed to contain operand %s of mode %s", op, value, mode);
+            stateCount++;
+        }
+
+        void aliveProc(LIRInstruction op, Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
+            assert !isVariable(value) && flags.contains(OperandFlag.UNINITIALIZED) : String.format("SpillMoveFactory: Instruction %s is not allowed to contain operand %s of mode %s", op, value, mode);
+            aliveCount++;
+        }
+
+        void inputProc(LIRInstruction op, Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
+            assert value.equals(input) || isJavaConstant(value) : String.format("SpillMoveFactory: Instruction %s can only have %s as input, got %s", op, input, value);
+            inputCount++;
+        }
+
+        void outputProc(LIRInstruction op, Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
+            assert value.equals(result) : String.format("SpillMoveFactory: Instruction %s can only have %s as input, got %s", op, input, value);
+            outputCount++;
+        }
+    }
+
+    /**
+     * Checks that the instructions adheres to the contract of {@link MoveFactory}.
+     */
+    private static boolean checkResult(LIRInstruction inst, AllocatableValue result, Value input) {
+
+        VerifyingMoveFactory.CheckClosure c = new CheckClosure(result, input);
+        inst.visitEachInput(c::inputProc);
+        inst.visitEachOutput(c::outputProc);
+        inst.visitEachAlive(c::aliveProc);
+        inst.visitEachTemp(c::tempProc);
+        inst.visitEachState(c::stateProc);
+
+        assert c.outputCount >= 1 : "no output produced" + inst;
+        assert c.stateCount == 0 : "SpillMoveFactory: instruction must not have a state: " + inst;
+        return true;
+    }
+}
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/AllocationPhase.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/AllocationPhase.java	Mon Nov 02 15:55:00 2015 +0100
@@ -29,15 +29,15 @@
 import com.oracle.graal.compiler.common.alloc.RegisterAllocationConfig;
 import com.oracle.graal.compiler.common.cfg.AbstractBlockBase;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
 
 public abstract class AllocationPhase extends LIRPhase<AllocationPhase.AllocationContext> {
 
     public static final class AllocationContext {
-        private final SpillMoveFactory spillMoveFactory;
+        private final MoveFactory spillMoveFactory;
         private final RegisterAllocationConfig registerAllocationConfig;
 
-        public AllocationContext(SpillMoveFactory spillMoveFactory, RegisterAllocationConfig registerAllocationConfig) {
+        public AllocationContext(MoveFactory spillMoveFactory, RegisterAllocationConfig registerAllocationConfig) {
             this.spillMoveFactory = spillMoveFactory;
             this.registerAllocationConfig = registerAllocationConfig;
         }
@@ -49,6 +49,6 @@
     }
 
     protected abstract <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder,
-                    SpillMoveFactory spillMoveFactory, RegisterAllocationConfig registerAllocationConfig);
+                    MoveFactory spillMoveFactory, RegisterAllocationConfig registerAllocationConfig);
 
 }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/LSStackSlotAllocator.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/LSStackSlotAllocator.java	Mon Nov 02 15:55:00 2015 +0100
@@ -53,15 +53,15 @@
 import com.oracle.graal.debug.Indent;
 import com.oracle.graal.lir.LIR;
 import com.oracle.graal.lir.LIRInstruction;
-import com.oracle.graal.lir.VirtualStackSlot;
 import com.oracle.graal.lir.LIRInstruction.OperandFlag;
 import com.oracle.graal.lir.LIRInstruction.OperandMode;
 import com.oracle.graal.lir.ValueProcedure;
+import com.oracle.graal.lir.VirtualStackSlot;
 import com.oracle.graal.lir.framemap.FrameMapBuilderTool;
 import com.oracle.graal.lir.framemap.SimpleVirtualStackSlot;
 import com.oracle.graal.lir.framemap.VirtualStackSlotRange;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
 import com.oracle.graal.lir.phases.AllocationPhase;
 
 /**
@@ -91,7 +91,7 @@
     private static final DebugTimer AssignSlotsTimer = Debug.timer("LSStackSlotAllocator[AssignSlots]");
 
     @Override
-    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, SpillMoveFactory spillMoveFactory,
+    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, MoveFactory spillMoveFactory,
                     RegisterAllocationConfig registerAllocationConfig) {
         lirGenRes.buildFrameMap(this);
     }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/SimpleStackSlotAllocator.java	Mon Nov 02 13:33:14 2015 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/SimpleStackSlotAllocator.java	Mon Nov 02 15:55:00 2015 +0100
@@ -43,13 +43,13 @@
 import com.oracle.graal.lir.framemap.SimpleVirtualStackSlot;
 import com.oracle.graal.lir.framemap.VirtualStackSlotRange;
 import com.oracle.graal.lir.gen.LIRGenerationResult;
-import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
+import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory;
 import com.oracle.graal.lir.phases.AllocationPhase;
 
 public class SimpleStackSlotAllocator extends AllocationPhase implements StackSlotAllocator {
 
     @Override
-    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, SpillMoveFactory spillMoveFactory,
+    protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, MoveFactory spillMoveFactory,
                     RegisterAllocationConfig registerAllocationConfig) {
         lirGenRes.buildFrameMap(this);
     }