# HG changeset patch # User Christos Kotselidis # Date 1383674451 -3600 # Node ID 3affe68ddb50dbc5a9f014d00aafec278a87b45a # Parent 944e31d1b427b6063c38b0f001f7118e677031e1# Parent e53aa17b8fdf097c2bd509d281b391db00dfe270 Merge diff -r 944e31d1b427 -r 3affe68ddb50 graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/KernelTester.java --- 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() { diff -r 944e31d1b427 -r 3affe68ddb50 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/FloatSqrtTest.java --- 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 diff -r 944e31d1b427 -r 3affe68ddb50 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticNBodySpillTest.java --- 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(); diff -r 944e31d1b427 -r 3affe68ddb50 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticNBodyTest.java --- 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(); diff -r 944e31d1b427 -r 3affe68ddb50 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StringContainsTest.java --- 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(); } diff -r 944e31d1b427 -r 3affe68ddb50 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StringIndexOfTest.java --- 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(); } diff -r 944e31d1b427 -r 3affe68ddb50 graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java --- 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)); diff -r 944e31d1b427 -r 3affe68ddb50 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java --- 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 { diff -r 944e31d1b427 -r 3affe68ddb50 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeWorkList.java --- 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 nodes) { for (Node node : nodes) { - if (node.isAlive() && !node.isExternal()) { + if (node.isAlive()) { this.add(node); } } diff -r 944e31d1b427 -r 3affe68ddb50 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java --- 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; } diff -r 944e31d1b427 -r 3affe68ddb50 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotForeignCallsProvider.java --- 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); - } } diff -r 944e31d1b427 -r 3affe68ddb50 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java --- 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 + } + } diff -r 944e31d1b427 -r 3affe68ddb50 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotReplacementsImpl.java --- 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 getMacroSubstitution(ResolvedJavaMethod method) { + Class 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; } + } diff -r 944e31d1b427 -r 3affe68ddb50 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java --- 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; diff -r 944e31d1b427 -r 3affe68ddb50 graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAIL.java --- 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); diff -r 944e31d1b427 -r 3affe68ddb50 graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILControlFlow.java --- 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; diff -r 944e31d1b427 -r 3affe68ddb50 graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java --- 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 diff -r 944e31d1b427 -r 3affe68ddb50 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java --- 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; } diff -r 944e31d1b427 -r 3affe68ddb50 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java --- 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; + } } diff -r 944e31d1b427 -r 3affe68ddb50 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java --- 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) { diff -r 944e31d1b427 -r 3affe68ddb50 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java --- 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; + } } - } diff -r 944e31d1b427 -r 3affe68ddb50 graal/com.oracle.graal.options.test/src/com/oracle/graal/options/test/TestOptionValue.java --- /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 Stable = new StableOptionValue<>(true); + public static final OptionValue Mutable = new OptionValue<>("original"); + public static final OptionValue 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 + } + } +} diff -r 944e31d1b427 -r 3affe68ddb50 graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionDescriptor.java --- 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); } /** diff -r 944e31d1b427 -r 3affe68ddb50 graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionValue.java --- 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 { /** + * 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. + *

+ * Since the returned object is {@link AutoCloseable} the try-with-resource construct can be + * used: + * + *

+     * try (OverrideScope s = OptionValue.override(myOption, myValue) {
+     *     // code that depends on myOption == myValue
+     * }
+     * 
+ */ + 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, 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. + *

+ * Since the returned object is {@link AutoCloseable} the try-with-resource construct can be + * used: + * + *

+     * Map overrides = new HashMap<>();
+     * overrides.put(myOption1, myValue1);
+     * overrides.put(myOption2, myValue2);
+     * try (OverrideScope s = OptionValue.override(overrides) {
+     *     // code that depends on myOption == myValue
+     * }
+     * 
+ */ + public static OverrideScope override(Map, Object> overrides) { + OverrideScope current = overrideScopes.get(); + if (current == null && overrides.size() == 1) { + Entry, 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. + *

+ * Since the returned object is {@link AutoCloseable} the try-with-resource construct can be + * used: + * + *

+     * try (OverrideScope s = OptionValue.override(myOption1, myValue1, myOption2, myValue2) {
+     *     // code that depends on myOption == myValue
+     * }
+     * 
+ * + * @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, 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 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 ""}. + */ + public String getName() { + return descriptor == null ? "" : (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 inherited); + + abstract T getOverride(OptionValue 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 inherited) { + inherited.put(option, value); + } + + @SuppressWarnings("unchecked") + @Override + T getOverride(OptionValue 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 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, 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, 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 inherited) { + if (parent != null) { + parent.addToInherited(inherited); + } + inherited.putAll(overrides); + } + + @SuppressWarnings("unchecked") + @Override + T getOverride(OptionValue option) { + return (T) overrides.get(option); + } + + @Override + public void close() { + if (!overrides.isEmpty()) { + overrideScopes.set(parent); + } + } + } } diff -r 944e31d1b427 -r 3affe68ddb50 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java --- 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 findParent(final Node start, final Class clazz) { - assert start != null; - if (clazz.isInstance(start.getParent())) { - return (T) start.getParent(); + public static T findParent(Node start, Class 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 findParentInterface(final Node start, final Class 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 List findAllParents(Node start, Class clazz) { + List 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 collectNodes(Node parent, Node child) { + List 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 findFirstNodeInstance(Node root, Class 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) { diff -r 944e31d1b427 -r 3affe68ddb50 mx/projects --- 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 diff -r 944e31d1b427 -r 3affe68ddb50 mxtool/mx.py --- 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:}' + + 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:' + for relevantResource in relevantResources: + 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}) diff -r 944e31d1b427 -r 3affe68ddb50 src/share/vm/code/nmethod.cpp --- 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"); } diff -r 944e31d1b427 -r 3affe68ddb50 src/share/vm/graal/graalRuntime.cpp --- 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))