changeset 12680:3affe68ddb50

Merge
author Christos Kotselidis <christos.kotselidis@oracle.com>
date Tue, 05 Nov 2013 19:00:51 +0100
parents 944e31d1b427 (current diff) e53aa17b8fdf (diff)
children 343477cb53ff
files
diffstat 29 files changed, 864 insertions(+), 451 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/KernelTester.java	Tue Nov 05 18:59:03 2013 +0100
+++ b/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/KernelTester.java	Tue Nov 05 19:00:51 2013 +0100
@@ -69,7 +69,7 @@
         COMPILED, INJECT_HSAIL, INJECT_OCL
     }
 
-    private DispatchMode dispatchMode;
+    public DispatchMode dispatchMode;
     // Where the hsail comes from.
     private HsailMode hsailMode;
     private Method testMethod;
@@ -84,6 +84,7 @@
     private static final String propPkgName = KernelTester.class.getPackage().getName();
     private static Level logLevel;
     private static ConsoleHandler consoleHandler;
+    private boolean runOkraFirst = Boolean.getBoolean("kerneltester.runOkraFirst");
 
     static {
         logger = Logger.getLogger(propPkgName);
@@ -692,25 +693,42 @@
         }
     }
 
-    private void compareOkraToSeq(HsailMode hsailMode1) {
-        compareOkraToSeq(hsailMode1, false);
+    private void compareOkraToSeq(HsailMode hsailModeToUse) {
+        compareOkraToSeq(hsailModeToUse, false);
     }
 
     /**
-     * Runs this instance on OKRA, and as SEQ and compares the output of the two executions.
+     * Runs this instance on OKRA, and as SEQ and compares the output of the two executions. the
+     * runOkraFirst flag controls which order they are done in. Note the compiler must use eager
+     * resolving if Okra is done first.
      */
-    private void compareOkraToSeq(HsailMode hsailMode1, boolean useLambda) {
+    private void compareOkraToSeq(HsailMode hsailModeToUse, boolean useLambda) {
+        KernelTester testerSeq;
+        if (runOkraFirst) {
+            runOkraInstance(hsailModeToUse, useLambda);
+            testerSeq = runSeqInstance();
+        } else {
+            testerSeq = runSeqInstance();
+            runOkraInstance(hsailModeToUse, useLambda);
+        }
+        assertTrue("failed comparison to SEQ", compareResults(testerSeq));
+    }
+
+    private void runOkraInstance(HsailMode hsailModeToUse, boolean useLambda) {
+        // run Okra instance in exiting KernelTester object
+        this.setHsailMode(hsailModeToUse);
+        this.setDispatchMode(DispatchMode.OKRA);
+        this.useLambdaMethod = useLambda;
+        this.runTest();
+        this.disposeKernelOkra();
+    }
+
+    private KernelTester runSeqInstance() {
         // Create and run sequential instance.
         KernelTester testerSeq = newInstance();
         testerSeq.setDispatchMode(DispatchMode.SEQ);
         testerSeq.runTest();
-        // Now do this object.
-        this.setHsailMode(hsailMode1);
-        this.setDispatchMode(DispatchMode.OKRA);
-        this.useLambdaMethod = useLambda;
-        this.runTest();
-        this.disposeKernelOkra();
-        assertTrue("failed comparison to SEQ", compareResults(testerSeq));
+        return testerSeq;
     }
 
     public void testGeneratedHsail() {
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/FloatSqrtTest.java	Tue Nov 05 18:59:03 2013 +0100
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/FloatSqrtTest.java	Tue Nov 05 19:00:51 2013 +0100
@@ -23,8 +23,6 @@
 
 package com.oracle.graal.compiler.hsail.test;
 
-import java.util.*;
-
 import org.junit.*;
 
 import com.oracle.graal.compiler.hsail.test.infra.*;
@@ -34,13 +32,13 @@
  */
 public class FloatSqrtTest extends GraalKernelTester {
 
-    static final int size = 128;
-    static final float[] input = new float[size];
-    @Result static final float[] output = new float[size];
-    static float[] seed = new float[size];
+    static final int size = 64;
+    float[] input = new float[size];
+    @Result float[] output = new float[size];
     {
-        for (int i = 0; i < seed.length; i++) {
-            seed[i] = (float) Math.random();
+        for (int i = 0; i < size; i++) {
+            input[i] = i;
+            output[i] = -1.0f;
         }
 
     }
@@ -51,9 +49,7 @@
 
     @Override
     public void runTest() {
-        System.arraycopy(seed, 0, input, 0, seed.length);
-        Arrays.fill(output, 0f);
-        dispatchMethodKernel(64, input, output);
+        dispatchMethodKernel(size, input, output);
     }
 
     @Test
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticNBodySpillTest.java	Tue Nov 05 18:59:03 2013 +0100
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticNBodySpillTest.java	Tue Nov 05 19:00:51 2013 +0100
@@ -48,7 +48,7 @@
     @Result private float[] invxyz = new float[bodies * 3];
     @Result private float[] outvxyz = new float[bodies * 3];
     static float[] seedxyz = new float[bodies * 3];
-    {
+    static {
         final float maxDist = width / 4;
         for (int body = 0; body < (bodies * 3); body += 3) {
             final float theta = (float) (Math.random() * Math.PI * 2);
@@ -95,7 +95,6 @@
         dispatchMethodKernel(bodies, inxyz, outxyz, invxyz, outvxyz);
     }
 
-    // Marked to only run on hardware until simulator spill bug is fixed.
     @Test
     public void test() {
         testGeneratedHsail();
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticNBodyTest.java	Tue Nov 05 18:59:03 2013 +0100
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticNBodyTest.java	Tue Nov 05 19:00:51 2013 +0100
@@ -27,7 +27,6 @@
 
 import org.junit.*;
 
-import com.oracle.graal.compiler.hsail.*;
 import com.oracle.graal.compiler.hsail.test.infra.*;
 
 /**
@@ -49,7 +48,7 @@
     @Result private float[] invxyz = new float[bodies * 3];
     @Result private float[] outvxyz = new float[bodies * 3];
     static float[] seedxyz = new float[bodies * 3];
-    {
+    static {
         final float maxDist = width / 4;
         for (int body = 0; body < (bodies * 3); body += 3) {
             final float theta = (float) (Math.random() * Math.PI * 2);
@@ -96,9 +95,6 @@
         dispatchMethodKernel(bodies, inxyz, outxyz, invxyz, outvxyz);
     }
 
-    /**
-     * Requires {@link HSAILLIRGenerator#emitDirectCall} to be implemented.
-     */
     @Test
     public void test() {
         testGeneratedHsail();
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StringContainsTest.java	Tue Nov 05 18:59:03 2013 +0100
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StringContainsTest.java	Tue Nov 05 19:00:51 2013 +0100
@@ -24,9 +24,6 @@
 package com.oracle.graal.compiler.hsail.test;
 
 import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.hotspot.hsail.*;
-
 import org.junit.Test;
 
 /**
@@ -59,10 +56,7 @@
         dispatchMethodKernel(NUM, base);
     }
 
-    /**
-     * Requires {@link HSAILHotSpotForeignCallsProvider#lookupForeignCall} to be implemented.
-     */
-    @Test(expected = GraalInternalError.class)
+    @Test
     public void test() {
         testGeneratedHsail();
     }
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StringIndexOfTest.java	Tue Nov 05 18:59:03 2013 +0100
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StringIndexOfTest.java	Tue Nov 05 19:00:51 2013 +0100
@@ -24,9 +24,6 @@
 package com.oracle.graal.compiler.hsail.test;
 
 import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.hotspot.hsail.*;
-
 import org.junit.Test;
 
 /**
@@ -59,10 +56,7 @@
         dispatchMethodKernel(NUM, base);
     }
 
-    /**
-     * Requires {@link HSAILHotSpotForeignCallsProvider#lookupForeignCall} to be implemented.
-     */
-    @Test(expected = GraalInternalError.class)
+    @Test
     public void test() {
         testGeneratedHsail();
     }
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java	Tue Nov 05 18:59:03 2013 +0100
+++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java	Tue Nov 05 19:00:51 2013 +0100
@@ -45,8 +45,6 @@
 import com.oracle.graal.lir.hsail.HSAILControlFlow.CondMoveOp;
 import com.oracle.graal.lir.hsail.HSAILControlFlow.FloatCompareBranchOp;
 import com.oracle.graal.lir.hsail.HSAILControlFlow.FloatCondMoveOp;
-import com.oracle.graal.lir.hsail.HSAILControlFlow.ForeignCall1ArgOp;
-import com.oracle.graal.lir.hsail.HSAILControlFlow.ForeignCallNoArgOp;
 import com.oracle.graal.lir.hsail.HSAILControlFlow.ReturnOp;
 import com.oracle.graal.lir.hsail.HSAILMove.LeaOp;
 import com.oracle.graal.lir.hsail.HSAILMove.MoveFromRegOp;
@@ -628,27 +626,6 @@
     }
 
     @Override
-    protected void emitForeignCall(ForeignCallLinkage linkage, Value result, Value[] arguments, Value[] temps, LIRFrameState info) {
-        String callName = linkage.getDescriptor().getName();
-        if (callName.equals("createOutOfBoundsException") || callName.equals("createNullPointerException")) {
-            // hack Alert !!
-            switch (arguments.length) {
-                case 0:
-                    append(new ForeignCallNoArgOp(callName, result));
-                    break;
-                case 1:
-                    append(new ForeignCall1ArgOp(callName, result, arguments[0]));
-                    break;
-                default:
-                    throw GraalInternalError.unimplemented();
-            }
-
-        } else {
-            throw GraalInternalError.unimplemented();
-        }
-    }
-
-    @Override
     public void emitBitCount(Variable result, Value value) {
         if (value.getKind().getStackKind() == Kind.Int) {
             append(new HSAILBitManipulationOp(IPOPCNT, result, value));
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Tue Nov 05 18:59:03 2013 +0100
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Tue Nov 05 19:00:51 2013 +0100
@@ -729,8 +729,8 @@
                     value = unsafe.getLong(node, dataOffsets[i]);
                 } else if (type == Boolean.TYPE) {
                     value = unsafe.getBoolean(node, dataOffsets[i]);
-                } else if (type == Long.TYPE) {
-                    value = unsafe.getLong(node, dataOffsets[i]);
+                } else if (type == Float.TYPE) {
+                    value = unsafe.getFloat(node, dataOffsets[i]);
                 } else if (type == Double.TYPE) {
                     value = unsafe.getDouble(node, dataOffsets[i]);
                 } else {
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeWorkList.java	Tue Nov 05 18:59:03 2013 +0100
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeWorkList.java	Tue Nov 05 19:00:51 2013 +0100
@@ -60,7 +60,7 @@
 
     public void addAll(Iterable<? extends Node> nodes) {
         for (Node node : nodes) {
-            if (node.isAlive() && !node.isExternal()) {
+            if (node.isAlive()) {
                 this.add(node);
             }
         }
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java	Tue Nov 05 18:59:03 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java	Tue Nov 05 19:00:51 2013 +0100
@@ -60,12 +60,6 @@
     }
 
     @Override
-    public void completeInitialization() {
-        HSAILHotSpotForeignCallsProvider foreignCalls = (HSAILHotSpotForeignCallsProvider) getProviders().getForeignCalls();
-        foreignCalls.initialize(getProviders(), getRuntime().getConfig());
-    }
-
-    @Override
     public boolean shouldAllocateRegisters() {
         return true;
     }
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotForeignCallsProvider.java	Tue Nov 05 18:59:03 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotForeignCallsProvider.java	Tue Nov 05 19:00:51 2013 +0100
@@ -22,10 +22,6 @@
  */
 package com.oracle.graal.hotspot.hsail;
 
-import static com.oracle.graal.api.meta.LocationIdentity.*;
-import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition.*;
-import static com.oracle.graal.java.GraphBuilderPhase.RuntimeCalls.*;
-
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.hotspot.*;
@@ -39,17 +35,32 @@
 
     @Override
     public HotSpotForeignCallLinkage lookupForeignCall(ForeignCallDescriptor descriptor) {
-        return super.lookupForeignCall(descriptor);
+        // we don't really support foreign calls yet, but we do want to generate dummy code for them
+        // so we lazily create dummy linkages here.
+        if (foreignCalls.get(descriptor) == null) {
+            return register(new HotSpotForeignCallLinkage(descriptor, 0x12345678, null, null, null, null, false, new LocationIdentity[0]));
+        } else {
+            return super.lookupForeignCall(descriptor);
+        }
+    }
+
+    @Override
+    public boolean isReexecutable(ForeignCallDescriptor descriptor) {
+        return lookupForeignCall(descriptor).isReexecutable();
+    }
+
+    @Override
+    public LocationIdentity[] getKilledLocations(ForeignCallDescriptor descriptor) {
+        return lookupForeignCall(descriptor).getKilledLocations();
+    }
+
+    @Override
+    public boolean canDeoptimize(ForeignCallDescriptor descriptor) {
+        return lookupForeignCall(descriptor).canDeoptimize();
     }
 
     public Value[] getNativeABICallerSaveRegisters() {
         // TODO is this correct?
         return new Value[0];
     }
-
-    public void initialize(HotSpotProviders providers, HotSpotVMConfig c) {
-        // TODO are these correct? what other foreign calls are supported on HSAIL?
-        linkForeignCall(providers, CREATE_NULL_POINTER_EXCEPTION, c.createNullPointerExceptionAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, ANY_LOCATION);
-        linkForeignCall(providers, CREATE_OUT_OF_BOUNDS_EXCEPTION, c.createOutOfBoundsExceptionAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, ANY_LOCATION);
-    }
 }
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java	Tue Nov 05 18:59:03 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java	Tue Nov 05 19:00:51 2013 +0100
@@ -29,10 +29,8 @@
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.hsail.*;
-import com.oracle.graal.lir.hsail.HSAILMove.LoadCompressedPointer;
-import com.oracle.graal.lir.hsail.HSAILMove.LoadOp;
-import com.oracle.graal.lir.hsail.HSAILMove.StoreCompressedPointer;
-import com.oracle.graal.lir.hsail.HSAILMove.StoreOp;
+import com.oracle.graal.lir.hsail.HSAILControlFlow.*;
+import com.oracle.graal.lir.hsail.HSAILMove.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.util.*;
 
@@ -79,4 +77,46 @@
             append(new StoreOp(kind, storeAddress, input, state));
         }
     }
+
+    /***
+     * This is a very temporary solution to emitForeignCall. We don't really support foreign calls
+     * yet, but we do want to generate dummy code for them. The ForeignCallXXXOps just end up
+     * emitting a comment as to what Foreign call they would have made.
+     **/
+    @Override
+    public Variable emitForeignCall(ForeignCallLinkage linkage, DeoptimizingNode info, Value... args) {
+        Variable result = newVariable(Kind.Object);  // linkage.getDescriptor().getResultType());
+
+        // to make the LIRVerifier happy, we move any constants into registers
+        Value[] argLocations = new Value[args.length];
+        for (int i = 0; i < args.length; i++) {
+            Value arg = args[i];
+            AllocatableValue loc = newVariable(arg.getKind());
+            emitMove(loc, arg);
+            argLocations[i] = loc;
+        }
+
+        // here we could check the callName if we wanted to only handle certain callnames
+        String callName = linkage.getDescriptor().getName();
+        switch (argLocations.length) {
+            case 0:
+                append(new ForeignCallNoArgOp(callName, result));
+                break;
+            case 1:
+                append(new ForeignCall1ArgOp(callName, result, argLocations[0]));
+                break;
+            case 2:
+                append(new ForeignCall2ArgOp(callName, result, argLocations[0], argLocations[1]));
+                break;
+            default:
+                throw new InternalError("NYI emitForeignCall " + callName + ", " + argLocations.length + ", " + linkage);
+        }
+        return result;
+    }
+
+    @Override
+    protected void emitForeignCall(ForeignCallLinkage linkage, Value result, Value[] arguments, Value[] temps, LIRFrameState info) {
+        // this version of emitForeignCall not used for now
+    }
+
 }
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotReplacementsImpl.java	Tue Nov 05 18:59:03 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotReplacementsImpl.java	Tue Nov 05 19:00:51 2013 +0100
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.hotspot.hsail;
 
+import java.lang.reflect.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
@@ -42,13 +44,37 @@
     }
 
     @Override
+    protected ResolvedJavaMethod registerMethodSubstitution(Member originalMethod, Method substituteMethod) {
+        // TODO: decide if we want to override this in any way
+        return super.registerMethodSubstitution(originalMethod, substituteMethod);
+    }
+
+    @Override
+    public Class<? extends FixedWithNextNode> getMacroSubstitution(ResolvedJavaMethod method) {
+        Class<? extends FixedWithNextNode> klass = super.getMacroSubstitution(method);
+        if (klass == null) {
+            // eventually we want to only defer certain macro substitutions to the host, but for now
+            // we will do everything
+            return host.getMacroSubstitution(method);
+        }
+        return klass;
+    }
+
+    @Override
+    public StructuredGraph getSnippet(ResolvedJavaMethod method) {
+        // TODO must work in cooperation with HSAILHotSpotLoweringProvider
+        return null;
+    }
+
+    @Override
     public StructuredGraph getMethodSubstitution(ResolvedJavaMethod original) {
         StructuredGraph m = super.getMethodSubstitution(original);
         if (m == null) {
-            if (original.getDeclaringClass().equals(providers.getMetaAccess().lookupJavaType(Math.class))) {
-                return host.getMethodSubstitution(original);
-            }
+            // eventually we want to only defer certain substitutions to the host, but for now we
+            // will defer everything
+            return host.getMethodSubstitution(original);
         }
         return m;
     }
+
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Tue Nov 05 18:59:03 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Tue Nov 05 19:00:51 2013 +0100
@@ -157,10 +157,7 @@
      * Reads a word value from a given address.
      */
     public static long unsafeReadWord(long address) {
-        if (getHostWordKind() == Kind.Long) {
-            return unsafe.getLong(address);
-        }
-        return unsafe.getInt(address);
+        return unsafe.getAddress(address);
     }
 
     /**
@@ -177,7 +174,7 @@
         if (getHostWordKind() == Kind.Long) {
             return unsafe.getLong(object, offset);
         }
-        return unsafe.getInt(object, offset);
+        return unsafe.getInt(object, offset) & 0xFFFFFFFFL;
     }
 
     protected/* final */CompilerToVM compilerToVm;
--- a/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAIL.java	Tue Nov 05 18:59:03 2013 +0100
+++ b/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAIL.java	Tue Nov 05 19:00:51 2013 +0100
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.hsail;
 
-import static com.oracle.graal.api.code.MemoryBarriers.*;
 import static com.oracle.graal.api.code.ValueUtil.*;
 
 import java.nio.*;
@@ -37,7 +36,6 @@
  */
 public class HSAIL extends Architecture {
 
-    // @formatter:off
     public static final RegisterCategory CPU = new RegisterCategory("CPU");
     public static final RegisterCategory FPU = new RegisterCategory("FPU");
 
@@ -51,236 +49,77 @@
     public static final Register c6 = new Register(6, 6, "c6", CPU);
     public static final Register c7 = new Register(7, 7, "c7", CPU);
 
-    //32 bit registers.
-    public static final Register s0  = new Register(8,  0,  "s0", CPU);
-    public static final Register s1  = new Register(9,  1,  "s1", CPU);
+    // 32 bit registers.
+    public static final Register s0 = new Register(8, 0, "s0", CPU);
+    public static final Register s1 = new Register(9, 1, "s1", CPU);
     public static final Register s2 = new Register(10, 2, "s2", CPU);
     public static final Register s3 = new Register(11, 3, "s3", CPU);
     public static final Register s4 = new Register(12, 4, "s4", CPU);
     public static final Register s5 = new Register(13, 5, "s5", CPU);
     public static final Register s6 = new Register(14, 6, "s6", CPU);
     public static final Register s7 = new Register(15, 7, "s7", CPU);
-    public static final Register s8  = new Register(16,  8,  "s8", CPU);
-    public static final Register s9  = new Register(17,  9,  "s9", CPU);
+    public static final Register s8 = new Register(16, 8, "s8", CPU);
+    public static final Register s9 = new Register(17, 9, "s9", CPU);
     public static final Register s10 = new Register(18, 10, "s10", CPU);
     public static final Register s11 = new Register(19, 11, "s11", CPU);
     public static final Register s12 = new Register(20, 12, "s12", CPU);
     public static final Register s13 = new Register(21, 13, "s13", CPU);
     public static final Register s14 = new Register(22, 14, "s14", CPU);
     public static final Register s15 = new Register(23, 15, "s15", CPU);
-    public static final Register s16  = new Register(24, 16,  "s16", CPU);
-    public static final Register s17  = new Register(25,  17,  "s17", CPU);
+    public static final Register s16 = new Register(24, 16, "s16", CPU);
+    public static final Register s17 = new Register(25, 17, "s17", CPU);
     public static final Register s18 = new Register(26, 18, "s18", CPU);
     public static final Register s19 = new Register(27, 19, "s19", CPU);
     public static final Register s20 = new Register(28, 20, "s20", CPU);
     public static final Register s21 = new Register(29, 21, "s21", CPU);
     public static final Register s22 = new Register(30, 22, "s22", CPU);
     public static final Register s23 = new Register(31, 23, "s23", CPU);
-    public static final Register s24  = new Register(32, 24,  "s24", CPU);
-    public static final Register s25  = new Register(33, 25,  "s25", CPU);
+    public static final Register s24 = new Register(32, 24, "s24", CPU);
+    public static final Register s25 = new Register(33, 25, "s25", CPU);
     public static final Register s26 = new Register(34, 26, "s26", CPU);
     public static final Register s27 = new Register(35, 27, "s27", CPU);
     public static final Register s28 = new Register(36, 28, "s28", CPU);
     public static final Register s29 = new Register(37, 29, "s29", CPU);
     public static final Register s30 = new Register(38, 30, "s30", CPU);
     public static final Register s31 = new Register(39, 31, "s31", CPU);
-    public static final Register s32  = new Register(40, 32,  "s32", CPU);
-    public static final Register s33  = new Register(41,  33,  "s33", CPU);
-    public static final Register s34 = new Register(42, 34, "s34", CPU);
-    public static final Register s35 = new Register(43, 35, "s35", CPU);
-    public static final Register s36 = new Register(44, 36, "s36", CPU);
-    public static final Register s37 = new Register(45, 37, "s37", CPU);
-    public static final Register s38 = new Register(45, 38, "s38", CPU);
-    public static final Register s39 = new Register(46, 39, "s39", CPU);
-    public static final Register s40  = new Register(47, 40,  "s40", CPU);
-    public static final Register s41  = new Register(48,  41,  "s41", CPU);
-    public static final Register s42 = new Register(49, 42, "s42", CPU);
-    public static final Register s43 = new Register(50, 43, "s43", CPU);
-    public static final Register s44 = new Register(51, 44, "s44", CPU);
-    public static final Register s45 = new Register(52, 45, "s45", CPU);
-    public static final Register s46 = new Register(53, 46, "s46", CPU);
-    public static final Register s47 = new Register(54, 47, "s47", CPU);
-    public static final Register s48  = new Register(55, 48,  "s48", CPU);
-    public static final Register s49  = new Register(56,  49,  "s49", CPU);
-    public static final Register s50 = new Register(57, 50, "s50", CPU);
-    public static final Register s51 = new Register(58, 51, "s51", CPU);
-    public static final Register s52 = new Register(59, 52, "s52", CPU);
-    public static final Register s53 = new Register(60, 53, "s53", CPU);
-    public static final Register s54 = new Register(61, 54, "s54", CPU);
-    public static final Register s55 = new Register(62, 55, "s55", CPU);
-    public static final Register s56  = new Register(64, 56,  "s56", CPU);
-    public static final Register s57  = new Register(64, 57,  "s57", CPU);
-    public static final Register s58 = new Register(65, 58, "s58", CPU);
-    public static final Register s59 = new Register(66, 59, "s59", CPU);
-    public static final Register s60 = new Register(67, 60, "s60", CPU);
-    public static final Register s61 = new Register(68, 61, "s61", CPU);
-    public static final Register s62 = new Register(69, 62, "s62", CPU);
-    public static final Register s63 = new Register(70, 63, "s63", CPU);
-    public static final Register s64  = new Register(71, 64,  "s64", CPU);
-    public static final Register s65  = new Register(72, 65,  "s65", CPU);
-    public static final Register s66 = new Register(73, 66, "s66", CPU);
-    public static final Register s67 = new Register(74, 67, "s67", CPU);
-    public static final Register s68 = new Register(75, 68, "s68", CPU);
-    public static final Register s69 = new Register(76, 69, "s69", CPU);
-    public static final Register s70 = new Register(77, 70, "s70", CPU);
-    public static final Register s71 = new Register(78, 71, "s71", CPU);
-    public static final Register s72  = new Register(79, 72,  "s72", CPU);
-    public static final Register s73  = new Register(80, 73,  "s73", CPU);
-    public static final Register s74 = new Register(81, 74, "s74", CPU);
-    public static final Register s75 = new Register(82, 75, "s75", CPU);
-    public static final Register s76 = new Register(83, 76, "s76", CPU);
-    public static final Register s77 = new Register(84, 77, "s77", CPU);
-    public static final Register s78 = new Register(85, 78, "s78", CPU);
-    public static final Register s79 = new Register(86, 79, "s79", CPU);
-    public static final Register s80  = new Register(87, 80,  "s80", CPU);
-    public static final Register s81  = new Register(88, 81,  "s81", CPU);
-    public static final Register s82 = new Register(89, 82, "s82", CPU);
-    public static final Register s83 = new Register(90, 83, "s83", CPU);
-    public static final Register s84 = new Register(91, 84, "s84", CPU);
-    public static final Register s85 = new Register(92, 85, "s85", CPU);
-    public static final Register s86 = new Register(93, 86, "s86", CPU);
-    public static final Register s87 = new Register(94, 87, "s87", CPU);
-    public static final Register s88  = new Register(95,  88,  "s88", CPU);
-    public static final Register s89  = new Register(96,  89,  "s89", CPU);
-    public static final Register s90 = new Register(97, 90, "s90", CPU);
-    public static final Register s91 = new Register(98, 91, "s91", CPU);
-    public static final Register s92 = new Register(99, 92, "s92", CPU);
-    public static final Register s93 = new Register(100, 93, "s93", CPU);
-    public static final Register s94 = new Register(101, 94, "s94", CPU);
-    public static final Register s95 = new Register(102, 95, "s95", CPU);
-    public static final Register s96  = new Register(103, 96,  "s96", CPU);
-    public static final Register s97  = new Register(104, 97,  "s97", CPU);
-    public static final Register s98 = new Register(105, 98, "s98", CPU);
-    public static final Register s99 = new Register(106, 99, "s99", CPU);
-    public static final Register s100 = new Register(107, 100, "s100", CPU);
-    public static final Register s101 = new Register(108, 101, "s101", CPU);
-    public static final Register s102 = new Register(109, 102, "s102", CPU);
-    public static final Register s103 = new Register(110, 103, "s103", CPU);
-    public static final Register s104  = new Register(111, 104,  "s104", CPU);
-    public static final Register s105  = new Register(112,  105,  "s105", CPU);
-    public static final Register s106 = new Register(113, 106, "s106", CPU);
-    public static final Register s107 = new Register(114, 107, "s107", CPU);
-    public static final Register s108 = new Register(115, 108, "s108", CPU);
-    public static final Register s109 = new Register(116, 109, "s109", CPU);
-    public static final Register s110 = new Register(117, 110, "s110", CPU);
-    public static final Register s111 = new Register(118, 111, "s111", CPU);
-    public static final Register s112  = new Register(119, 112,  "s112", CPU);
-    public static final Register s113  = new Register(120, 113,  "s113", CPU);
-    public static final Register s114 = new Register(121, 114, "s114", CPU);
-    public static final Register s115 = new Register(122, 115, "s115", CPU);
-    public static final Register s116 = new Register(123, 116, "s116", CPU);
-    public static final Register s117 = new Register(124, 117, "s117", CPU);
-    public static final Register s118 = new Register(125, 118, "s118", CPU);
-    public static final Register s119 = new Register(126, 119, "s119", CPU);
-    public static final Register s120  = new Register(127, 120,  "s120", CPU);
-    public static final Register s121  = new Register(128, 121,  "s121", CPU);
-    public static final Register s122 = new Register(129, 122, "s122", CPU);
-    public static final Register s123 = new Register(130, 123, "s123", CPU);
-    public static final Register s124 = new Register(131, 124, "s124", CPU);
-    public static final Register s125 = new Register(132, 125, "s125", CPU);
-    public static final Register s126 = new Register(133, 126, "s126", CPU);
-    public static final Register s127 = new Register(134, 127, "s127", CPU);
+
+    // 64 bit registers.
+    public static final Register d0 = new Register(40, 0, "d0", CPU);
+    public static final Register d1 = new Register(41, 1, "d1", CPU);
+    public static final Register d2 = new Register(42, 2, "d2", CPU);
+    public static final Register d3 = new Register(43, 3, "d3", CPU);
+    public static final Register d4 = new Register(44, 4, "d4", CPU);
+    public static final Register d5 = new Register(45, 5, "d5", CPU);
+    public static final Register d6 = new Register(46, 6, "d6", CPU);
+    public static final Register d7 = new Register(47, 7, "d7", CPU);
+    public static final Register d8 = new Register(48, 8, "d8", CPU);
+    public static final Register d9 = new Register(49, 9, "d9", CPU);
+    public static final Register d10 = new Register(50, 10, "d10", CPU);
+    public static final Register d11 = new Register(51, 11, "d11", CPU);
+    public static final Register d12 = new Register(52, 12, "d12", CPU);
+    public static final Register d13 = new Register(53, 13, "d13", CPU);
+    public static final Register d14 = new Register(54, 14, "d14", CPU);
+    public static final Register d15 = new Register(55, 15, "d15", CPU);
 
-    //64 bit registers.
-    public static final Register d0  = new Register(135,  0,  "d0", CPU);
-    public static final Register d1  = new Register(136,  1,  "d1", CPU);
-    public static final Register d2 = new Register(137, 2, "d2", CPU);
-    public static final Register d3 = new Register(138, 3, "d3", CPU);
-    public static final Register d4 = new Register(139, 4, "d4", CPU);
-    public static final Register d5 = new Register(140, 5, "d5", CPU);
-    public static final Register d6 = new Register(141, 6, "d6", CPU);
-    public static final Register d7 = new Register(142, 7, "d7", CPU);
-    public static final Register d8  = new Register(143,  8,  "d8", CPU);
-    public static final Register d9  = new Register(144,  9,  "d9", CPU);
-    public static final Register d10 = new Register(145, 10, "d10", CPU);
-    public static final Register d11 = new Register(146, 11, "d11", CPU);
-    public static final Register d12 = new Register(147, 12, "d12", CPU);
-    public static final Register d13 = new Register(148, 13, "d13", CPU);
-    public static final Register d14 = new Register(149, 14, "d14", CPU);
-    public static final Register d15 = new Register(150, 15, "d15", CPU);
-    public static final Register d16  = new Register(151, 16,  "d16", CPU);
-    public static final Register d17  = new Register(152,  17,  "d17", CPU);
-    public static final Register d18 = new Register(153, 18, "d18", CPU);
-    public static final Register d19 = new Register(154, 19, "d19", CPU);
-    public static final Register d20 = new Register(155, 20, "d20", CPU);
-    public static final Register d21 = new Register(156, 21, "d21", CPU);
-    public static final Register d22 = new Register(157, 22, "d22", CPU);
-    public static final Register d23 = new Register(158, 23, "d23", CPU);
-    public static final Register d24  = new Register(159, 24,  "d24", CPU);
-    public static final Register d25  = new Register(160, 25,  "d25", CPU);
-    public static final Register d26 = new Register(161, 26, "d26", CPU);
-    public static final Register d27 = new Register(162, 27, "d27", CPU);
-    public static final Register d28 = new Register(163, 28, "d28", CPU);
-    public static final Register d29 = new Register(164, 29, "d29", CPU);
-    public static final Register d30 = new Register(165, 30, "d30", CPU);
-    public static final Register d31 = new Register(166, 31, "d31", CPU);
-    public static final Register d32  = new Register(167, 32,  "d32", CPU);
-    public static final Register d33  = new Register(168,  33,  "d33", CPU);
-    public static final Register d34 = new Register(169, 34, "d34", CPU);
-    public static final Register d35 = new Register(170, 35, "d35", CPU);
-    public static final Register d36 = new Register(171, 36, "d36", CPU);
-    public static final Register d37 = new Register(172, 37, "d37", CPU);
-    public static final Register d38 = new Register(173, 38, "d38", CPU);
-    public static final Register d39 = new Register(174, 39, "d39", CPU);
-    public static final Register d40  = new Register(175, 40,  "d40", CPU);
-    public static final Register d41  = new Register(176,  41,  "d41", CPU);
-    public static final Register d42 = new Register(177, 42, "d42", CPU);
-    public static final Register d43 = new Register(178, 43, "d43", CPU);
-    public static final Register d44 = new Register(179, 44, "d44", CPU);
-    public static final Register d45 = new Register(180, 45, "d45", CPU);
-    public static final Register d46 = new Register(181, 46, "d46", CPU);
-    public static final Register d47 = new Register(182, 47, "d47", CPU);
-    public static final Register d48  = new Register(183, 48,  "d48", CPU);
-    public static final Register d49  = new Register(184,  49,  "d49", CPU);
-    public static final Register d50 = new Register(185, 50, "d50", CPU);
-    public static final Register d51 = new Register(186, 51, "d51", CPU);
-    public static final Register d52 = new Register(187, 52, "d52", CPU);
-    public static final Register d53 = new Register(188, 53, "d53", CPU);
-    public static final Register d54 = new Register(189, 54, "d54", CPU);
-    public static final Register d55 = new Register(190, 55, "d55", CPU);
-    public static final Register d56  = new Register(191, 56,  "d56", CPU);
-    public static final Register d57  = new Register(192, 57,  "d57", CPU);
-    public static final Register d58 = new Register(193, 58, "d58", CPU);
-    public static final Register d59 = new Register(194, 59, "d59", CPU);
-    public static final Register d60 = new Register(195, 60, "d60", CPU);
-    public static final Register d61 = new Register(196, 61, "d61", CPU);
-    public static final Register d62 = new Register(197, 62, "d62", CPU);
-    public static final Register d63 = new Register(198, 63, "d63", CPU);
+    // 128 bit registers.
+    public static final Register q0 = new Register(56, 0, "q0", CPU);
+    public static final Register q1 = new Register(57, 1, "q1", CPU);
+    public static final Register q2 = new Register(58, 2, "q2", CPU);
+    public static final Register q3 = new Register(59, 3, "q3", CPU);
+    public static final Register q4 = new Register(60, 4, "q4", CPU);
+    public static final Register q5 = new Register(61, 5, "q5", CPU);
+    public static final Register q6 = new Register(62, 6, "q6", CPU);
+    public static final Register q7 = new Register(63, 7, "q7", CPU);
+    public static final Register q8 = new Register(64, 8, "q8", CPU);
+    public static final Register q9 = new Register(65, 9, "q9", CPU);
+    public static final Register q10 = new Register(66, 10, "q10", CPU);
+    public static final Register q11 = new Register(67, 11, "q11", CPU);
+    public static final Register q12 = new Register(68, 12, "q12", CPU);
+    public static final Register q13 = new Register(69, 13, "q13", CPU);
+    public static final Register q14 = new Register(70, 14, "q14", CPU);
+    public static final Register q15 = new Register(71, 15, "q15", CPU);
 
-    //128 bit registers.
-    public static final Register q0 = new Register(199, 0, "q0", CPU);
-    public static final Register q1 = new Register(200, 1, "q1", CPU);
-    public static final Register q2 = new Register(201, 2, "q2", CPU);
-    public static final Register q3 = new Register(202, 3, "q3", CPU);
-    public static final Register q4 = new Register(203, 4, "q4", CPU);
-    public static final Register q5 = new Register(204, 5, "q5", CPU);
-    public static final Register q6 = new Register(205, 6, "q6", CPU);
-    public static final Register q7 = new Register(206, 7, "q7", CPU);
-    public static final Register q8 = new Register(207, 8, "q8", CPU);
-    public static final Register q9 = new Register(208, 9, "q9", CPU);
-    public static final Register q10 = new Register(209, 10, "q10", CPU);
-    public static final Register q11 = new Register(210, 11, "q11", CPU);
-    public static final Register q12 = new Register(211, 12, "q12", CPU);
-    public static final Register q13 = new Register(212, 13, "q13", CPU);
-    public static final Register q14 = new Register(213, 14, "q14", CPU);
-    public static final Register q15 = new Register(214, 15, "q15", CPU);
-    public static final Register q16 = new Register(215, 16, "q16", CPU);
-    public static final Register q17 = new Register(216, 17, "q17", CPU);
-    public static final Register q18 = new Register(217, 18, "q18", CPU);
-    public static final Register q19 = new Register(218, 19, "q19", CPU);
-    public static final Register q20 = new Register(219, 20, "q20", CPU);
-    public static final Register q21 = new Register(220, 21, "q21", CPU);
-    public static final Register q22 = new Register(221, 22, "q22", CPU);
-    public static final Register q23 = new Register(222, 23, "q23", CPU);
-    public static final Register q24 = new Register(223, 24, "q24", CPU);
-    public static final Register q25 = new Register(224, 25, "q25", CPU);
-    public static final Register q26 = new Register(225, 26, "q26", CPU);
-    public static final Register q27 = new Register(226, 27, "q27", CPU);
-    public static final Register q28 = new Register(227, 28, "q28", CPU);
-    public static final Register q29 = new Register(228, 29, "q29", CPU);
-    public static final Register q30 = new Register(229, 30, "q30", CPU);
-    public static final Register q31 = new Register(230, 31, "q31", CPU);
-
+    // @formatter:off
     public static final Register[] cRegisters = {
         c0, c1, c2, c3, c4, c5, c6, c7
     };
@@ -289,58 +128,28 @@
         s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10,
         s11, s12, s13, s14, s15, s16, s17, s18, s19,
         s20, s21, s22, s23, s24, s25, s26, s27, s28,
-        s29, s30, s31, s32, s33, s34, s35, s36, s37,
-        s38, s39, s40, s41, s42, s43, s44, s45, s46,
-        s47, s48, s49, s50, s51, s52, s53, s54, s55,
-        s56, s57, s58, s59, s60, s61, s62, s63, s64,
-        s65, s66, s67, s68, s69, s70, s71, s72, s73,
-        s74, s75, s76, s77, s78, s79, s80, s81, s82,
-        s83, s84, s85, s86, s87, s88, s89, s90, s91,
-        s92, s93, s94, s95, s96, s97, s98, s99, s100,
-        s101, s102, s103, s104, s105, s106, s107, s108,
-        s109, s110, s111, s112, s113, s114, s115, s116,
-        s117, s118, s119, s120, s121, s122, s123, s124,
-        s125, s126, s127
+        s29, s30, s31
     };
 
     public static final Register[] dRegisters = {
-        d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28,
-        d29, d30, d31, d32, d33, d34, d35, d36, d37, d38, d39, d40, d41, d42, d43, d44, d45, d46, d47, d48, d49, d50, d51, d52, d53, d54, d55,
-        d56, d57, d58, d59, d60, d61, d62, d63
+        d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15
     };
 
     public static final Register[] qRegisters = {
-        q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12, q13, q14, q15, q16, q17, q18, q19, q20, q21, q22, q23, q24, q25, q26, q27, q28, q29, q30, q31
+        q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12, q13, q14, q15
     };
 
     public static final Register[] allRegisters = {
-        c0, c1, c2, c3, c4, c5, c6, c7, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19,
-        s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31, s32, s33, s34, s35,
-        s36, s37, s38, s39, s40, s41, s42, s43, s44, s45, s46, s47, s48, s49, s50, s51, s52,
-        s53, s54, s55, s56, s57, s58, s59, s60, s61,
-        s62, s63, s64, s65, s66, s67, s68, s69, s70,
-        s71, s72, s73, s74, s75, s76, s77, s78, s79,
-        s80, s81, s82, s83, s84, s85, s86, s87, s88,
-        s89, s90, s91, s92, s93, s94, s95, s96, s97,
-        s98, s99, s100, s101, s102, s103, s104, s105,
-        s106, s107, s108, s109, s110, s111, s112, s113,
-        s114, s115, s116, s117, s118, s119, s120, s121,
-        s122, s123, s124, s125, s126, s127,  d0, d1, d2,
-        d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13,
-        d14, d15, d16, d17, d18, d19, d20, d21, d22, d23,
-        d24, d25, d26, d27, d28, d29, d30, d31, d32, d33,
-        d34, d35, d36, d37, d38, d39, d40, d41, d42, d43,
-        d44, d45, d46, d47, d48, d49, d50, d51, d52, d53,
-        d54, d55, d56, d57, d58, d59, d60, d61, d62, d63,
-        q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11,
-        q12, q13, q14, q15, q16, q17, q18, q19, q20, q21,
-        q22, q23, q24, q25, q26, q27, q28, q29, q30, q31
+        c0, c1, c2, c3, c4, c5, c6, c7, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15,
+        d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13,
+        d14, d15, q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11,
+        q12, q13, q14, q15
     };
 
     // @formatter:on
 
     public HSAIL() {
-        super("HSAIL", 8, ByteOrder.LITTLE_ENDIAN, false, allRegisters, LOAD_STORE | STORE_STORE, 1, q31.encoding + 1, 8);
+        super("HSAIL", 8, ByteOrder.LITTLE_ENDIAN, false, allRegisters, 0, 1, q15.encoding + 1, 8);
     }
 
     public static int getStackOffset(Value reg) {
@@ -368,7 +177,7 @@
         switch (argType) {
             case "float":
                 reg = asFloatReg(arg);
-                encoding = reg.encoding() + 16;
+                encoding = reg.encoding();
                 break;
             case "int":
                 reg = asIntReg(arg);
@@ -380,7 +189,7 @@
                 break;
             case "double":
                 reg = asDoubleReg(arg);
-                encoding = reg.encoding() + 16;
+                encoding = reg.encoding();
                 break;
             case "Object":
                 reg = asObjectReg(arg);
--- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILControlFlow.java	Tue Nov 05 18:59:03 2013 +0100
+++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILControlFlow.java	Tue Nov 05 19:00:51 2013 +0100
@@ -79,6 +79,16 @@
         }
     }
 
+    public static class ForeignCall2ArgOp extends ForeignCall1ArgOp {
+
+        @Use({REG, ILLEGAL}) protected Value arg2;
+
+        public ForeignCall2ArgOp(String callName, Value out, Value arg1, Value arg2) {
+            super(callName, out, arg1);
+            this.arg2 = arg2;
+        }
+    }
+
     public static class CompareBranchOp extends HSAILLIRInstruction implements StandardOp.BranchOp {
 
         @Opcode protected final HSAILCompare opcode;
@@ -205,13 +215,13 @@
 
         @Opcode protected final HSAILCompare opcode;
         @Def({REG, HINT}) protected Value result;
-        @Alive({REG}) protected Value trueValue;
+        @Use({REG, STACK, CONST}) protected Value trueValue;
         @Use({REG, STACK, CONST}) protected Value falseValue;
         @Use({REG, STACK, CONST}) protected Value left;
         @Use({REG, STACK, CONST}) protected Value right;
         protected final Condition condition;
 
-        public CondMoveOp(HSAILCompare opcode, Variable left, Variable right, Variable result, Condition condition, Variable trueValue, Value falseValue) {
+        public CondMoveOp(HSAILCompare opcode, Variable left, Variable right, Variable result, Condition condition, Value trueValue, Value falseValue) {
             this.opcode = opcode;
             this.result = result;
             this.left = left;
--- a/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java	Tue Nov 05 18:59:03 2013 +0100
+++ b/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java	Tue Nov 05 19:00:51 2013 +0100
@@ -167,23 +167,93 @@
 
     @Test
     public void testNot() {
-        assertEquals(new IntegerStamp(Kind.Int, -11, -1, 0xfffffff0L, 0xffffffffL), StampTool.not(new IntegerStamp(Kind.Int, 0, 10, 0, 0xf)));
+        assertEquals(new IntegerStamp(Kind.Int, -11, -1, 0xffff_fff0L, 0xffff_ffffL), StampTool.not(new IntegerStamp(Kind.Int, 0, 10, 0, 0xf)));
+    }
+
+    @Test
+    public void testAddIntSimple() {
+        assertEquals(StampFactory.forInteger(Kind.Int, 0, 30, 0, 31), StampTool.add(StampFactory.forInteger(Kind.Int, 0, 10), StampFactory.forInteger(Kind.Int, 0, 20)));
+    }
+
+    @Test
+    public void testAddNegativeOverFlowInt1() {
+        assertEquals(StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 0xffff_ffffL),
+                        StampTool.add(StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE, 0), StampFactory.forInteger(Kind.Int, -1, 0)));
+    }
+
+    @Test
+    public void testAddNegativeOverFlowInt2() {
+        assertEquals(StampFactory.forInteger(Kind.Int, Integer.MAX_VALUE - 2, Integer.MAX_VALUE, 0x7fff_fffcL, 0x7fff_ffffL),
+                        StampTool.add(StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE, Integer.MIN_VALUE + 1), StampFactory.forInteger(Kind.Int, -3, -2)));
+    }
+
+    @Test
+    public void testAddPositiveOverFlowInt1() {
+        assertEquals(StampFactory.forKind(Kind.Int), StampTool.add(StampFactory.forInteger(Kind.Int, 0, 1), StampFactory.forInteger(Kind.Int, 0, Integer.MAX_VALUE)));
+    }
+
+    @Test
+    public void testAddPositiveOverFlowInt2() {
+        assertEquals(StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE, Integer.MIN_VALUE + 2),
+                        StampTool.add(StampFactory.forInteger(Kind.Int, Integer.MAX_VALUE - 1, Integer.MAX_VALUE), StampFactory.forInteger(Kind.Int, 2, 3)));
+    }
+
+    @Test
+    public void testAddOverFlowsInt() {
+        assertEquals(StampFactory.forKind(Kind.Int), StampTool.add(StampFactory.forInteger(Kind.Int, -1, 1), StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE, Integer.MAX_VALUE)));
+    }
+
+    @Test
+    public void testAddLongSimple() {
+        assertEquals(StampFactory.forInteger(Kind.Long, 0, 30, 0, 31), StampTool.add(StampFactory.forInteger(Kind.Long, 0, 10), StampFactory.forInteger(Kind.Long, 0, 20)));
     }
 
     @Test
-    public void testAdd() {
-        assertEquals(StampFactory.forInteger(Kind.Int, 0, 30), StampTool.add(StampFactory.forInteger(Kind.Int, 0, 10), StampFactory.forInteger(Kind.Int, 0, 20)));
-        assertEquals(StampFactory.forKind(Kind.Long),
+    public void testAddNegativOverFlowLong1() {
+        assertEquals(StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MAX_VALUE, 0, 0xffff_ffff_ffff_ffffL),
                         StampTool.add(StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MIN_VALUE + 1), StampFactory.forInteger(Kind.Long, Integer.MIN_VALUE, Integer.MAX_VALUE)));
-        assertEquals(StampFactory.forInteger(Kind.Int, -2147483647, 31 - 2147483647),
-                        StampTool.add(StampFactory.forInteger(Kind.Int, 0, 31), StampFactory.forInteger(Kind.Int, -2147483647, -2147483647)));
+    }
+
+    @Test
+    public void testAddNegativeOverFlowLong2() {
+        assertEquals(StampFactory.forInteger(Kind.Long, Long.MAX_VALUE - 2, Long.MAX_VALUE),
+                        StampTool.add(StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MIN_VALUE + 1), StampFactory.forInteger(Kind.Long, -3, -2)));
+    }
+
+    @Test
+    public void testAddPositiveOverFlowLong1() {
+        assertEquals(StampFactory.forKind(Kind.Long), StampTool.add(StampFactory.forInteger(Kind.Long, 0, 1), StampFactory.forInteger(Kind.Long, 0, Long.MAX_VALUE)));
+    }
+
+    @Test
+    public void testAddPositiveOverFlowLong2() {
+        assertEquals(StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MIN_VALUE + 2),
+                        StampTool.add(StampFactory.forInteger(Kind.Long, Long.MAX_VALUE - 1, Long.MAX_VALUE), StampFactory.forInteger(Kind.Long, 2, 3)));
+    }
 
-        assertEquals(StampFactory.forInteger(Kind.Int, 0x8000007e, 0x8000007f, 0x8000007eL, 0x8000007fL),
-                        StampTool.add(StampFactory.forInteger(Kind.Int, 0x7ffffffe, 0x7fffffff, 0x7ffffffeL, 0x7fffffffL), StampFactory.forInteger(Kind.Int, 128, 128)));
+    @Test
+    public void testAddOverFlowsLong() {
+        assertEquals(StampFactory.forKind(Kind.Long), StampTool.add(StampFactory.forInteger(Kind.Long, -1, 1), StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MAX_VALUE)));
+    }
+
+    @Test
+    public void testAdd1() {
+        assertEquals(StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE + 1, 31 + (Integer.MIN_VALUE + 1)),
+                        StampTool.add(StampFactory.forInteger(Kind.Int, 0, 31), StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE + 1, Integer.MIN_VALUE + 1)));
+    }
 
-        assertEquals(StampFactory.forInteger(Kind.Long, -9223372036854775808L, 9223372036854775806L, 0, 0xfffffffffffffffeL),
-                        StampTool.add(StampFactory.forInteger(Kind.Long, -9223372036854775808L, 9223372036854775806L, 0, 0xfffffffffffffffeL),
-                                        StampFactory.forInteger(Kind.Long, -9223372036854775808L, 9223372036854775806L, 0, 0xfffffffffffffffeL)));
+    @Test
+    public void testAdd2() {
+        assertEquals(StampFactory.forInteger(Kind.Int, 0x8000_007e, 0x8000_007f, 0x8000_007eL, 0x8000_007fL),
+                        StampTool.add(StampFactory.forInteger(Kind.Int, 0x7fff_fffe, 0x7fff_ffff, 0x7fff_fffeL, 0x7ffff_fffL), StampFactory.forInteger(Kind.Int, 128, 128)));
+    }
+
+    @Test
+    public void testAdd3() {
+        assertEquals(StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MAX_VALUE - 1, 0, 0xffff_ffff_ffff_fffeL),
+                        StampTool.add(StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MAX_VALUE - 1, 0, 0xffff_ffff_ffff_fffeL),
+                                        StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MAX_VALUE - 1, 0, 0xffff_ffff_ffff_fffeL)));
+
     }
 
     @Test
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java	Tue Nov 05 18:59:03 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java	Tue Nov 05 19:00:51 2013 +0100
@@ -78,6 +78,11 @@
     }
 
     @Override
+    public boolean isDeleted() {
+        return false;
+    }
+
+    @Override
     public boolean isAlive() {
         return true;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java	Tue Nov 05 18:59:03 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java	Tue Nov 05 19:00:51 2013 +0100
@@ -42,7 +42,7 @@
     private final long upMask;
 
     public IntegerStamp(Kind kind) {
-        this(kind.getStackKind(), kind.getMinValue(), kind.getMaxValue(), 0, defaultMask(kind == Kind.Char ? kind : kind.getStackKind()));
+        this(kind.getStackKind(), kind.getMinValue(), kind.getMaxValue(), 0, defaultMask(isUnsignedKind(kind) ? kind : kind.getStackKind()));
     }
 
     public IntegerStamp(Kind kind, long lowerBound, long upperBound, long downMask, long upMask) {
@@ -262,4 +262,8 @@
         }
         return null;
     }
+
+    private static boolean isUnsignedKind(Kind kind) {
+        return kind == Kind.Char;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Tue Nov 05 18:59:03 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Tue Nov 05 19:00:51 2013 +0100
@@ -135,42 +135,39 @@
     }
 
     public static IntegerStamp add(IntegerStamp stamp1, IntegerStamp stamp2) {
-        try {
-            if (stamp1.isUnrestricted() || stamp2.isUnrestricted()) {
-                return (IntegerStamp) StampFactory.forKind(stamp1.kind());
-            }
-            Kind kind = stamp1.kind();
-            assert stamp1.kind() == stamp2.kind();
-            long defaultMask = IntegerStamp.defaultMask(kind);
-            long variableBits = (stamp1.downMask() ^ stamp1.upMask()) | (stamp2.downMask() ^ stamp2.upMask());
-            long variableBitsWithCarry = variableBits | (carryBits(stamp1.downMask(), stamp2.downMask()) ^ carryBits(stamp1.upMask(), stamp2.upMask()));
-            long newDownMask = (stamp1.downMask() + stamp2.downMask()) & ~variableBitsWithCarry;
-            long newUpMask = (stamp1.downMask() + stamp2.downMask()) | variableBitsWithCarry;
+        if (stamp1.isUnrestricted() || stamp2.isUnrestricted()) {
+            return (IntegerStamp) StampFactory.forKind(stamp1.kind());
+        }
+        Kind kind = stamp1.kind();
+        assert stamp1.kind() == stamp2.kind();
+        long defaultMask = IntegerStamp.defaultMask(kind);
+        long variableBits = (stamp1.downMask() ^ stamp1.upMask()) | (stamp2.downMask() ^ stamp2.upMask());
+        long variableBitsWithCarry = variableBits | (carryBits(stamp1.downMask(), stamp2.downMask()) ^ carryBits(stamp1.upMask(), stamp2.upMask()));
+        long newDownMask = (stamp1.downMask() + stamp2.downMask()) & ~variableBitsWithCarry;
+        long newUpMask = (stamp1.downMask() + stamp2.downMask()) | variableBitsWithCarry;
 
-            newDownMask &= defaultMask;
-            newUpMask &= defaultMask;
+        newDownMask &= defaultMask;
+        newUpMask &= defaultMask;
 
-            long lowerBound;
-            long upperBound;
-            boolean lowerOverflowsPositively = addOverflowsPositively(stamp1.lowerBound(), stamp2.lowerBound(), kind);
-            boolean upperOverflowsPositively = addOverflowsPositively(stamp1.upperBound(), stamp2.upperBound(), kind);
-            boolean lowerOverflowsNegatively = addOverflowsNegatively(stamp1.lowerBound(), stamp2.lowerBound(), kind);
-            boolean upperOverflowsNegatively = addOverflowsNegatively(stamp1.upperBound(), stamp2.upperBound(), kind);
-            if ((lowerOverflowsNegatively && !upperOverflowsNegatively) || (!lowerOverflowsNegatively && !lowerOverflowsPositively && upperOverflowsPositively)) {
-                lowerBound = kind.getMinValue();
-                upperBound = kind.getMaxValue();
-            } else {
-                lowerBound = signExtend(stamp1.lowerBound() + stamp2.lowerBound(), kind);
-                upperBound = signExtend(stamp1.upperBound() + stamp2.upperBound(), kind);
-            }
-            IntegerStamp limit = StampFactory.forInteger(kind, lowerBound, upperBound);
-            newUpMask &= limit.upMask();
-            upperBound = signExtend(upperBound & newUpMask, kind);
-            lowerBound |= newDownMask;
-            return new IntegerStamp(kind, lowerBound, upperBound, newDownMask, newUpMask);
-        } catch (Throwable e) {
-            throw new RuntimeException(stamp1 + " + " + stamp2, e);
+        long lowerBound;
+        long upperBound;
+        boolean lowerOverflowsPositively = addOverflowsPositively(stamp1.lowerBound(), stamp2.lowerBound(), kind);
+        boolean upperOverflowsPositively = addOverflowsPositively(stamp1.upperBound(), stamp2.upperBound(), kind);
+        boolean lowerOverflowsNegatively = addOverflowsNegatively(stamp1.lowerBound(), stamp2.lowerBound(), kind);
+        boolean upperOverflowsNegatively = addOverflowsNegatively(stamp1.upperBound(), stamp2.upperBound(), kind);
+        if ((lowerOverflowsNegatively && !upperOverflowsNegatively) || (!lowerOverflowsPositively && upperOverflowsPositively)) {
+            lowerBound = kind.getMinValue();
+            upperBound = kind.getMaxValue();
+        } else {
+            lowerBound = signExtend((stamp1.lowerBound() + stamp2.lowerBound()) & defaultMask, kind);
+            upperBound = signExtend((stamp1.upperBound() + stamp2.upperBound()) & defaultMask, kind);
         }
+        IntegerStamp limit = StampFactory.forInteger(kind, lowerBound, upperBound);
+        newUpMask &= limit.upMask();
+        upperBound = signExtend(upperBound & newUpMask, kind);
+        newDownMask |= limit.downMask();
+        lowerBound |= newDownMask;
+        return new IntegerStamp(kind, lowerBound, upperBound, newDownMask, newUpMask);
     }
 
     public static Stamp sub(IntegerStamp stamp1, IntegerStamp stamp2) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Tue Nov 05 18:59:03 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Tue Nov 05 19:00:51 2013 +0100
@@ -314,26 +314,67 @@
             }
         } while (v != null);
 
-        // if the simple check fails (this can happen for complicated phi/proxy/phi constructs), we
-        // do an exhaustive search
         if (v == null) {
+            v = new OriginalValueSearch(proxy).result;
+        }
+        return v;
+    }
+
+    /**
+     * Exhaustive search for {@link GraphUtil#originalValue(ValueNode)} when a simple search fails.
+     * This can happen in the presence of complicated phi/proxy/phi constructs.
+     */
+    static class OriginalValueSearch {
+        ValueNode result;
+
+        public OriginalValueSearch(ValueNode proxy) {
             NodeWorkList worklist = proxy.graph().createNodeWorkList();
             worklist.add(proxy);
             for (Node node : worklist) {
                 if (node instanceof ValueProxy) {
-                    worklist.add(((ValueProxy) node).getOriginalValue());
+                    ValueNode originalValue = ((ValueProxy) node).getOriginalValue();
+                    if (!process(originalValue, worklist)) {
+                        return;
+                    }
                 } else if (node instanceof PhiNode) {
-                    worklist.addAll(((PhiNode) node).values());
+                    for (Node value : ((PhiNode) node).values()) {
+                        if (!process((ValueNode) value, worklist)) {
+                            return;
+                        }
+                    }
                 } else {
-                    if (v == null) {
-                        v = (ValueNode) node;
-                    } else {
-                        return null;
+                    if (!process((ValueNode) node, null)) {
+                        return;
                     }
                 }
             }
         }
-        return v;
+
+        /**
+         * Process a node as part of this search.
+         * 
+         * @param node the next node encountered in the search
+         * @param worklist if non-null and {@code node} is not external, {@code node} will be added
+         *            to this list. Otherwise, {@code node} is treated as a candidate result.
+         * @return true if the search should continue, false if a definitive {@link #result} has
+         *         been found
+         */
+        private boolean process(ValueNode node, NodeWorkList worklist) {
+            if (node.isAlive()) {
+                if (node.isExternal() || worklist == null) {
+                    if (result == null) {
+                        // Initial candidate result: continue search
+                        result = node;
+                    } else if (result != node) {
+                        // Conflicts with existing candidate: stop search with null result
+                        result = null;
+                        return false;
+                    }
+                } else {
+                    worklist.add(node);
+                }
+            }
+            return true;
+        }
     }
-
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.options.test/src/com/oracle/graal/options/test/TestOptionValue.java	Tue Nov 05 19:00:51 2013 +0100
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2013, 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.options.test;
+
+import static com.oracle.graal.options.test.TestOptionValue.Options.*;
+import static org.junit.Assert.*;
+
+import org.junit.*;
+
+import com.oracle.graal.options.*;
+import com.oracle.graal.options.OptionValue.OverrideScope;
+
+public class TestOptionValue {
+
+    public static class Options {
+        public static final OptionValue<Boolean> Stable = new StableOptionValue<>(true);
+        public static final OptionValue<String> Mutable = new OptionValue<>("original");
+        public static final OptionValue<String> SecondMutable = new OptionValue<>("second");
+    }
+
+    static final OptionDescriptor stable = new OptionDescriptor("Stable", Boolean.class, "", Options.class, "Stable", Stable);
+    static final OptionDescriptor mutable = new OptionDescriptor("Mutable", String.class, "", Options.class, "Mutable", Mutable);
+    static final OptionDescriptor secondMutable = new OptionDescriptor("SecondMutable", String.class, "", Options.class, "SecondMutable", SecondMutable);
+
+    @Test
+    public void testMutable() {
+        assertEquals("original", Mutable.getValue());
+        try (OverrideScope s1 = OptionValue.override(Mutable, "override1")) {
+            assertEquals("override1", Mutable.getValue());
+            try (OverrideScope s2 = OptionValue.override(Mutable, "override2")) {
+                assertEquals("override2", Mutable.getValue());
+            }
+            assertEquals("override1", Mutable.getValue());
+            try (OverrideScope s3 = OptionValue.override(Mutable, "override3")) {
+                assertEquals("override3", Mutable.getValue());
+            }
+            assertEquals("override1", Mutable.getValue());
+        }
+        assertEquals("original", Mutable.getValue());
+        try (OverrideScope s1 = OptionValue.override(Mutable, "original")) {
+            assertEquals("original", Mutable.getValue());
+        }
+    }
+
+    @Test
+    public void testMultiple() {
+        assertEquals("original", Mutable.getValue());
+        assertEquals("second", SecondMutable.getValue());
+        try (OverrideScope s1 = OptionValue.override(Mutable, "override1", SecondMutable, "secondOverride1")) {
+            assertEquals("override1", Mutable.getValue());
+            assertEquals("secondOverride1", SecondMutable.getValue());
+            try (OverrideScope s2 = OptionValue.override(Mutable, "override2", SecondMutable, "secondOverride2")) {
+                assertEquals("override2", Mutable.getValue());
+                assertEquals("secondOverride2", SecondMutable.getValue());
+            }
+            assertEquals("override1", Mutable.getValue());
+            assertEquals("secondOverride1", SecondMutable.getValue());
+            try (OverrideScope s3 = OptionValue.override(Mutable, "override3", SecondMutable, "secondOverride3")) {
+                assertEquals("override3", Mutable.getValue());
+                assertEquals("secondOverride3", SecondMutable.getValue());
+            }
+            assertEquals("override1", Mutable.getValue());
+            assertEquals("secondOverride1", SecondMutable.getValue());
+        }
+        assertEquals("original", Mutable.getValue());
+        assertEquals("second", SecondMutable.getValue());
+        try (OverrideScope s1 = OptionValue.override(Mutable, "original", SecondMutable, "second")) {
+            assertEquals("original", Mutable.getValue());
+            assertEquals("second", SecondMutable.getValue());
+        }
+    }
+
+    @Test
+    public void testStable() {
+        assertTrue(Stable.getValue());
+        try (OverrideScope s = OptionValue.override(Stable, false)) {
+            fail("cannot override stable option");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+}
--- a/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionDescriptor.java	Tue Nov 05 18:59:03 2013 +0100
+++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionDescriptor.java	Tue Nov 05 19:00:51 2013 +0100
@@ -42,6 +42,7 @@
         this.option = option;
         this.declaringClass = declaringClass;
         this.fieldName = fieldName;
+        option.setDescriptor(this);
     }
 
     /**
--- a/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionValue.java	Tue Nov 05 18:59:03 2013 +0100
+++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionValue.java	Tue Nov 05 19:00:51 2013 +0100
@@ -22,16 +22,120 @@
  */
 package com.oracle.graal.options;
 
+import java.util.*;
+import java.util.Map.Entry;
+
 /**
  * An option value.
  */
 public class OptionValue<T> {
 
     /**
+     * Temporarily changes the value for an option. The {@linkplain OptionValue#getValue() value} of
+     * {@code option} is set to {@code value} until {@link OverrideScope#close()} is called on the
+     * object returned by this method.
+     * <p>
+     * Since the returned object is {@link AutoCloseable} the try-with-resource construct can be
+     * used:
+     * 
+     * <pre>
+     * try (OverrideScope s = OptionValue.override(myOption, myValue) {
+     *     // code that depends on myOption == myValue
+     * }
+     * </pre>
+     */
+    public static OverrideScope override(OptionValue<?> option, Object value) {
+        OverrideScope current = overrideScopes.get();
+        if (current == null) {
+            if (!value.equals(option.getValue())) {
+                return new SingleOverrideScope(option, value);
+            }
+            Map<OptionValue<?>, Object> overrides = Collections.emptyMap();
+            return new MultipleOverridesScope(current, overrides);
+        }
+        return new MultipleOverridesScope(current, option, value);
+    }
+
+    /**
+     * Temporarily changes the values for a set of options. The {@linkplain OptionValue#getValue()
+     * value} of each {@code option} in {@code overrides} is set to the corresponding {@code value}
+     * in {@code overrides} until {@link OverrideScope#close()} is called on the object returned by
+     * this method.
+     * <p>
+     * Since the returned object is {@link AutoCloseable} the try-with-resource construct can be
+     * used:
+     * 
+     * <pre>
+     * Map<OptionValue, Object> overrides = new HashMap<>();
+     * overrides.put(myOption1, myValue1);
+     * overrides.put(myOption2, myValue2);
+     * try (OverrideScope s = OptionValue.override(overrides) {
+     *     // code that depends on myOption == myValue
+     * }
+     * </pre>
+     */
+    public static OverrideScope override(Map<OptionValue<?>, Object> overrides) {
+        OverrideScope current = overrideScopes.get();
+        if (current == null && overrides.size() == 1) {
+            Entry<OptionValue<?>, Object> single = overrides.entrySet().iterator().next();
+            OptionValue<?> option = single.getKey();
+            Object overrideValue = single.getValue();
+            if (!overrideValue.equals(option.getValue())) {
+                return new SingleOverrideScope(option, overrideValue);
+            }
+        }
+        return new MultipleOverridesScope(current, overrides);
+    }
+
+    /**
+     * Temporarily changes the values for a set of options. The {@linkplain OptionValue#getValue()
+     * value} of each {@code option} in {@code overrides} is set to the corresponding {@code value}
+     * in {@code overrides} until {@link OverrideScope#close()} is called on the object returned by
+     * this method.
+     * <p>
+     * Since the returned object is {@link AutoCloseable} the try-with-resource construct can be
+     * used:
+     * 
+     * <pre>
+     * try (OverrideScope s = OptionValue.override(myOption1, myValue1, myOption2, myValue2) {
+     *     // code that depends on myOption == myValue
+     * }
+     * </pre>
+     * 
+     * @param overrides overrides in the form {@code [option1, override1, option2, override2, ...]}
+     */
+    public static OverrideScope override(Object... overrides) {
+        OverrideScope current = overrideScopes.get();
+        if (current == null && overrides.length == 2) {
+            OptionValue<?> option = (OptionValue<?>) overrides[0];
+            Object overrideValue = overrides[1];
+            if (!overrideValue.equals(option.getValue())) {
+                return new SingleOverrideScope(option, overrideValue);
+            }
+        }
+        Map<OptionValue<?>, Object> map = Collections.emptyMap();
+        for (int i = 0; i < overrides.length; i += 2) {
+            OptionValue<?> option = (OptionValue<?>) overrides[i];
+            Object overrideValue = overrides[i + 1];
+            if (!overrideValue.equals(option.getValue())) {
+                if (map.isEmpty()) {
+                    map = new HashMap<>();
+                }
+                map.put(option, overrideValue);
+            }
+        }
+        return new MultipleOverridesScope(current, map);
+    }
+
+    private static ThreadLocal<OverrideScope> overrideScopes = new ThreadLocal<>();
+
+    /**
      * The raw option value.
      */
     protected T value;
 
+    private OptionDescriptor descriptor;
+
     public OptionValue(T value) {
         this.value = value;
     }
@@ -55,9 +159,38 @@
     }
 
     /**
+     * Sets the descriptor for this option.
+     */
+    public void setDescriptor(OptionDescriptor descriptor) {
+        this.descriptor = descriptor;
+    }
+
+    /**
+     * Gets the name of this option. The name for an option value with a null
+     * {@linkplain #setDescriptor(OptionDescriptor) descriptor} is {@code "<anonymous>"}.
+     */
+    public String getName() {
+        return descriptor == null ? "<anonymous>" : (descriptor.getDeclaringClass().getName() + "." + descriptor.getName());
+    }
+
+    @Override
+    public String toString() {
+        return getName() + "=" + value;
+    }
+
+    /**
      * Gets the value of this option.
      */
     public T getValue() {
+        if (!(this instanceof StableOptionValue)) {
+            OverrideScope overrideScope = overrideScopes.get();
+            if (overrideScope != null) {
+                T override = overrideScope.getOverride(this);
+                if (override != null) {
+                    return override;
+                }
+            }
+        }
         if (value == UNINITIALIZED) {
             value = initialValue();
         }
@@ -71,4 +204,117 @@
     public void setValue(Object v) {
         this.value = (T) v;
     }
+
+    /**
+     * An object whose {@link #close()} method reverts the option value overriding initiated by
+     * {@link OptionValue#override(OptionValue, Object)} or {@link OptionValue#override(Map)}.
+     */
+    public abstract static class OverrideScope implements AutoCloseable {
+        abstract void addToInherited(Map<OptionValue, Object> inherited);
+
+        abstract <T> T getOverride(OptionValue<T> option);
+
+        public abstract void close();
+    }
+
+    static class SingleOverrideScope extends OverrideScope {
+
+        private final OptionValue<?> option;
+        private final Object value;
+
+        public SingleOverrideScope(OptionValue<?> option, Object value) {
+            if (option instanceof StableOptionValue) {
+                throw new IllegalArgumentException("Cannot override stable option " + option);
+            }
+            this.option = option;
+            this.value = value;
+            overrideScopes.set(this);
+        }
+
+        @Override
+        void addToInherited(Map<OptionValue, Object> inherited) {
+            inherited.put(option, value);
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        <T> T getOverride(OptionValue<T> key) {
+            if (key == this.option) {
+                return (T) value;
+            }
+            return null;
+        }
+
+        @Override
+        public void close() {
+            overrideScopes.set(null);
+        }
+    }
+
+    static class MultipleOverridesScope extends OverrideScope {
+        final OverrideScope parent;
+        final Map<OptionValue, Object> overrides;
+
+        public MultipleOverridesScope(OverrideScope parent, OptionValue<?> option, Object value) {
+            this.parent = parent;
+            this.overrides = new HashMap<>();
+            if (parent != null) {
+                parent.addToInherited(overrides);
+            }
+            if (option instanceof StableOptionValue) {
+                throw new IllegalArgumentException("Cannot override stable option " + option);
+            }
+            if (!value.equals(option.getValue())) {
+                this.overrides.put(option, value);
+            }
+            if (!overrides.isEmpty()) {
+                overrideScopes.set(this);
+            }
+        }
+
+        MultipleOverridesScope(OverrideScope parent, Map<OptionValue<?>, Object> overrides) {
+            this.parent = parent;
+            if (overrides.isEmpty() && parent == null) {
+                this.overrides = Collections.emptyMap();
+                return;
+            }
+            this.overrides = new HashMap<>();
+            if (parent != null) {
+                parent.addToInherited(this.overrides);
+            }
+            for (Map.Entry<OptionValue<?>, Object> e : overrides.entrySet()) {
+                OptionValue<?> option = e.getKey();
+                if (option instanceof StableOptionValue) {
+                    throw new IllegalArgumentException("Cannot override stable option " + option);
+                }
+                if (!e.getValue().equals(option.getValue())) {
+                    this.overrides.put(option, e.getValue());
+                }
+            }
+            if (!this.overrides.isEmpty()) {
+                overrideScopes.set(this);
+            }
+        }
+
+        @Override
+        void addToInherited(Map<OptionValue, Object> inherited) {
+            if (parent != null) {
+                parent.addToInherited(inherited);
+            }
+            inherited.putAll(overrides);
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        <T> T getOverride(OptionValue<T> option) {
+            return (T) overrides.get(option);
+        }
+
+        @Override
+        public void close() {
+            if (!overrides.isEmpty()) {
+                overrideScopes.set(parent);
+            }
+        }
+    }
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java	Tue Nov 05 18:59:03 2013 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java	Tue Nov 05 19:00:51 2013 +0100
@@ -451,31 +451,44 @@
         return null;
     }
 
-    @SuppressWarnings("unchecked")
-    public static <T extends Node> T findParent(final Node start, final Class<T> clazz) {
-        assert start != null;
-        if (clazz.isInstance(start.getParent())) {
-            return (T) start.getParent();
+    public static <T> T findParent(Node start, Class<T> clazz) {
+        Node parent = start.getParent();
+        if (parent == null) {
+            return null;
+        } else if (clazz.isInstance(parent)) {
+            return clazz.cast(parent);
         } else {
-            return start.getParent() != null ? findParent(start.getParent(), clazz) : null;
+            return findParent(parent, clazz);
         }
     }
 
-    @SuppressWarnings("unchecked")
-    public static <I> I findParentInterface(final Node start, final Class<I> clazz) {
-        assert start != null;
-        if (clazz.isInstance(start.getParent())) {
-            return (I) start.getParent();
-        } else {
-            return (start.getParent() != null ? findParentInterface(start.getParent(), clazz) : null);
+    public static <T> List<T> findAllParents(Node start, Class<T> clazz) {
+        List<T> parents = new ArrayList<>();
+        T parent = findParent(start, clazz);
+        while (parent != null) {
+            parents.add(parent);
+            parent = findParent((Node) parent, clazz);
         }
+        return parents;
     }
 
-    @SuppressWarnings("unchecked")
+    public static List<Node> collectNodes(Node parent, Node child) {
+        List<Node> nodes = new ArrayList<>();
+        Node current = child;
+        while (current != null) {
+            nodes.add(current);
+            if (current == parent) {
+                return nodes;
+            }
+            current = current.getParent();
+        }
+        throw new IllegalArgumentException("Node " + parent + " is not a parent of " + child + ".");
+    }
+
     public static <T> T findFirstNodeInstance(Node root, Class<T> clazz) {
         for (Node childNode : findNodeChildren(root)) {
             if (clazz.isInstance(childNode)) {
-                return (T) childNode;
+                return clazz.cast(childNode);
             } else {
                 T node = findFirstNodeInstance(childNode, clazz);
                 if (node != null) {
--- a/mx/projects	Tue Nov 05 18:59:03 2013 +0100
+++ b/mx/projects	Tue Nov 05 19:00:51 2013 +0100
@@ -154,7 +154,7 @@
 # graal.hotspot.hsail
 project@com.oracle.graal.hotspot.hsail@subDir=graal
 project@com.oracle.graal.hotspot.hsail@sourceDirs=src
-project@com.oracle.graal.hotspot.hsail@dependencies=com.oracle.graal.hotspot,com.oracle.graal.compiler.hsail
+project@com.oracle.graal.hotspot.hsail@dependencies=com.oracle.graal.compiler.hsail,com.oracle.graal.hotspot
 project@com.oracle.graal.hotspot.hsail@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.hotspot.hsail@annotationProcessors=com.oracle.graal.service.processor
 project@com.oracle.graal.hotspot.hsail@javaCompliance=1.7
@@ -200,6 +200,14 @@
 project@com.oracle.graal.options@annotationProcessorForDependents=true
 project@com.oracle.graal.options@workingSets=Graal,Codegen
 
+# graal.options.test
+project@com.oracle.graal.options.test@subDir=graal
+project@com.oracle.graal.options.test@sourceDirs=src
+project@com.oracle.graal.options.test@dependencies=com.oracle.graal.options,JUNIT
+project@com.oracle.graal.options.test@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.options.test@javaCompliance=1.7
+project@com.oracle.graal.options.test@workingSets=Graal
+
 # graal.graph
 project@com.oracle.graal.graph@subDir=graal
 project@com.oracle.graal.graph@sourceDirs=src
--- a/mxtool/mx.py	Tue Nov 05 18:59:03 2013 +0100
+++ b/mxtool/mx.py	Tue Nov 05 19:00:51 2013 +0100
@@ -25,7 +25,6 @@
 #
 # ----------------------------------------------------------------------------------------------------
 #
-
 r"""
 mx is a command line tool for managing the development of Java code organized as suites of projects.
 
@@ -2981,13 +2980,18 @@
                 out.element('arguments', data='')
                 out.close('buildCommand')
 
+        # The path should always be p.name/dir. independent of where the workspace actually is.
+        # So we use the parent folder of the project, whatever that is, to generate such a relative path.
+        logicalWorkspaceRoot = os.path.dirname(p.dir)
+        binFolder = os.path.relpath(p.output_dir(), logicalWorkspaceRoot) 
+        
         if _isAnnotationProcessorDependency(p):
-            _genEclipseBuilder(out, p, 'Jar', 'archive ' + p.name, refresh=False, async=False, xmlIndent='', xmlStandalone='no')
-            _genEclipseBuilder(out, p, 'Refresh', '', refresh=True, async=True)
+            refreshFile = os.path.relpath(join(p.dir, p.name + '.jar'),  logicalWorkspaceRoot)
+            _genEclipseBuilder(out, p, 'Jar', 'archive ' + p.name, refresh=True, refreshFile=refreshFile, relevantResources=[binFolder], async=True, xmlIndent='', xmlStandalone='no')
 
         if projToDist.has_key(p.name):
             dist, distDeps = projToDist[p.name]
-            _genEclipseBuilder(out, p, 'Create' + dist.name + 'Dist', 'archive @' + dist.name, logToFile=True, refresh=False, async=True)
+            _genEclipseBuilder(out, p, 'Create' + dist.name + 'Dist', 'archive @' + dist.name, relevantResources=[binFolder], logToFile=True, refresh=False, async=True)
 
         out.close('buildSpec')
         out.open('natures')
@@ -3049,7 +3053,7 @@
     """
     return p in sorted_deps(annotation_processors())
 
-def _genEclipseBuilder(dotProjectDoc, p, name, mxCommand, refresh=True, async=False, logToConsole=False, logToFile=False, appendToLogFile=True, xmlIndent='\t', xmlStandalone=None):
+def _genEclipseBuilder(dotProjectDoc, p, name, mxCommand, refresh=True, refreshFile=None, relevantResources=None, async=False, logToConsole=False, logToFile=False, appendToLogFile=True, xmlIndent='\t', xmlStandalone=None):
     externalToolDir = join(p.dir, '.externalToolBuilders')
     launchOut = XMLDoc()
     consoleOn = 'true' if logToConsole else 'false'
@@ -3060,7 +3064,22 @@
     launchOut.close('mapAttribute')
 
     if refresh:
-        launchOut.element('stringAttribute', {'key' : 'org.eclipse.debug.core.ATTR_REFRESH_SCOPE', 'value': '${project}'})
+        if refreshFile is None:
+            refreshScope = '${project}'
+        else:
+            refreshScope = '${working_set:<?xml version="1.0" encoding="UTF-8"?><resources><item path="' + refreshFile + '" type="1"/></resources>}'
+        
+        launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.core.ATTR_REFRESH_RECURSIVE', 'value':  'false'})  
+        launchOut.element('stringAttribute', {'key' : 'org.eclipse.debug.core.ATTR_REFRESH_SCOPE', 'value':  refreshScope})
+
+    if relevantResources is not None:
+        resources = '${working_set:<?xml version="1.0" encoding="UTF-8"?><resources>'
+        for relevantResource in relevantResources:
+            resources += '<item path="' + relevantResource +'" type="2" />'
+        resources += '</resources>}'
+        launchOut.element('stringAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_BUILD_SCOPE', 'value': resources})
+        
+    
     launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.ui.ATTR_CONSOLE_OUTPUT_ON', 'value': consoleOn})
     launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND', 'value': 'true' if async else 'false'})
     if logToFile:
@@ -3082,7 +3101,7 @@
             abort('cannot locate ' + cmd)
 
     launchOut.element('stringAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_LOCATION', 'value':  cmdPath})
-    launchOut.element('stringAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS', 'value': 'auto,full,incremental'})
+    launchOut.element('stringAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS', 'value': 'full,incremental,auto,'})
     launchOut.element('stringAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS', 'value': mxCommand})
     launchOut.element('booleanAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED', 'value': 'true'})
     launchOut.element('stringAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY', 'value': p.suite.dir})
--- a/src/share/vm/code/nmethod.cpp	Tue Nov 05 18:59:03 2013 +0100
+++ b/src/share/vm/code/nmethod.cpp	Tue Nov 05 19:00:51 2013 +0100
@@ -129,8 +129,7 @@
 
 // These variables are put into one block to reduce relocations
 // and make it simpler to print from the debugger.
-static
-struct nmethod_stats_struct {
+struct java_nmethod_stats_struct {
   int nmethod_count;
   int total_size;
   int relocation_size;
@@ -158,9 +157,9 @@
     handler_table_size  += nm->handler_table_size();
     nul_chk_table_size  += nm->nul_chk_table_size();
   }
-  void print_nmethod_stats() {
+  void print_nmethod_stats(const char* name) {
     if (nmethod_count == 0)  return;
-    tty->print_cr("Statistics for %d bytecoded nmethods:", nmethod_count);
+    tty->print_cr("Statistics for %d bytecoded nmethods for %s:", nmethod_count, name);
     if (total_size != 0)          tty->print_cr(" total in heap  = %d", total_size);
     if (relocation_size != 0)     tty->print_cr(" relocation     = %d", relocation_size);
     if (consts_size != 0)         tty->print_cr(" constants      = %d", consts_size);
@@ -173,7 +172,9 @@
     if (handler_table_size != 0)  tty->print_cr(" handler table  = %d", handler_table_size);
     if (nul_chk_table_size != 0)  tty->print_cr(" nul chk table  = %d", nul_chk_table_size);
   }
-
+};
+
+struct native_nmethod_stats_struct {
   int native_nmethod_count;
   int native_total_size;
   int native_relocation_size;
@@ -194,7 +195,9 @@
     if (native_insts_size != 0)       tty->print_cr(" N. main code   = %d", native_insts_size);
     if (native_oops_size != 0)        tty->print_cr(" N. oops        = %d", native_oops_size);
   }
-
+};
+
+struct pc_nmethod_stats_struct {
   int pc_desc_resets;   // number of resets (= number of caches)
   int pc_desc_queries;  // queries to nmethod::find_pc_desc
   int pc_desc_approx;   // number of those which have approximate true
@@ -215,7 +218,38 @@
                   pc_desc_repeats, pc_desc_hits,
                   pc_desc_tests, pc_desc_searches, pc_desc_adds);
   }
-} nmethod_stats;
+};
+
+#ifdef COMPILER1
+static java_nmethod_stats_struct c1_java_nmethod_stats;
+#endif
+#ifdef COMPILER2
+static java_nmethod_stats_struct c2_java_nmethod_stats;
+#endif
+#ifdef GRAAL
+static java_nmethod_stats_struct graal_java_nmethod_stats;
+#endif
+
+static native_nmethod_stats_struct native_nmethod_stats;
+static pc_nmethod_stats_struct pc_nmethod_stats;
+
+static void note_java_nmethod(nmethod* nm) {
+#ifdef COMPILER1
+  if (nm->is_compiled_by_c1()) {
+    c1_java_nmethod_stats.note_nmethod(nm);
+  }
+#endif
+#ifdef COMPILER2
+  if (nm->is_compiled_by_c2()) {
+    c2_java_nmethod_stats.note_nmethod(nm);
+  }
+#endif
+#ifdef GRAAL
+  if (nm->is_compiled_by_graal()) {
+    graal_java_nmethod_stats.note_nmethod(nm);
+  }
+#endif
+}
 
 
 //---------------------------------------------------------------------------------
@@ -296,7 +330,7 @@
 
 // Helper used by both find_pc_desc methods.
 static inline bool match_desc(PcDesc* pc, int pc_offset, bool approximate) {
-  NOT_PRODUCT(++nmethod_stats.pc_desc_tests);
+  NOT_PRODUCT(++pc_nmethod_stats.pc_desc_tests);
   if (!approximate)
     return pc->pc_offset() == pc_offset;
   else
@@ -308,7 +342,7 @@
     _pc_descs[0] = NULL; // native method; no PcDescs at all
     return;
   }
-  NOT_PRODUCT(++nmethod_stats.pc_desc_resets);
+  NOT_PRODUCT(++pc_nmethod_stats.pc_desc_resets);
   // reset the cache by filling it with benign (non-null) values
   assert(initial_pc_desc->pc_offset() < 0, "must be sentinel");
   for (int i = 0; i < cache_size; i++)
@@ -316,8 +350,8 @@
 }
 
 PcDesc* PcDescCache::find_pc_desc(int pc_offset, bool approximate) {
-  NOT_PRODUCT(++nmethod_stats.pc_desc_queries);
-  NOT_PRODUCT(if (approximate) ++nmethod_stats.pc_desc_approx);
+  NOT_PRODUCT(++pc_nmethod_stats.pc_desc_queries);
+  NOT_PRODUCT(if (approximate) ++pc_nmethod_stats.pc_desc_approx);
 
   // Note: one might think that caching the most recently
   // read value separately would be a win, but one would be
@@ -333,7 +367,7 @@
   res = _pc_descs[0];
   if (res == NULL) return NULL;  // native method; no PcDescs at all
   if (match_desc(res, pc_offset, approximate)) {
-    NOT_PRODUCT(++nmethod_stats.pc_desc_repeats);
+    NOT_PRODUCT(++pc_nmethod_stats.pc_desc_repeats);
     return res;
   }
 
@@ -342,7 +376,7 @@
     res = _pc_descs[i];
     if (res->pc_offset() < 0) break;  // optimization: skip empty cache
     if (match_desc(res, pc_offset, approximate)) {
-      NOT_PRODUCT(++nmethod_stats.pc_desc_hits);
+      NOT_PRODUCT(++pc_nmethod_stats.pc_desc_hits);
       return res;
     }
   }
@@ -352,7 +386,7 @@
 }
 
 void PcDescCache::add_pc_desc(PcDesc* pc_desc) {
-  NOT_PRODUCT(++nmethod_stats.pc_desc_adds);
+  NOT_PRODUCT(++pc_nmethod_stats.pc_desc_adds);
   // Update the LRU cache by shifting pc_desc forward.
   for (int i = 0; i < cache_size; i++)  {
     PcDesc* next = _pc_descs[i];
@@ -519,7 +553,7 @@
                                             code_buffer, frame_size,
                                             basic_lock_owner_sp_offset,
                                             basic_lock_sp_offset, oop_maps);
-    if (nm != NULL)  nmethod_stats.note_native_nmethod(nm);
+    if (nm != NULL)  native_nmethod_stats.note_native_nmethod(nm);
     if (PrintAssembly && nm != NULL) {
       Disassembler::decode(nm);
     }
@@ -555,7 +589,7 @@
     nm = new (nmethod_size) nmethod(method(), nmethod_size,
                                     &offsets, code_buffer, frame_size);
 
-    if (nm != NULL)  nmethod_stats.note_nmethod(nm);
+    if (nm != NULL)  note_java_nmethod(nm);
     if (PrintAssembly && nm != NULL) {
       Disassembler::decode(nm);
     }
@@ -640,7 +674,7 @@
         InstanceKlass::cast(klass)->add_dependent_nmethod(nm);
       }
     }
-    if (nm != NULL)  nmethod_stats.note_nmethod(nm);
+    if (nm != NULL)  note_java_nmethod(nm);
     if (PrintAssembly && nm != NULL) {
       Disassembler::decode(nm);
     }
@@ -2168,7 +2202,7 @@
   lower += 1; // exclude initial sentinel
   PcDesc* res = NULL;
   for (PcDesc* p = lower; p < upper; p++) {
-    NOT_PRODUCT(--nmethod_stats.pc_desc_tests);  // don't count this call to match_desc
+    NOT_PRODUCT(--pc_nmethod_stats.pc_desc_tests);  // don't count this call to match_desc
     if (match_desc(p, pc_offset, approximate)) {
       if (res == NULL)
         res = p;
@@ -2215,7 +2249,7 @@
 
   // Use the last successful return as a split point.
   PcDesc* mid = _pc_desc_cache.last_pc_desc();
-  NOT_PRODUCT(++nmethod_stats.pc_desc_searches);
+  NOT_PRODUCT(++pc_nmethod_stats.pc_desc_searches);
   if (mid->pc_offset() < pc_offset) {
     lower = mid;
   } else {
@@ -2228,7 +2262,7 @@
   for (int step = (1 << (LOG2_RADIX*3)); step > 1; step >>= LOG2_RADIX) {
     while ((mid = lower + step) < upper) {
       assert_LU_OK;
-      NOT_PRODUCT(++nmethod_stats.pc_desc_searches);
+      NOT_PRODUCT(++pc_nmethod_stats.pc_desc_searches);
       if (mid->pc_offset() < pc_offset) {
         lower = mid;
       } else {
@@ -2243,7 +2277,7 @@
   while (true) {
     assert_LU_OK;
     mid = lower + 1;
-    NOT_PRODUCT(++nmethod_stats.pc_desc_searches);
+    NOT_PRODUCT(++pc_nmethod_stats.pc_desc_searches);
     if (mid->pc_offset() < pc_offset) {
       lower = mid;
     } else {
@@ -3043,10 +3077,18 @@
 void nmethod::print_statistics() {
   ttyLocker ttyl;
   if (xtty != NULL)  xtty->head("statistics type='nmethod'");
-  nmethod_stats.print_native_nmethod_stats();
-  nmethod_stats.print_nmethod_stats();
+  native_nmethod_stats.print_native_nmethod_stats();
+#ifdef COMPILER1
+  c1_java_nmethod_stats.print_nmethod_stats("C1");
+#endif
+#ifdef COMPILER2
+  c2_java_nmethod_stats.print_nmethod_stats("C2");
+#endif
+#ifdef GRAAL
+  graal_java_nmethod_stats.print_nmethod_stats("Graal");
+#endif
   DebugInformationRecorder::print_statistics();
-  nmethod_stats.print_pc_stats();
+  pc_nmethod_stats.print_pc_stats();
   Dependencies::print_statistics();
   if (xtty != NULL)  xtty->tail("statistics");
 }
--- a/src/share/vm/graal/graalRuntime.cpp	Tue Nov 05 18:59:03 2013 +0100
+++ b/src/share/vm/graal/graalRuntime.cpp	Tue Nov 05 19:00:51 2013 +0100
@@ -299,13 +299,17 @@
 }
 
 JRT_ENTRY(void, GraalRuntime::create_null_exception(JavaThread* thread))
-  thread->set_vm_result(Exceptions::new_exception(thread, vmSymbols::java_lang_NullPointerException(), NULL)());
+  SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_NullPointerException());
+  thread->set_vm_result(PENDING_EXCEPTION);
+  CLEAR_PENDING_EXCEPTION;
 JRT_END
 
 JRT_ENTRY(void, GraalRuntime::create_out_of_bounds_exception(JavaThread* thread, jint index))
   char message[jintAsStringSize];
   sprintf(message, "%d", index);
-  thread->set_vm_result(Exceptions::new_exception(thread, vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), message)());
+  SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), message);
+  thread->set_vm_result(PENDING_EXCEPTION);
+  CLEAR_PENDING_EXCEPTION;
 JRT_END
 
 JRT_ENTRY_NO_ASYNC(void, GraalRuntime::monitorenter(JavaThread* thread, oopDesc* obj, BasicLock* lock))