# HG changeset patch # User Thomas Wuerthinger # Date 1379106730 -7200 # Node ID e9fc19eb3efb39c6711154d552b2472d6b0f6379 # Parent 2bd626188d31932dd32075defe853e509638104d# Parent a0566c8dcabfb68233b06f9cc1e10c6c46685ac3 Merge. diff -r 2bd626188d31 -r e9fc19eb3efb README_GRAAL.txt --- a/README_GRAAL.txt Thu Sep 05 16:36:40 2013 +0200 +++ b/README_GRAAL.txt Fri Sep 13 23:12:10 2013 +0200 @@ -11,11 +11,30 @@ % mx build -This builds the 'product' version of HotSpot with the Graal modifications. -To build the debug or fastdebug versions: +There are a number of VM configurations supported by mx which can +be explicitly specified using the --vm option. However, you'll typically +want one of these VM configurations: - mx build debug - mx build fastdebug +1. The 'server' configuration is a standard HotSpot VM that includes the + runtime support for Graal but uses the existing compilers for normal + compilation (e.g., when the interpreter threshold is hit for a method). + Compilation with Graal is only done by explicit requests to the + Graal API. This is how Truffle uses Graal. + +2. The 'graal' configuration is a VM where all compilation is performed + by Graal and no other compilers are built into the VM binary. This + VM will bootstrap Graal itself at startup unless the -XX:-BootstrapGraal + VM option is given. + +Unless you use the --vm option with the build command, you will be presented +with a dialogue to choose one of the above VM configurations for the build +as well as have the option to make it your default for subsequent commands +that need a VM specified. + +To build the debug or fastdebug builds: + +% mx --vmbuild debug build +% mx --vmbuild fastdebug build Running Graal ------------- @@ -24,47 +43,28 @@ % mx vm ... -To select the fastdebug or debug versions of the VM: - -% mx --fastdebug vm ... -% mx --debug vm ... +To select the fastdebug or debug builds of the VM: -Graal has an optional bootstrap step where it compiles itself before -compiling any application code. This bootstrap step currently takes about 7 seconds -on a fast x64 machine. It's useful to disable this bootstrap step when running small -programs with the -XX:-BootstrapGraal options. For example: +% mx --vmbuild fastdebug vm ... +% mx --vmbuild debug vm ... -% mx vm -XX:-BootstrapGraal ... - +Other VM Configurations +----------------------- -Other Build Configurations --------------------------- - -By default the build commands above create a HotSpot binary where Graal -is the only compiler. This binary is the Graal VM binary and identifies as -such with the -version option: +In addition to the VM configurations described above, there are +VM configurations that omit all VM support for Graal: -% mx vm -XX:-BootstrapGraal -version -java version "1.7.0_07" -Java(TM) SE Runtime Environment (build 1.7.0_07-b10) -OpenJDK 64-Bit Graal VM (build 25.0-b10-internal, mixed mode) - -It's also possible to build and execute the standard HotSpot binaries -using the --vm option: +% mx --vm server-nograal build +% mx --vm server-nograal vm -version +java version "1.7.0_25" +Java(TM) SE Runtime Environment (build 1.7.0_25-b15) +OpenJDK 64-Bit Server VM (build 25.0-b43-internal, mixed mode) -% mx --vm server build -% mx --vm server vm -version -java version "1.7.0_07" -Java(TM) SE Runtime Environment (build 1.7.0_07-b10) -OpenJDK 64-Bit Server VM (build 25.0-b10-internal, mixed mode) +% mx --vm client-nograal build +% mx --vm client-nograal vm -version +java version "1.7.0_25" +Java(TM) SE Runtime Environment (build 1.7.0_25-b15) +OpenJDK 64-Bit Cleint VM (build 25.0-b43-internal, mixed mode) -These standard binaries still include the code necessary to support use of the -Graal compiler for explicit compilation requests. However, in this configuration -the Graal compiler will not service VM issued compilation requests (e.g., upon -counter overflow in the interpreter). - -To build a HotSpot binary that completely omits all VM support for Graal, -define an environment variable OMIT_GRAAL (its value does not matter) and build -with the --vm option as above (doing a clean first if necessary): - -% env OMIT_GRAAL= mx --vm server build +These configurations aim to match as closely as possible the +VM(s) included in the OpenJDK binaries one can download. \ No newline at end of file diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DelegatingCodeCacheProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DelegatingCodeCacheProvider.java Fri Sep 13 23:12:10 2013 +0200 @@ -0,0 +1,72 @@ +/* + * 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.api.code; + +import com.oracle.graal.api.meta.*; + +/** + * A {@link CodeCacheProvider} that delegates to another {@link CodeCacheProvider}. + */ +public class DelegatingCodeCacheProvider extends DelegatingMetaAccessProvider implements CodeCacheProvider { + + public DelegatingCodeCacheProvider(CodeCacheProvider delegate) { + super(delegate); + } + + @Override + protected CodeCacheProvider delegate() { + return (CodeCacheProvider) super.delegate(); + } + + public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult) { + return delegate().addMethod(method, compResult); + } + + public String disassemble(CompilationResult compResult, InstalledCode installedCode) { + return delegate().disassemble(compResult, installedCode); + } + + public RegisterConfig lookupRegisterConfig() { + return delegate().lookupRegisterConfig(); + } + + public int getMinimumOutgoingSize() { + return delegate().getMinimumOutgoingSize(); + } + + public ForeignCallLinkage lookupForeignCall(ForeignCallDescriptor descriptor) { + return delegate().lookupForeignCall(descriptor); + } + + public int encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason) { + return delegate().encodeDeoptActionAndReason(action, reason); + } + + public boolean needsDataPatch(Constant constant) { + return delegate().needsDataPatch(constant); + } + + public TargetDescription getTarget() { + return delegate().getTarget(); + } +} diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DelegatingMetaAccessProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DelegatingMetaAccessProvider.java Fri Sep 13 23:12:10 2013 +0200 @@ -0,0 +1,89 @@ +/* + * 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.api.meta; + +import java.lang.reflect.*; + +/** + * A {@link MetaAccessProvider} that delegates to another {@link MetaAccessProvider}. + */ +public class DelegatingMetaAccessProvider implements MetaAccessProvider { + + private final MetaAccessProvider delegate; + + public DelegatingMetaAccessProvider(MetaAccessProvider delegate) { + this.delegate = delegate; + } + + protected MetaAccessProvider delegate() { + return delegate; + } + + public ResolvedJavaType lookupJavaType(Class clazz) { + return delegate.lookupJavaType(clazz); + } + + public ResolvedJavaMethod lookupJavaMethod(Method reflectionMethod) { + return delegate.lookupJavaMethod(reflectionMethod); + } + + public ResolvedJavaMethod lookupJavaConstructor(Constructor reflectionConstructor) { + return delegate.lookupJavaConstructor(reflectionConstructor); + } + + public ResolvedJavaField lookupJavaField(Field reflectionField) { + return delegate.lookupJavaField(reflectionField); + } + + public ResolvedJavaType lookupJavaType(Constant constant) { + return delegate.lookupJavaType(constant); + } + + public Signature parseMethodDescriptor(String methodDescriptor) { + return delegate.parseMethodDescriptor(methodDescriptor); + } + + public boolean constantEquals(Constant x, Constant y) { + return delegate.constantEquals(x, y); + } + + public int lookupArrayLength(Constant array) { + return delegate.lookupArrayLength(array); + } + + public Constant readUnsafeConstant(Kind kind, Object base, long displacement, boolean compressible) { + return delegate.readUnsafeConstant(kind, base, displacement, compressible); + } + + public boolean isReexecutable(ForeignCallDescriptor descriptor) { + return delegate.isReexecutable(descriptor); + } + + public LocationIdentity[] getKilledLocations(ForeignCallDescriptor descriptor) { + return delegate.getKilledLocations(descriptor); + } + + public boolean canDeoptimize(ForeignCallDescriptor descriptor) { + return delegate.canDeoptimize(descriptor); + } +} diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java Fri Sep 13 23:12:10 2013 +0200 @@ -112,7 +112,7 @@ int getModifiers(); /** - * Checks whether this type is initialized. If a type is initialized it implies that is was + * Checks whether this type is initialized. If a type is initialized it implies that it was * {@link #isLinked() linked} and that the static initializer has run. * * @return {@code true} if this type is initialized diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ArrayPTXTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ArrayPTXTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -0,0 +1,117 @@ +/* + * 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.compiler.ptx.test; + +import java.lang.reflect.Method; + +import org.junit.*; + +public class ArrayPTXTest extends PTXTestBase { + + @Ignore + @Test + public void testArray() { + compile("testArray1I"); + compile("testArray1J"); + compile("testArray1B"); + compile("testArray1S"); + compile("testArray1C"); + compile("testArray1F"); + compile("testArray1D"); + compile("testArray1L"); + compile("testStoreArray1I"); + compile("testStoreArray1J"); + compile("testStoreArray1B"); + compile("testStoreArray1S"); + compile("testStoreArray1F"); + compile("testStoreArray1D"); + } + + public static int testArray1I(int[] array, int i) { + return array[i]; + } + + public static long testArray1J(long[] array, int i) { + return array[i]; + } + + public static byte testArray1B(byte[] array, int i) { + return array[i]; + } + + public static short testArray1S(short[] array, int i) { + return array[i]; + } + + public static char testArray1C(char[] array, int i) { + return array[i]; + } + + public static float testArray1F(float[] array, int i) { + return array[i]; + } + + public static double testArray1D(double[] array, int i) { + return array[i]; + } + + public static Object testArray1L(Object[] array, int i) { + return array[i]; + } + + public static void testStoreArray1I(int[] array, int i, int val) { + array[i] = val; + } + + public static void testStoreArray1B(byte[] array, int i, byte val) { + array[i] = val; + } + + public static void testStoreArray1S(short[] array, int i, short val) { + array[i] = val; + } + + public static void testStoreArray1J(long[] array, int i, long val) { + array[i] = val; + } + + public static void testStoreArray1F(float[] array, int i, float val) { + array[i] = val; + } + + public static void testStoreArray1D(double[] array, int i, double val) { + array[i] = val; + } + + public static void main(String[] args) { + ArrayPTXTest test = new ArrayPTXTest(); + for (Method m : ArrayPTXTest.class.getMethods()) { + String name = m.getName(); + if (m.getAnnotation(Test.class) == null && name.startsWith("test")) { + // CheckStyle: stop system..print check + System.out.println(name + ": \n" + new String(test.compile(name).getTargetCode())); + // CheckStyle: resume system..print check + } + } + } +} diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ArrayTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ArrayTest.java Thu Sep 05 16:36:40 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,117 +0,0 @@ -/* - * 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.compiler.ptx.test; - -import java.lang.reflect.Method; - -import org.junit.*; - -public class ArrayTest extends PTXTestBase { - - @Ignore - @Test - public void testArray() { - compile("testArray1I"); - compile("testArray1J"); - compile("testArray1B"); - compile("testArray1S"); - compile("testArray1C"); - compile("testArray1F"); - compile("testArray1D"); - compile("testArray1L"); - compile("testStoreArray1I"); - compile("testStoreArray1J"); - compile("testStoreArray1B"); - compile("testStoreArray1S"); - compile("testStoreArray1F"); - compile("testStoreArray1D"); - } - - public static int testArray1I(int[] array, int i) { - return array[i]; - } - - public static long testArray1J(long[] array, int i) { - return array[i]; - } - - public static byte testArray1B(byte[] array, int i) { - return array[i]; - } - - public static short testArray1S(short[] array, int i) { - return array[i]; - } - - public static char testArray1C(char[] array, int i) { - return array[i]; - } - - public static float testArray1F(float[] array, int i) { - return array[i]; - } - - public static double testArray1D(double[] array, int i) { - return array[i]; - } - - public static Object testArray1L(Object[] array, int i) { - return array[i]; - } - - public static void testStoreArray1I(int[] array, int i, int val) { - array[i] = val; - } - - public static void testStoreArray1B(byte[] array, int i, byte val) { - array[i] = val; - } - - public static void testStoreArray1S(short[] array, int i, short val) { - array[i] = val; - } - - public static void testStoreArray1J(long[] array, int i, long val) { - array[i] = val; - } - - public static void testStoreArray1F(float[] array, int i, float val) { - array[i] = val; - } - - public static void testStoreArray1D(double[] array, int i, double val) { - array[i] = val; - } - - public static void main(String[] args) { - ArrayTest test = new ArrayTest(); - for (Method m : ArrayTest.class.getMethods()) { - String name = m.getName(); - if (m.getAnnotation(Test.class) == null && name.startsWith("test")) { - // CheckStyle: stop system..print check - System.out.println(name + ": \n" + new String(test.compile(name).getTargetCode())); - // CheckStyle: resume system..print check - } - } - } -} diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -39,35 +39,47 @@ public static int testSwitch1I(int a) { switch (a) { - case 1: - return 2; - case 2: - return 3; - default: - return 4; + case 1: + return 2; + case 2: + return 3; + default: + return 4; } } public static int testLookupSwitch1I(int a) { switch (a) { - case 0: return 1; - case 1: return 2; - case 2: return 3; - case 3: return 1; - case 4: return 2; - case 5: return 3; - case 6: return 1; - case 7: return 2; - case 8: return 3; - case 9: return 1; - case 10: return 2; - case 11: return 3; - default: return -1; + case 0: + return 1; + case 1: + return 2; + case 2: + return 3; + case 3: + return 1; + case 4: + return 2; + case 5: + return 3; + case 6: + return 1; + case 7: + return 2; + case 8: + return 3; + case 9: + return 1; + case 10: + return 2; + case 11: + return 3; + default: + return -1; } } - @SuppressWarnings("unused") - private static Object foo = null; + @SuppressWarnings("unused") private static Object foo = null; public static boolean testStatic(Object o) { foo = o; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/FloatPTXTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/FloatPTXTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/FloatPTXTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -37,6 +37,8 @@ if (r.getTargetCode() == null) { printReport("Compilation of testAdd2F FAILED"); } + + /* r = compile("testAdd2D"); if (r.getTargetCode() == null) { printReport("Compilation of testAdd2D FAILED"); @@ -58,6 +60,7 @@ if (r.getTargetCode() == null) { printReport("Compilation of testConstD FAILED"); } + */ } public static float testAdd2F(float a, float b) { @@ -84,6 +87,7 @@ return 32.0 + a; } + @Ignore @Test public void testSub() { CompilationResult r = compile("testSub2F"); @@ -141,6 +145,7 @@ return 32.0 - a; } + @Ignore @Test public void testMul() { CompilationResult r = compile("testMul2F"); @@ -198,6 +203,7 @@ return 32.0 * a; } + @Ignore @Test public void testDiv() { CompilationResult r = compile("testDiv2F"); @@ -255,6 +261,7 @@ return 32.0 / a; } + @Ignore @Test public void testNeg() { CompilationResult r = compile("testNeg2F"); @@ -276,6 +283,7 @@ return -a; } + @Ignore @Test public void testRem() { // need linkage to PTX remainder() @@ -360,9 +368,7 @@ FloatPTXTest test = new FloatPTXTest(); for (Method m : FloatPTXTest.class.getMethods()) { String name = m.getName(); - if (m.getAnnotation(Test.class) == null && - name.startsWith("test") && - name.startsWith("testRem") == false) { + if (m.getAnnotation(Test.class) == null && name.startsWith("test") && name.startsWith("testRem") == false) { // CheckStyle: stop system..print check System.out.println(name + ": \n" + new String(test.compile(name).getTargetCode())); // CheckStyle: resume system..print check diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/IntegerPTXTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/IntegerPTXTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/IntegerPTXTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -26,13 +26,21 @@ import java.lang.reflect.Method; - public class IntegerPTXTest extends PTXTestBase { @Test public void testAdd() { - Integer r4 = (Integer) invoke(compile("testAdd2I"), 18, 24); + Integer r4 = (Integer) invoke(compile("testAdd2B"), (byte) 6, (byte) 4); + if (r4 == null) { + printReport("testAdd2B FAILED"); + } else if (r4.intValue() == testAdd2B((byte) 6, (byte) 4)) { + printReport("testAdd2B PASSED"); + } else { + printReport("testAdd2B FAILED"); + } + + r4 = (Integer) invoke(compile("testAdd2I"), 18, 24); if (r4 == null) { printReport("testAdd2I FAILED"); } else if (r4.intValue() == testAdd2I(18, 24)) { @@ -50,8 +58,6 @@ printReport("testAdd2L FAILED"); } - //invoke(compile("testAdd2B"), (byte) 6, (byte) 4); - r4 = (Integer) invoke(compile("testAddIConst"), 5); if (r4 == null) { printReport("testAddIConst FAILED"); @@ -69,7 +75,6 @@ } else { printReport("testAddConstI FAILED"); } - } public static int testAdd2I(int a, int b) { @@ -288,6 +293,7 @@ public static long testRem2L(long a, long b) { return a % b; } + @Ignore @Test public void testIntConversion() { diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/LogicPTXTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/LogicPTXTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/LogicPTXTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -26,7 +26,6 @@ import org.junit.Test; - /* PTX ISA 3.1 - 8.7.5 Logic and Shift Instructions */ public class LogicPTXTest extends PTXTestBase { diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXBackend.java --- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXBackend.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXBackend.java Fri Sep 13 23:12:10 2013 +0200 @@ -132,8 +132,6 @@ // Start emiting body of the PTX kernel. codeBuffer.emitString0(") {"); codeBuffer.emitString(""); - - codeBuffer.emitString(".reg .u64" + " %rax;"); } // Emit .reg space declarations @@ -144,6 +142,8 @@ final SortedSet signed32 = new TreeSet<>(); final SortedSet signed64 = new TreeSet<>(); + final SortedSet float32 = new TreeSet<>(); + final SortedSet float64 = new TreeSet<>(); ValueProcedure trackRegisterKind = new ValueProcedure() { @@ -159,6 +159,12 @@ case Long: signed64.add(regVal.getRegister().encoding()); break; + case Float: + float32.add(regVal.getRegister().encoding()); + break; + case Double: + float64.add(regVal.getRegister().encoding()); + break; default : throw GraalInternalError.shouldNotReachHere("unhandled register type " + value.toString()); } @@ -179,6 +185,12 @@ for (Integer i : signed64) { codeBuffer.emitString(".reg .s64 %r" + i.intValue() + ";"); } + for (Integer i : float32) { + codeBuffer.emitString(".reg .f32 %r" + i.intValue() + ";"); + } + for (Integer i : float64) { + codeBuffer.emitString(".reg .f64 %r" + i.intValue() + ";"); + } } @Override diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java --- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Fri Sep 13 23:12:10 2013 +0200 @@ -123,7 +123,7 @@ // Additional argument for return value. Value[] params = new Value[argCount + 1]; for (int i = 0; i < argCount; i++) { - params[i] = toParamKind(incomingArguments.getArgument(i)); + params[i] = incomingArguments.getArgument(i); } // Add the return value as the last parameter. params[argCount] = incomingArguments.getReturn(); @@ -131,7 +131,6 @@ append(new PTXParameterOp(params)); for (LocalNode local : graph.getNodes(LocalNode.class)) { Value param = params[local.index()]; - assert param.getKind() == local.kind().getStackKind(); setResult(local, emitLoadParam(param.getKind(), param, null)); } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -308,8 +308,8 @@ graph = parse(snippet); Assumptions assumptions = new Assumptions(false); HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); - new InliningPhase().apply(graph, context); - new PartialEscapePhase(false).apply(graph, context); + new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); + new PartialEscapePhase(false, new CanonicalizerPhase(true)).apply(graph, context); } private void compareGraphs(final String snippet, final String referenceSnippet) { @@ -326,19 +326,19 @@ Assumptions assumptions = new Assumptions(false); HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); - new InliningPhase().apply(graph, context); + new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); if (loopPeeling) { new LoopTransformHighPhase().apply(graph); } new DeadCodeEliminationPhase().apply(graph); canonicalizer.apply(graph, context); - new PartialEscapePhase(false).apply(graph, context); + new PartialEscapePhase(false, canonicalizer).apply(graph, context); new DeadCodeEliminationPhase().apply(graph); canonicalizer.apply(graph, context); StructuredGraph referenceGraph = parse(referenceSnippet); - new InliningPhase().apply(referenceGraph, context); + new InliningPhase(new CanonicalizerPhase(true)).apply(referenceGraph, context); new DeadCodeEliminationPhase().apply(referenceGraph); new CanonicalizerPhase(true).apply(referenceGraph, context); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -30,12 +30,13 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.tiers.*; public class CompareCanonicalizerTest extends GraalCompilerTest { private StructuredGraph getCanonicalizedGraph(String name) { StructuredGraph graph = parse(name); - new CanonicalizerPhase.Instance(runtime(), null, true).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements)); return graph; } @@ -53,7 +54,7 @@ assertEquals(referenceGraph, graph); } Assumptions assumptions = new Assumptions(false); - new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(referenceGraph); + new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(runtime(), assumptions, replacements)); for (int i = 1; i < 4; i++) { StructuredGraph graph = getCanonicalizedGraph("canonicalCompare" + i); assertEquals(referenceGraph, graph); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -45,7 +45,7 @@ Constant b = Constant.forInt(i < 100 ? a.asInt() : rand.nextInt()); boolean result1 = c1.foldCondition(a, b, null, false); boolean result2 = c2.foldCondition(a, b, null, false); - if (result1 && implies) { + if (result1) { assertTrue(result2); } } @@ -60,7 +60,7 @@ for (Condition c1 : Condition.values()) { for (Condition c2 : Condition.values()) { Condition join = c1.join(c2); - assertTrue(join == c2.join(c1)); + assertEquals(join, c2.join(c1)); if (join != null) { for (int i = 0; i < 1000; i++) { Constant a = Constant.forInt(rand.nextInt()); @@ -70,6 +70,8 @@ boolean resultJoin = join.foldCondition(a, b, null, false); if (result1 && result2) { assertTrue(resultJoin); + } else { + assertFalse(resultJoin); } } } @@ -83,7 +85,7 @@ for (Condition c1 : Condition.values()) { for (Condition c2 : Condition.values()) { Condition meet = c1.meet(c2); - assertTrue(meet == c2.meet(c1)); + assertEquals(meet, c2.meet(c1)); if (meet != null) { for (int i = 0; i < 1000; i++) { Constant a = Constant.forInt(rand.nextInt()); @@ -93,6 +95,8 @@ boolean resultMeet = meet.foldCondition(a, b, null, false); if (result1 || result2) { assertTrue(resultMeet); + } else { + assertFalse(resultMeet); } } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -32,6 +32,7 @@ import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.tiers.*; /** * Collection of tests for {@link ConditionalEliminationPhase} including those that triggered bugs @@ -141,7 +142,7 @@ StructuredGraph graph = parse("testNullnessSnippet"); new ConditionalEliminationPhase(runtime()).apply(graph); - new CanonicalizerPhase.Instance(runtime(), null, true).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements)); for (ConstantNode constant : graph.getNodes().filter(ConstantNode.class)) { assertTrue("unexpected constant: " + constant, constant.asConstant().isNull() || constant.asConstant().asInt() > 0); } @@ -163,7 +164,7 @@ @Test public void testDisjunction() { StructuredGraph graph = parse("testDisjunctionSnippet"); - new CanonicalizerPhase.Instance(runtime(), null, true).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements)); IfNode ifNode = (IfNode) graph.start().next(); InstanceOfNode instanceOf = (InstanceOfNode) ifNode.condition(); IsNullNode x = graph.unique(new IsNullNode(graph.getLocal(0))); @@ -171,9 +172,9 @@ ShortCircuitOrNode disjunction = graph.unique(new ShortCircuitOrNode(x, false, y, false, NOT_FREQUENT_PROBABILITY)); LogicNegationNode negation = graph.unique(new LogicNegationNode(disjunction)); ifNode.setCondition(negation); - new CanonicalizerPhase.Instance(runtime(), null, true).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements)); new ConditionalEliminationPhase(runtime()).apply(graph); - new CanonicalizerPhase.Instance(runtime(), null, true).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements)); for (ConstantNode constant : graph.getNodes().filter(ConstantNode.class)) { assertTrue("unexpected constant: " + constant, constant.asConstant().isNull() || constant.asConstant().asInt() > 0); } @@ -191,7 +192,7 @@ public void testInvoke() { test("testInvokeSnippet", new Integer(16)); StructuredGraph graph = parse("testInvokeSnippet"); - new CanonicalizerPhase.Instance(runtime(), null, true).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements)); new ConditionalEliminationPhase(runtime()).apply(graph); InvokeNode invoke = graph.getNodes(InvokeNode.class).first(); @@ -221,11 +222,43 @@ @Test public void testTypeMerging() { StructuredGraph graph = parse("testTypeMergingSnippet"); - new CanonicalizerPhase.Instance(runtime(), null, true).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements)); new ConditionalEliminationPhase(runtime()).apply(graph); - new CanonicalizerPhase.Instance(runtime(), null, true).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements)); assertEquals(0, graph.getNodes().filter(StoreFieldNode.class).count()); } + public static String testInstanceOfCheckCastSnippet(Object e) { + if (e instanceof Entry) { + return ((Entry) e).name; + } + return null; + } + + @Test + public void testInstanceOfCheckCast() { + StructuredGraph graph = parse("testInstanceOfCheckCastSnippet"); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements)); + new ConditionalEliminationPhase(runtime()).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements)); + + assertEquals(0, graph.getNodes().filter(CheckCastNode.class).count()); + } + + @Test + @Ignore + public void testInstanceOfCheckCastLowered() { + StructuredGraph graph = parse("testInstanceOfCheckCastSnippet"); + + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); + PhaseContext context = new PhaseContext(runtime(), null, replacements); + + new LoweringPhase(canonicalizer).apply(graph, context); + canonicalizer.apply(graph, context); + new ConditionalEliminationPhase(runtime()).apply(graph); + canonicalizer.apply(graph, context); + + assertEquals(0, graph.getNodes().filter(GuardNode.class).count()); + } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -83,7 +83,7 @@ public void run() { StructuredGraph graph = parse(snippet); HighTierContext context = new HighTierContext(runtime(), new Assumptions(false), replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); - new InliningPhase().apply(graph, context); + new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); new CanonicalizerPhase(true).apply(graph, context); Debug.dump(graph, "Graph"); StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -31,6 +31,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.tiers.*; public class EliminateNestedCheckCastsTest extends GraalCompilerTest { @@ -113,8 +114,8 @@ public StructuredGraph call() throws Exception { Debug.dump(graph, "After parsing: " + snippet); Assert.assertEquals(checkcasts, graph.getNodes().filter(CheckCastNode.class).count()); - new CanonicalizerPhase.Instance(runtime(), new Assumptions(false), true).apply(graph); - Assert.assertEquals(afterCanon, graph.getNodes(CheckCastNode.class).count()); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), new Assumptions(false), replacements)); + Assert.assertEquals(afterCanon, graph.getNodes().filter(CheckCastNode.class).count()); return graph; } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -69,7 +69,7 @@ GraphBuilderConfiguration conf = GraphBuilderConfiguration.getSnippetDefault(); new GraphBuilderPhase(runtime, conf, OptimisticOptimizations.ALL).apply(graph); HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); - new InliningPhase().apply(graph, context); + new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); new CanonicalizerPhase(true).apply(graph, context); return graph; } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -29,7 +29,6 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.Lowerable.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; @@ -60,7 +59,7 @@ public void run() { StructuredGraph graph = parse(snippet); PhaseContext context = new PhaseContext(runtime(), new Assumptions(false), replacements); - new LoweringPhase(LoweringType.BEFORE_GUARDS).apply(graph, context); + new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, context); new FloatingReadPhase().apply(graph); ReturnNode returnNode = null; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -87,7 +87,7 @@ } @BeforeClass - public static void initializeDebgging() { + public static void initializeDebugging() { DebugEnvironment.initialize(System.out); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfCanonicalizerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfCanonicalizerTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfCanonicalizerTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -31,6 +31,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.tiers.*; /** * In the following tests, the usages of local variable "a" are replaced with the integer constant @@ -144,7 +145,7 @@ n.replaceFirstInput(local, constant); } Debug.dump(graph, "Graph"); - new CanonicalizerPhase.Instance(runtime(), new Assumptions(false), true).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), new Assumptions(false), replacements)); for (FrameState fs : local.usages().filter(FrameState.class).snapshot()) { fs.replaceFirstInput(local, null); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -74,7 +74,7 @@ final Method method = getMethod("testMethod"); final StructuredGraph graph = parseDebug(method); int graphLineSPs = 0; - for (InfopointNode ipn : graph.getNodes(InfopointNode.class)) { + for (InfopointNode ipn : graph.getNodes().filter(InfopointNode.class)) { if (ipn.reason == InfopointReason.LINE_NUMBER) { ++graphLineSPs; } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeExceptionTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeExceptionTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeExceptionTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -67,7 +67,7 @@ } Assumptions assumptions = new Assumptions(false); HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); - new InliningPhase(hints).apply(graph, context); + new InliningPhase(hints, new CanonicalizerPhase(true)).apply(graph, context); new CanonicalizerPhase(true).apply(graph, context); new DeadCodeEliminationPhase().apply(graph); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeHintsTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeHintsTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeHintsTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -78,7 +78,7 @@ Assumptions assumptions = new Assumptions(false); HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); - new InliningPhase(hints).apply(graph, context); + new InliningPhase(hints, new CanonicalizerPhase(true)).apply(graph, context); new CanonicalizerPhase(true).apply(graph, context); new DeadCodeEliminationPhase().apply(graph); StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LockEliminationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LockEliminationTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LockEliminationTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -29,7 +29,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.spi.Lowerable.LoweringType; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; @@ -62,7 +61,7 @@ test("testSynchronizedSnippet", new A(), new A()); StructuredGraph graph = getGraph("testSynchronizedSnippet"); - new CanonicalizerPhase.Instance(runtime(), null, true).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements)); new LockEliminationPhase().apply(graph); assertEquals(1, graph.getNodes().filter(MonitorEnterNode.class).count()); assertEquals(1, graph.getNodes().filter(MonitorExitNode.class).count()); @@ -80,7 +79,7 @@ test("testSynchronizedMethodSnippet", new A()); StructuredGraph graph = getGraph("testSynchronizedMethodSnippet"); - new CanonicalizerPhase.Instance(runtime(), null, true).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements)); new LockEliminationPhase().apply(graph); assertEquals(1, graph.getNodes().filter(MonitorEnterNode.class).count()); assertEquals(1, graph.getNodes().filter(MonitorExitNode.class).count()); @@ -93,10 +92,10 @@ Assumptions assumptions = new Assumptions(true); HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, phasePlan, OptimisticOptimizations.ALL); new CanonicalizerPhase(true).apply(graph, context); - new InliningPhase().apply(graph, context); + new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); new CanonicalizerPhase(true).apply(graph, context); new DeadCodeEliminationPhase().apply(graph); - new LoweringPhase(LoweringType.BEFORE_GUARDS).apply(graph, context); + new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, context); new ValueAnchorCleanupPhase().apply(graph); new LockEliminationPhase().apply(graph); return graph; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LoopUnswitchTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LoopUnswitchTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LoopUnswitchTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -30,6 +30,7 @@ import com.oracle.graal.loop.phases.*; import com.oracle.graal.nodes.*; import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.tiers.*; public class LoopUnswitchTest extends GraalCompilerTest { @@ -133,8 +134,8 @@ } Assumptions assumptions = new Assumptions(false); - new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(graph); - new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(referenceGraph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), assumptions, replacements)); + new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(runtime(), assumptions, replacements)); Debug.scope("Test", new DebugDumpScope("Test:" + snippet), new Runnable() { @Override diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -36,7 +36,6 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.Lowerable.LoweringType; import com.oracle.graal.nodes.util.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; @@ -502,9 +501,9 @@ HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); new CanonicalizerPhase(true).apply(graph, context); if (mode == TestMode.INLINED_WITHOUT_FRAMESTATES) { - new InliningPhase().apply(graph, context); + new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); } - new LoweringPhase(LoweringType.BEFORE_GUARDS).apply(graph, context); + new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, context); if (mode == TestMode.WITHOUT_FRAMESTATES || mode == TestMode.INLINED_WITHOUT_FRAMESTATES) { for (Node node : graph.getNodes()) { if (node instanceof StateSplit) { @@ -523,8 +522,8 @@ MidTierContext midContext = new MidTierContext(runtime(), assumptions, replacements, runtime().getTarget(), OptimisticOptimizations.ALL); new GuardLoweringPhase().apply(graph, midContext); - new LoweringPhase(LoweringType.AFTER_GUARDS).apply(graph, midContext); - new LoweringPhase(LoweringType.AFTER_FSA).apply(graph, midContext); + new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, midContext); + new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, midContext); SchedulePhase schedule = new SchedulePhase(SchedulingStrategy.LATEST_OUT_OF_LOOPS, memsched); schedule.apply(graph); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -95,7 +95,7 @@ } Assumptions assumptions = new Assumptions(false); HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); - new InliningPhase(hints).apply(graph, context); + new InliningPhase(hints, new CanonicalizerPhase(true)).apply(graph, context); new CanonicalizerPhase(true).apply(graph, context); new DeadCodeEliminationPhase().apply(graph); return graph; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -30,7 +30,6 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.Lowerable.LoweringType; import com.oracle.graal.nodes.type.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; @@ -94,7 +93,7 @@ StructuredGraph graph = parse(snippet); PhaseContext context = new PhaseContext(runtime(), new Assumptions(false), replacements); CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); - new LoweringPhase(LoweringType.BEFORE_GUARDS).apply(graph, context); + new LoweringPhase(canonicalizer).apply(graph, context); canonicalizer.apply(graph, context); new PushThroughPiPhase().apply(graph); canonicalizer.apply(graph, context); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -29,7 +29,6 @@ import com.oracle.graal.debug.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.Lowerable.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; @@ -85,7 +84,7 @@ public void run() { StructuredGraph graph = parse(snippet); PhaseContext context = new PhaseContext(runtime(), new Assumptions(false), replacements); - new LoweringPhase(LoweringType.BEFORE_GUARDS).apply(graph, context); + new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, context); new FloatingReadPhase().apply(graph); new EliminatePartiallyRedundantGuardsPhase(true, false).apply(graph); new ReadEliminationPhase().apply(graph); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReassociateAndCanonicalTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReassociateAndCanonicalTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReassociateAndCanonicalTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -28,6 +28,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.tiers.*; public class ReassociateAndCanonicalTest extends GraalCompilerTest { @@ -241,12 +242,12 @@ return (2 - rnd) - 1; } - private void test(String test, String ref) { + private void test(String test, String ref) { StructuredGraph testGraph = parse(test); Assumptions assumptions = new Assumptions(false); - new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(testGraph); + new CanonicalizerPhase(true).apply(testGraph, new PhaseContext(runtime(), assumptions, replacements)); StructuredGraph refGraph = parse(ref); - new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(refGraph); + new CanonicalizerPhase(true).apply(refGraph, new PhaseContext(runtime(), assumptions, replacements)); assertEquals(testGraph, refGraph); } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ScalarTypeSystemTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ScalarTypeSystemTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ScalarTypeSystemTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -28,6 +28,7 @@ import com.oracle.graal.debug.*; import com.oracle.graal.nodes.*; import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.tiers.*; /** * In the following tests, the scalar type system of the compiler should be complete enough to see @@ -166,9 +167,9 @@ StructuredGraph graph = parse(snippet); Debug.dump(graph, "Graph"); Assumptions assumptions = new Assumptions(false); - new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), assumptions, replacements)); new ConditionalEliminationPhase(runtime()).apply(graph); - new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), assumptions, replacements)); StructuredGraph referenceGraph = parse(referenceSnippet); assertEquals(referenceGraph, graph); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StampCanonicalizerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StampCanonicalizerTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StampCanonicalizerTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -28,6 +28,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.tiers.*; /** * This class tests some specific patterns the stamp system should be able to canonicalize away @@ -109,7 +110,7 @@ private void testZeroReturn(String methodName) { StructuredGraph graph = parse(methodName); - new CanonicalizerPhase.Instance(runtime(), new Assumptions(false), true).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), new Assumptions(false), replacements)); new DeadCodeEliminationPhase().apply(graph); assertConstantReturn(graph, 0); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StraighteningTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StraighteningTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StraighteningTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -28,6 +28,7 @@ import com.oracle.graal.debug.*; import com.oracle.graal.nodes.*; import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.tiers.*; public class StraighteningTest extends GraalCompilerTest { @@ -89,7 +90,7 @@ // No debug scope to reduce console noise for @Test(expected = ...) tests StructuredGraph graph = parse(snippet); Debug.dump(graph, "Graph"); - new CanonicalizerPhase.Instance(runtime(), new Assumptions(false), true).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), new Assumptions(false), replacements)); StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET); assertEquals(referenceGraph, graph); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/TypeSystemTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/TypeSystemTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/TypeSystemTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -35,6 +35,7 @@ import com.oracle.graal.nodes.java.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.schedule.*; +import com.oracle.graal.phases.tiers.*; /** * In the following tests, the scalar type system of the compiler should be complete enough to see @@ -44,7 +45,7 @@ @Test public void test1() { - test("test1Snippet", CheckCastNode.class); + testHelper("test1Snippet", CheckCastNode.class); } public static int test1Snippet(Object a) { @@ -56,7 +57,7 @@ @Test public void test2() { - test("test2Snippet", CheckCastNode.class); + testHelper("test2Snippet", CheckCastNode.class); } public static int test2Snippet(Object a) { @@ -161,7 +162,7 @@ @Test public void test6() { - test("test6Snippet", CheckCastNode.class); + testHelper("test6Snippet", CheckCastNode.class); } public static int test6Snippet(int i) throws IOException { @@ -184,13 +185,13 @@ StructuredGraph graph = parse(snippet); Debug.dump(graph, "Graph"); Assumptions assumptions = new Assumptions(false); - new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), assumptions, replacements)); new ConditionalEliminationPhase(runtime()).apply(graph); - new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), assumptions, replacements)); // a second canonicalizer is needed to process nested MaterializeNodes - new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), assumptions, replacements)); StructuredGraph referenceGraph = parse(referenceSnippet); - new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(referenceGraph); + new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(runtime(), assumptions, replacements)); assertEquals(referenceGraph, graph); } @@ -236,14 +237,14 @@ } } - private void test(String snippet, Class clazz) { + private void testHelper(String snippet, Class clazz) { StructuredGraph graph = parse(snippet); Debug.dump(graph, "Graph"); Assumptions assumptions = new Assumptions(false); - new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), assumptions, replacements)); new ConditionalEliminationPhase(runtime()).apply(graph); - new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), assumptions, replacements)); Debug.dump(graph, "Graph"); - Assert.assertFalse("shouldn't have nodes of type " + clazz, graph.getNodes(clazz).iterator().hasNext()); + Assert.assertFalse("shouldn't have nodes of type " + clazz, graph.getNodes().filter(clazz).iterator().hasNext()); } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -32,6 +32,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.tiers.*; import com.oracle.graal.test.*; /** @@ -55,7 +56,7 @@ public void test1() { Method method = getMethod("testMethod"); final StructuredGraph graph = parse(method); - new CanonicalizerPhase.Instance(runtime(), new Assumptions(false), true).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), new Assumptions(false), replacements)); new DeadCodeEliminationPhase().apply(graph); for (Node node : graph.getNodes()) { diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EarlyReadEliminationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EarlyReadEliminationTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EarlyReadEliminationTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -42,7 +42,7 @@ graph = parse(snippet); Assumptions assumptions = new Assumptions(false); HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); - new InliningPhase().apply(graph, context); - new EarlyReadEliminationPhase().apply(graph, context); + new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); + new EarlyReadEliminationPhase(new CanonicalizerPhase(true)).apply(graph, context); } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -234,17 +234,18 @@ Assumptions assumptions = new Assumptions(false); HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); - new InliningPhase().apply(graph, context); + new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); new DeadCodeEliminationPhase().apply(graph); new CanonicalizerPhase(true).apply(graph, context); - new PartialEscapePhase(iterativeEscapeAnalysis).apply(graph, context); + new PartialEscapePhase(iterativeEscapeAnalysis, new CanonicalizerPhase(true)).apply(graph, context); Assert.assertEquals(1, graph.getNodes(ReturnNode.class).count()); ReturnNode returnNode = graph.getNodes(ReturnNode.class).first(); if (expectedConstantResult != null) { Assert.assertTrue(returnNode.result().toString(), returnNode.result().isConstant()); Assert.assertEquals(expectedConstantResult, returnNode.result().asConstant()); } - int newInstanceCount = graph.getNodes(NewInstanceNode.class).count() + graph.getNodes(NewArrayNode.class).count() + graph.getNodes(CommitAllocationNode.class).count(); + int newInstanceCount = graph.getNodes().filter(NewInstanceNode.class).count() + graph.getNodes().filter(NewArrayNode.class).count() + + graph.getNodes(CommitAllocationNode.class).count(); Assert.assertEquals(0, newInstanceCount); return returnNode; } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -244,7 +244,7 @@ graph = parse(snippet); Assumptions assumptions = new Assumptions(false); HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); - new InliningPhase().apply(graph, context); - new PartialEscapePhase(false, true).apply(graph, context); + new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); + new PartialEscapePhase(false, true, new CanonicalizerPhase(true)).apply(graph, context); } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -167,8 +167,8 @@ final void testMaterialize(final String snippet, double expectedProbability, int expectedCount, Class... invalidNodeClasses) { StructuredGraph result = processMethod(snippet); try { - Assert.assertTrue("partial escape analysis should have removed all NewInstanceNode allocations", result.getNodes(NewInstanceNode.class).isEmpty()); - Assert.assertTrue("partial escape analysis should have removed all NewArrayNode allocations", result.getNodes(NewArrayNode.class).isEmpty()); + Assert.assertTrue("partial escape analysis should have removed all NewInstanceNode allocations", result.getNodes().filter(NewInstanceNode.class).isEmpty()); + Assert.assertTrue("partial escape analysis should have removed all NewArrayNode allocations", result.getNodes().filter(NewArrayNode.class).isEmpty()); NodesToDoubles nodeProbabilities = new ComputeProbabilityClosure(result).apply(); double probabilitySum = 0; @@ -199,10 +199,10 @@ Assumptions assumptions = new Assumptions(false); HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); - new InliningPhase().apply(graph, context); + new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); new DeadCodeEliminationPhase().apply(graph); new CanonicalizerPhase(true).apply(graph, context); - new PartialEscapePhase(false).apply(graph, context); + new PartialEscapePhase(false, new CanonicalizerPhase(true)).apply(graph, context); for (MergeNode merge : graph.getNodes(MergeNode.class)) { merge.setStateAfter(null); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -240,7 +240,7 @@ HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, phasePlan, OptimisticOptimizations.ALL); Debug.dump(graph, "Graph"); new CanonicalizerPhase(true).apply(graph, context); - new InliningPhase().apply(graph, context); + new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); Debug.dump(graph, "Graph"); new CanonicalizerPhase(true).apply(graph, context); new DeadCodeEliminationPhase().apply(graph); @@ -279,7 +279,7 @@ private static int[] countMethodInfopoints(StructuredGraph graph) { int start = 0; int end = 0; - for (InfopointNode ipn : graph.getNodes(InfopointNode.class)) { + for (InfopointNode ipn : graph.getNodes().filter(InfopointNode.class)) { if (ipn.reason == InfopointReason.METHOD_START) { ++start; } else if (ipn.reason == InfopointReason.METHOD_END) { diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Fri Sep 13 23:12:10 2013 +0200 @@ -36,8 +36,6 @@ public class GraalDebugConfig implements DebugConfig { // @formatter:off - @Option(help = "Enable scope-based debugging", name = "Debug") - public static final OptionValue DebugEnabled = new OptionValue<>(true); @Option(help = "Pattern for scope(s) to in which dumping is enabled (see DebugFilter and Debug.dump)") public static final OptionValue Dump = new OptionValue<>(null); @Option(help = "Pattern for scope(s) to in which metering is enabled (see DebugFilter and Debug.metric)") @@ -53,7 +51,7 @@ "Partial - aggregate by partially qualified name (e.g., A.B.C.D.Counter and X.Y.Z.D.Counter will be merged to D.Counter)%n" + "Complete - aggregate by qualified name%n" + "Thread - aggregate by qualified name and thread") - public static final OptionValue DebugValueSummary = new OptionValue<>("Complete"); + public static final OptionValue DebugValueSummary = new OptionValue<>("Name"); @Option(help = "Send Graal IR to dump handlers on error") public static final OptionValue DumpOnError = new OptionValue<>(false); @Option(help = "Enable expensive assertions") @@ -68,6 +66,10 @@ }; // @formatter:on + public static boolean areDebugScopePatternsEnabled() { + return DumpOnError.getValue() || Dump.getValue() != null || Meter.getValue() != null || Time.getValue() != null || Log.getValue() != null; + } + private final DebugFilter logFilter; private final DebugFilter meterFilter; private final DebugFilter timerFilter; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Fri Sep 13 23:12:10 2013 +0200 @@ -686,9 +686,8 @@ List instructions = ir.lir(block); int numInst = instructions.size(); - // iterate all instructions of the block. skip the first because it is always a label - assert !instructions.get(0).hasOperands() : "first operation must always be a label"; - for (int j = 1; j < numInst; j++) { + // iterate all instructions of the block + for (int j = 0; j < numInst; j++) { final LIRInstruction op = instructions.get(j); ValueProcedure useProc = new ValueProcedure() { @@ -1174,10 +1173,8 @@ } // iterate all instructions of the block in reverse order. - // skip the first instruction because it is always a label // definitions of intervals are processed before uses - assert !instructions.get(0).hasOperands() : "first operation must always be a label"; - for (int j = instructions.size() - 1; j >= 1; j--) { + for (int j = instructions.size() - 1; j >= 0; j--) { final LIRInstruction op = instructions.get(j); final int opId = op.id(); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Fri Sep 13 23:12:10 2013 +0200 @@ -40,7 +40,6 @@ import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.JumpOp; import com.oracle.graal.lir.StandardOp.LabelOp; -import com.oracle.graal.lir.StandardOp.ParametersOp; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.calc.*; @@ -405,7 +404,7 @@ } public void emitIncomingValues(Value[] params) { - append(new ParametersOp(params)); + ((LabelOp) lir.lir(currentBlock).get(0)).setIncomingValues(params); } @Override diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Fri Sep 13 23:12:10 2013 +0200 @@ -22,12 +22,12 @@ */ package com.oracle.graal.compiler.phases; +import static com.oracle.graal.compiler.phases.HighTier.Options.*; import static com.oracle.graal.phases.GraalOptions.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.loop.phases.*; -import com.oracle.graal.nodes.spi.Lowerable.LoweringType; import com.oracle.graal.options.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; @@ -37,12 +37,15 @@ public class HighTier extends PhaseSuite { - // @formatter:off - @Option(help = "") - public static final OptionValue VerifyUsageWithEquals = new OptionValue<>(true); - @Option(help = "Enable inlining") - public static final OptionValue Inline = new OptionValue<>(true); - // @formatter:on + static class Options { + + // @formatter:off + @Option(help = "") + public static final OptionValue VerifyUsageWithEquals = new OptionValue<>(true); + @Option(help = "Enable inlining") + public static final OptionValue Inline = new OptionValue<>(true); + // @formatter:on + } public HighTier() { CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!AOTCompilation.getValue()); @@ -60,12 +63,12 @@ if (IterativeInlining.getValue()) { appendPhase(new IterativeInliningPhase(canonicalizer)); } else { - appendPhase(new InliningPhase()); + appendPhase(new InliningPhase(canonicalizer)); appendPhase(new DeadCodeEliminationPhase()); if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) { appendPhase(canonicalizer); - appendPhase(new IterativeConditionalEliminationPhase()); + appendPhase(new IterativeConditionalEliminationPhase(canonicalizer)); } } } @@ -73,15 +76,15 @@ appendPhase(new CleanTypeProfileProxyPhase()); if (FullUnroll.getValue()) { - appendPhase(new LoopFullUnrollPhase(!AOTCompilation.getValue())); + appendPhase(new LoopFullUnrollPhase(canonicalizer)); } if (OptTailDuplication.getValue()) { - appendPhase(new TailDuplicationPhase()); + appendPhase(new TailDuplicationPhase(canonicalizer)); } if (PartialEscapeAnalysis.getValue()) { - appendPhase(new PartialEscapePhase(true)); + appendPhase(new PartialEscapePhase(true, canonicalizer)); } if (OptConvertDeoptsToGuards.getValue()) { @@ -98,6 +101,6 @@ appendPhase(canonicalizer); } - appendPhase(new LoweringPhase(LoweringType.BEFORE_GUARDS)); + appendPhase(new LoweringPhase(canonicalizer)); } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java Fri Sep 13 23:12:10 2013 +0200 @@ -22,7 +22,8 @@ */ package com.oracle.graal.compiler.phases; -import com.oracle.graal.nodes.spi.Lowerable.LoweringType; +import static com.oracle.graal.phases.GraalOptions.*; + import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; @@ -30,7 +31,9 @@ public class LowTier extends PhaseSuite { public LowTier() { - appendPhase(new LoweringPhase(LoweringType.AFTER_FSA)); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!AOTCompilation.getValue()); + + appendPhase(new LoweringPhase(canonicalizer)); appendPhase(new ExpandLogicPhase()); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java Fri Sep 13 23:12:10 2013 +0200 @@ -25,7 +25,6 @@ import static com.oracle.graal.phases.GraalOptions.*; import com.oracle.graal.loop.phases.*; -import com.oracle.graal.nodes.spi.Lowerable.LoweringType; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; @@ -47,11 +46,11 @@ appendPhase(new LockEliminationPhase()); if (OptReadElimination.getValue()) { - appendPhase(new EarlyReadEliminationPhase()); + appendPhase(new EarlyReadEliminationPhase(canonicalizer)); } if (OptFloatingReads.getValue()) { - IncrementalCanonicalizerPhase incCanonicalizer = new IncrementalCanonicalizerPhase<>(); + IncrementalCanonicalizerPhase incCanonicalizer = new IncrementalCanonicalizerPhase<>(canonicalizer); incCanonicalizer.appendPhase(new FloatingReadPhase()); appendPhase(incCanonicalizer); if (OptReadElimination.getValue()) { @@ -69,7 +68,7 @@ } if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) { - appendPhase(new IterativeConditionalEliminationPhase()); + appendPhase(new IterativeConditionalEliminationPhase(canonicalizer)); } if (OptEliminatePartiallyRedundantGuards.getValue()) { @@ -86,7 +85,7 @@ appendPhase(new GuardLoweringPhase()); - appendPhase(new LoweringPhase(LoweringType.AFTER_GUARDS)); + appendPhase(new LoweringPhase(canonicalizer)); appendPhase(new FrameStateAssignmentPhase()); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.debug.test/src/com/oracle/graal/debug/test/DebugHistogramTest.java --- a/graal/com.oracle.graal.debug.test/src/com/oracle/graal/debug/test/DebugHistogramTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.debug.test/src/com/oracle/graal/debug/test/DebugHistogramTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -27,6 +27,7 @@ import org.junit.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.internal.*; public class DebugHistogramTest { @@ -34,8 +35,13 @@ public void testEmptyHistogram() { DebugHistogram histogram = Debug.createHistogram("TestHistogram"); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - histogram.print(new PrintStream(outputStream)); + + new DebugHistogramAsciiPrinter(new PrintStream(outputStream)).print(histogram); Assert.assertEquals("TestHistogram is empty.\n", outputStream.toString()); + + outputStream.reset(); + new DebugHistogramRPrinter(new PrintStream(outputStream)).print(histogram); + Assert.assertEquals("", outputStream.toString()); } @Test @@ -44,19 +50,28 @@ ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); histogram.add(new Integer(1)); histogram.add(new Integer(1)); - histogram.print(new PrintStream(outputStream)); + new DebugHistogramAsciiPrinter(new PrintStream(outputStream)).print(histogram); String[] lines = outputStream.toString().split("\n"); - Assert.assertEquals(4, lines.length); - Assert.assertEquals("TestHistogram has 1 unique elements and 2 total elements:", lines[0]); - Assert.assertEquals( - "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------", - lines[1]); - Assert.assertEquals( - "| 1 | 2 | ==================================================================================================== |", - lines[2]); - Assert.assertEquals( - "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------", - lines[3]); + // @formatter:off + String[] expected = { + "TestHistogram has 1 unique elements and 2 total elements:", + "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------", + "| 1 | 2 | ==================================================================================================== |", + "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------" + }; + // @formatter:on + Assert.assertArrayEquals(expected, lines); + + outputStream.reset(); + new DebugHistogramRPrinter(new PrintStream(outputStream)).print(histogram); + lines = outputStream.toString().split("\n"); + // @formatter:off + expected = new String[] { + "TestHistogram <- c(2);", + "names(TestHistogram) <- c(\"1\");" + }; + // @formatter:on + Assert.assertArrayEquals(expected, lines); } @Test @@ -66,22 +81,29 @@ histogram.add(new Integer(1)); histogram.add(new Integer(2)); histogram.add(new Integer(2)); - histogram.print(new PrintStream(outputStream)); + new DebugHistogramAsciiPrinter(new PrintStream(outputStream)).print(histogram); String[] lines = outputStream.toString().split("\n"); - Assert.assertEquals(5, lines.length); - Assert.assertEquals("TestHistogram has 2 unique elements and 3 total elements:", lines[0]); - Assert.assertEquals( - "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------", - lines[1]); - Assert.assertEquals( - "| 2 | 2 | ==================================================================================================== |", - lines[2]); - Assert.assertEquals( - "| 1 | 1 | ================================================== |", - lines[3]); - Assert.assertEquals( - "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------", - lines[4]); + // @formatter:off + String[] expected = new String[] { + "TestHistogram has 2 unique elements and 3 total elements:", + "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------", + "| 2 | 2 | ==================================================================================================== |", + "| 1 | 1 | ================================================== |", + "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------" + }; + // @formatter:on + Assert.assertArrayEquals(expected, lines); + + outputStream.reset(); + new DebugHistogramRPrinter(new PrintStream(outputStream)).print(histogram); + lines = outputStream.toString().split("\n"); + // @formatter:off + expected = new String[] { + "TestHistogram <- c(2, 1);", + "names(TestHistogram) <- c(\"2\", \"1\");" + }; + // @formatter:on + Assert.assertArrayEquals(expected, lines); } @Test @@ -89,7 +111,7 @@ DebugHistogram histogram = Debug.createHistogram("TestHistogram"); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); histogram.add("MyCustomValue"); - histogram.print(new PrintStream(outputStream), Integer.MAX_VALUE, 10, 10); + new DebugHistogramAsciiPrinter(new PrintStream(outputStream), Integer.MAX_VALUE, 10, 10).print(histogram); String[] lines = outputStream.toString().split("\n"); Assert.assertEquals(4, lines.length); Assert.assertEquals("TestHistogram has 1 unique elements and 1 total elements:", lines[0]); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java Fri Sep 13 23:12:10 2013 +0200 @@ -22,24 +22,49 @@ */ package com.oracle.graal.debug; -import com.oracle.graal.debug.internal.*; +import static com.oracle.graal.debug.Debug.Initialization.*; import java.io.*; import java.util.*; import java.util.concurrent.*; +import com.oracle.graal.debug.internal.*; + +/** + * Scope based debugging facility. This facility is {@link #isEnabled()} if assertions are enabled + * for the {@link Debug} class or the {@value Initialization#INITIALIZER_PROPERTY_NAME} system + * property is {@code "true"} when {@link Debug} is initialized. + */ public class Debug { - private static boolean ENABLED = false; + /** + * Class to assist with initialization of {@link Debug}. + */ + public static class Initialization { + + public static final String INITIALIZER_PROPERTY_NAME = "graal.debug.enable"; - public static void enable() { - ENABLED = true; + private static boolean initialized; + + /** + * Determines if {@link Debug} has been initialized. + */ + public static boolean isDebugInitialized() { + return initialized; + } + } - public static void disable() { - ENABLED = false; + @SuppressWarnings("all") + private static boolean initialize() { + boolean assertionsEnabled = false; + assert assertionsEnabled = true; + Initialization.initialized = true; + return assertionsEnabled || Boolean.getBoolean(INITIALIZER_PROPERTY_NAME); } + private static final boolean ENABLED = initialize(); + public static boolean isEnabled() { return ENABLED; } @@ -330,7 +355,7 @@ public static DebugMetric metric(String name) { if (ENABLED) { - return new MetricImpl(name); + return new MetricImpl(name, true); } else { return VOID_METRIC; } @@ -342,6 +367,9 @@ } } + /** + * Creates an object for counting value frequencies. + */ public static DebugHistogram createHistogram(String name) { return new DebugHistogramImpl(name); } @@ -402,11 +430,19 @@ public void add(long value) { } + + public void setConditional(boolean flag) { + throw new InternalError("Cannot make void metric conditional"); + } + + public boolean isConditional() { + return false; + } }; public static DebugTimer timer(String name) { if (ENABLED) { - return new TimerImpl(name); + return new TimerImpl(name, true); } else { return VOID_TIMER; } @@ -417,5 +453,13 @@ public TimerCloseable start() { return TimerImpl.VOID_CLOSEABLE; } + + public void setConditional(boolean flag) { + throw new InternalError("Cannot make void timer conditional"); + } + + public boolean isConditional() { + return false; + } }; } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugHistogram.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugHistogram.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugHistogram.java Fri Sep 13 23:12:10 2013 +0200 @@ -22,15 +22,75 @@ */ package com.oracle.graal.debug; -import java.io.*; +import java.util.*; +/** + * Facility for recording value frequencies. + */ public interface DebugHistogram { + /** + * Gets the name specified when this objected was {@linkplain Debug#createHistogram(String) + * created}. + */ String getName(); + /** + * Increments the count for a given value. + */ void add(Object value); - void print(PrintStream os); + /** + * A value and a frequency. The ordering imposed by {@link #compareTo(CountedValue)} places + * values with higher frequencies first. + */ + public class CountedValue implements Comparable { + + private int count; + private final Object value; + + public CountedValue(int count, Object value) { + this.count = count; + this.value = value; + } + + public int compareTo(CountedValue o) { + if (count < o.count) { + return 1; + } else if (count > o.count) { + return -1; + } + return 0; + } - void print(PrintStream os, int limit, int nameSize, int barSize); + @Override + public String toString() { + return count + " -> " + value; + } + + public void inc() { + count++; + } + + public int getCount() { + return count; + } + + public Object getValue() { + return value; + } + } + + /** + * Gets a list of the counted values, sorted in descending order of frequency. + */ + List getValues(); + + /** + * Interface for a service that can render a visualization of a histogram. + */ + public interface Printer { + + void print(DebugHistogram histogram); + } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugMetric.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugMetric.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugMetric.java Fri Sep 13 23:12:10 2013 +0200 @@ -22,9 +22,32 @@ */ package com.oracle.graal.debug; +/** + * A counter for some value of interest. + */ public interface DebugMetric { + /** + * Adds 1 to this counter if metering is {@link Debug#isMeterEnabled() enabled} or this is an + * {@linkplain #isConditional() unconditional} metric. + */ void increment(); + /** + * Adds {@code value} to this counter if metering is {@link Debug#isMeterEnabled() enabled} or + * this is an {@linkplain #isConditional() unconditional} metric. + */ void add(long value); + + /** + * Sets a flag determining if this counter is only enabled if metering is + * {@link Debug#isMeterEnabled() enabled}. + */ + void setConditional(boolean flag); + + /** + * Determines if this counter is only enabled if metering is {@link Debug#isMeterEnabled() + * enabled}. + */ + boolean isConditional(); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugTimer.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugTimer.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugTimer.java Fri Sep 13 23:12:10 2013 +0200 @@ -24,7 +24,36 @@ import com.oracle.graal.debug.internal.*; +/** + * A timer for some activity of interest. A timer should be deployed using the try-with-resources + * pattern: + * + *
+ * try (TimerCloseable a = timer.start()) {
+ *     // the code to time
+ * }
+ * 
+ */ public interface DebugTimer { + /** + * Starts this timer if timing is {@linkplain Debug#isTimeEnabled() enabled} or this is an + * {@linkplain #isConditional() unconditional} timer. + * + * @return an object that must be closed once the activity has completed to add the elapsed time + * since this call to the total for this timer + */ TimerCloseable start(); + + /** + * Sets a flag determining if this timer is only enabled if metering is + * {@link Debug#isMeterEnabled() enabled}. + */ + void setConditional(boolean flag); + + /** + * Determines if this timer is only enabled if metering is {@link Debug#isMeterEnabled() + * enabled}. + */ + boolean isConditional(); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugHistogramAsciiPrinter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugHistogramAsciiPrinter.java Fri Sep 13 23:12:10 2013 +0200 @@ -0,0 +1,101 @@ +/* + * 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.debug.internal; + +import java.io.*; +import java.util.*; + +import com.oracle.graal.debug.*; +import com.oracle.graal.debug.DebugHistogram.*; + +/** + * Renders a textual representation of a histogram to a given print stream. + */ +public class DebugHistogramAsciiPrinter implements Printer { + + public static final int NumberSize = 10; + public static final int DefaultNameSize = 50; + public static final int DefaultBarSize = 100; + + private PrintStream os; + private int limit; + private int nameSize; + private int barSize; + + public DebugHistogramAsciiPrinter(PrintStream os) { + this(os, Integer.MAX_VALUE, DefaultNameSize, DefaultBarSize); + } + + /** + * @param os where to print + * @param limit limits printing to the {@code limit} most frequent values + * @param nameSize the width of the value names column + * @param barSize the width of the value frequency column + */ + public DebugHistogramAsciiPrinter(PrintStream os, int limit, int nameSize, int barSize) { + this.os = os; + this.limit = limit; + this.nameSize = nameSize; + this.barSize = barSize; + } + + public void print(DebugHistogram histogram) { + List list = histogram.getValues(); + if (list.isEmpty()) { + os.printf("%s is empty.\n", histogram.getName()); + return; + } + + // Sum up the total number of elements. + int total = 0; + for (CountedValue cv : list) { + total += cv.getCount(); + } + + // Print header. + os.printf("%s has %d unique elements and %d total elements:\n", histogram.getName(), list.size(), total); + + int max = list.get(0).getCount(); + final int lineSize = nameSize + NumberSize + barSize + 10; + printLine(os, '-', lineSize); + String formatString = "| %-" + nameSize + "s | %-" + NumberSize + "d | %-" + barSize + "s |\n"; + for (int i = 0; i < list.size() && i < limit; ++i) { + CountedValue cv = list.get(i); + int value = cv.getCount(); + char[] bar = new char[(int) (((double) value / (double) max) * barSize)]; + Arrays.fill(bar, '='); + String objectString = String.valueOf(cv.getValue()); + if (objectString.length() > nameSize) { + objectString = objectString.substring(0, nameSize - 3) + "..."; + } + os.printf(formatString, objectString, value, new String(bar)); + } + printLine(os, '-', lineSize); + } + + private static void printLine(PrintStream printStream, char c, int lineSize) { + char[] charArr = new char[lineSize]; + Arrays.fill(charArr, c); + printStream.printf("%s\n", new String(charArr)); + } +} diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugHistogramImpl.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugHistogramImpl.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugHistogramImpl.java Fri Sep 13 23:12:10 2013 +0200 @@ -22,28 +22,25 @@ */ package com.oracle.graal.debug.internal; -import java.io.*; import java.util.*; import com.oracle.graal.debug.*; public class DebugHistogramImpl implements DebugHistogram { - public static final int NumberSize = 10; - public static final int DefaultNameSize = 50; - public static final int DefaultBarSize = 100; private final String name; - private HashMap map = new HashMap<>(); + private HashMap map = new HashMap<>(); public DebugHistogramImpl(String name) { this.name = name; } public void add(Object value) { - if (!map.containsKey(value)) { - map.put(value, 1); + CountedValue cv = map.get(value); + if (cv == null) { + map.put(value, new CountedValue(1, value)); } else { - map.put(value, map.get(value) + 1); + cv.inc(); } } @@ -52,59 +49,9 @@ return name; } - @Override - public void print(PrintStream os) { - print(os, Integer.MAX_VALUE, DefaultNameSize, DefaultBarSize); - } - - public void print(PrintStream os, int limit, int nameSize, int barSize) { - - List list = new ArrayList<>(map.keySet()); - if (list.size() == 0) { - // No elements in the histogram. - os.printf("%s is empty.\n", name); - return; - } - - // Sort from highest to smallest. - Collections.sort(list, new Comparator() { - - @Override - public int compare(Object o1, Object o2) { - return map.get(o2) - map.get(o1); - } - }); - - // Sum up the total number of elements. - int total = 0; - for (Object o : list) { - total += map.get(o); - } - - // Print header. - os.printf("%s has %d unique elements and %d total elements:\n", name, list.size(), total); - - int max = map.get(list.get(0)); - final int lineSize = nameSize + NumberSize + barSize + 10; - printLine(os, '-', lineSize); - String formatString = "| %-" + nameSize + "s | %-" + NumberSize + "d | %-" + barSize + "s |\n"; - for (int i = 0; i < list.size() && i < limit; ++i) { - Object o = list.get(i); - int value = map.get(o); - char[] bar = new char[(int) (((double) value / (double) max) * barSize)]; - Arrays.fill(bar, '='); - String objectString = o.toString(); - if (objectString.length() > nameSize) { - objectString = objectString.substring(0, nameSize - 3) + "..."; - } - os.printf(formatString, objectString, value, new String(bar)); - } - printLine(os, '-', lineSize); - } - - private static void printLine(PrintStream printStream, char c, int lineSize) { - char[] charArr = new char[lineSize]; - Arrays.fill(charArr, c); - printStream.printf("%s\n", new String(charArr)); + public List getValues() { + ArrayList res = new ArrayList<>(map.values()); + Collections.sort(res); + return res; } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugHistogramRPrinter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugHistogramRPrinter.java Fri Sep 13 23:12:10 2013 +0200 @@ -0,0 +1,81 @@ +/* + * 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.debug.internal; + +import java.io.*; +import java.util.*; + +import com.oracle.graal.debug.*; +import com.oracle.graal.debug.DebugHistogram.CountedValue; +import com.oracle.graal.debug.DebugHistogram.Printer; + +/** + * Renders a histogram as an R script to a given print stream. The R script emitted for a histogram + * is a simple set of statements for defining a vector of named objects. + */ +public class DebugHistogramRPrinter implements Printer { + + private PrintStream os; + private int limit; + + public DebugHistogramRPrinter(PrintStream os) { + this(os, Integer.MAX_VALUE); + } + + /** + * @param os where to print + * @param limit limits printing to the {@code limit} most frequent values + */ + public DebugHistogramRPrinter(PrintStream os, int limit) { + this.os = os; + this.limit = limit; + } + + public void print(DebugHistogram histogram) { + List list = histogram.getValues(); + if (list.isEmpty()) { + return; + } + + String var = histogram.getName().replace('-', '.').replace(' ', '_'); + os.print(var + " <- c("); + for (int i = 0; i < list.size() && i < limit; ++i) { + CountedValue cv = list.get(i); + if (i != 0) { + os.print(", "); + } + os.print(cv.getCount()); + } + os.println(");"); + + os.print("names(" + var + ") <- c("); + for (int i = 0; i < list.size() && i < limit; ++i) { + CountedValue cv = list.get(i); + if (i != 0) { + os.print(", "); + } + os.print("\"" + cv.getValue() + "\""); + } + os.println(");"); + } +} diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java Fri Sep 13 23:12:10 2013 +0200 @@ -92,7 +92,6 @@ private static ThreadLocal instanceTL = new ThreadLocal<>(); private static ThreadLocal configTL = new ThreadLocal<>(); private static ThreadLocal lastExceptionThrownTL = new ThreadLocal<>(); - private static DebugTimer scopeTime = Debug.timer("ScopeTime"); private final DebugScope parent; private IndentImpl lastUsedIndent; @@ -239,7 +238,7 @@ } instanceTL.set(newChild); newChild.updateFlags(); - try (TimerCloseable a = scopeTime.start()) { + try { return executeScope(runnable, callable); } finally { newChild.context = null; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugValue.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugValue.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugValue.java Fri Sep 13 23:12:10 2013 +0200 @@ -30,10 +30,12 @@ private final String name; private int index; + private boolean conditional; - protected DebugValue(String name) { + protected DebugValue(String name, boolean conditional) { this.name = name; this.index = -1; + this.conditional = conditional; } protected long getCurrentValue() { @@ -46,6 +48,14 @@ DebugScope.getInstance().setCurrentValue(index, l); } + public void setConditional(boolean flag) { + conditional = flag; + } + + public boolean isConditional() { + return conditional; + } + private void ensureInitialized() { if (index == -1) { index = KeyRegistry.register(this); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/MetricImpl.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/MetricImpl.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/MetricImpl.java Fri Sep 13 23:12:10 2013 +0200 @@ -26,8 +26,8 @@ public final class MetricImpl extends DebugValue implements DebugMetric { - public MetricImpl(String name) { - super(name); + public MetricImpl(String name, boolean conditional) { + super(name, conditional); } public void increment() { @@ -35,7 +35,7 @@ } public void add(long value) { - if (Debug.isMeterEnabled()) { + if (!isConditional() || Debug.isMeterEnabled()) { super.addToCurrentValue(value); } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/TimerCloseable.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/TimerCloseable.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/TimerCloseable.java Fri Sep 13 23:12:10 2013 +0200 @@ -22,6 +22,12 @@ */ package com.oracle.graal.debug.internal; +import com.oracle.graal.debug.*; + +/** + * An object returned by {@link DebugTimer#start()} that when closed, stops the associated timer and + * adds the elapsed time since {@code start()} to the total for the timer. + */ public interface TimerCloseable extends AutoCloseable { void close(); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/TimerImpl.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/TimerImpl.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/TimerImpl.java Fri Sep 13 23:12:10 2013 +0200 @@ -37,59 +37,78 @@ } }; - private ThreadLocal valueToSubstract = new ThreadLocal<>(); + /** + * Records the most recent active timer. + */ + private static ThreadLocal currentTimer = new ThreadLocal<>(); + + private final DebugValue flat; - public TimerImpl(String name) { - super(name); + public TimerImpl(String name, boolean conditional) { + super(name + "_Accm", conditional); + this.flat = new DebugValue(name + "_Flat", conditional) { + + @Override + public String toString(long value) { + return valueToString(value); + } + }; } @Override public TimerCloseable start() { - if (Debug.isTimeEnabled()) { + if (!isConditional() || Debug.isTimeEnabled()) { long startTime; if (threadMXBean.isCurrentThreadCpuTimeSupported()) { startTime = threadMXBean.getCurrentThreadCpuTime(); } else { startTime = System.nanoTime(); } - if (valueToSubstract.get() == null) { - valueToSubstract.set(0L); - } - long previousValueToSubstract = valueToSubstract.get(); + AbstractTimer result; if (threadMXBean.isCurrentThreadCpuTimeSupported()) { - result = new CpuTimeTimer(startTime, previousValueToSubstract); + result = new CpuTimeTimer(startTime); } else { - result = new SystemNanosTimer(startTime, previousValueToSubstract); + result = new SystemNanosTimer(startTime); } - valueToSubstract.set(0L); + currentTimer.set(result); return result; } else { return VOID_CLOSEABLE; } } + public static String valueToString(long value) { + return String.format("%d.%d ms", value / 1000000, (value / 100000) % 10); + } + @Override public String toString(long value) { - return String.format("%d.%d ms", value / 1000000, (value / 100000) % 10); + return valueToString(value); } private abstract class AbstractTimer implements TimerCloseable { + private final AbstractTimer parent; private final long startTime; - private final long previousValueToSubstract; + private long nestedTimeToSubtract; - private AbstractTimer(long startTime, long previousValueToSubstract) { + private AbstractTimer(long startTime) { + this.parent = currentTimer.get(); this.startTime = startTime; - this.previousValueToSubstract = previousValueToSubstract; } @Override public void close() { - long timeSpan = currentTime() - startTime; - long oldValueToSubstract = valueToSubstract.get(); - valueToSubstract.set(timeSpan + previousValueToSubstract); - TimerImpl.this.addToCurrentValue(timeSpan - oldValueToSubstract); + long endTime = currentTime(); + long timeSpan = endTime - startTime; + if (parent != null) { + parent.nestedTimeToSubtract += timeSpan; + } + currentTimer.set(parent); + long flatTime = timeSpan - nestedTimeToSubtract; + TimerImpl.this.addToCurrentValue(timeSpan); + flat.addToCurrentValue(flatTime); } protected abstract long currentTime(); @@ -97,8 +116,8 @@ private final class SystemNanosTimer extends AbstractTimer { - public SystemNanosTimer(long startTime, long previousValueToSubstract) { - super(startTime, previousValueToSubstract); + public SystemNanosTimer(long startTime) { + super(startTime); } @Override @@ -109,8 +128,8 @@ private final class CpuTimeTimer extends AbstractTimer { - public CpuTimeTimer(long startTime, long previousValueToSubstract) { - super(startTime, previousValueToSubstract); + public CpuTimeTimer(long startTime) { + super(startTime); } @Override diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/TypedNodeIteratorTest.java --- a/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/TypedNodeIteratorTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/TypedNodeIteratorTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -32,7 +32,7 @@ public class TypedNodeIteratorTest { - private static class TestNode extends Node implements Node.IterableNodeType, TestNodeInterface { + private static class TestNode extends Node implements IterableNodeType, TestNodeInterface { private final String name; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/TypedNodeIteratorTest2.java --- a/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/TypedNodeIteratorTest2.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/TypedNodeIteratorTest2.java Fri Sep 13 23:12:10 2013 +0200 @@ -43,7 +43,7 @@ } } - private static class NodeB extends NodeA implements Node.IterableNodeType { + private static class NodeB extends NodeA implements IterableNodeType { public NodeB(String name) { super(name); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Fri Sep 13 23:12:10 2013 +0200 @@ -25,7 +25,6 @@ import java.util.*; import com.oracle.graal.graph.GraphEvent.NodeEvent; -import com.oracle.graal.graph.Node.IterableNodeType; import com.oracle.graal.graph.Node.ValueNumberable; import com.oracle.graal.graph.iterators.*; @@ -125,37 +124,49 @@ } } + int extractOriginalNodeId(Node node) { + int id = node.id; + if (id <= Node.DELETED_ID_START) { + id = Node.DELETED_ID_START - id; + } + return id; + } + int modCount(Node node) { - if (node.id >= 0 && node.id < nodeModCounts.length) { - return nodeModCounts[node.id]; + int id = extractOriginalNodeId(node); + if (id >= 0 && id < nodeModCounts.length) { + return nodeModCounts[id]; } return 0; } void incModCount(Node node) { - if (node.id >= 0) { - if (node.id >= nodeModCounts.length) { - nodeModCounts = Arrays.copyOf(nodeModCounts, node.id + 30); + int id = extractOriginalNodeId(node); + if (id >= 0) { + if (id >= nodeModCounts.length) { + nodeModCounts = Arrays.copyOf(nodeModCounts, id + 30); } - nodeModCounts[node.id]++; + nodeModCounts[id]++; } else { assert false; } } int usageModCount(Node node) { - if (node.id >= 0 && node.id < nodeUsageModCounts.length) { - return nodeUsageModCounts[node.id]; + int id = extractOriginalNodeId(node); + if (id >= 0 && id < nodeUsageModCounts.length) { + return nodeUsageModCounts[id]; } return 0; } void incUsageModCount(Node node) { - if (node.id >= 0) { - if (node.id >= nodeUsageModCounts.length) { - nodeUsageModCounts = Arrays.copyOf(nodeUsageModCounts, node.id + 30); + int id = extractOriginalNodeId(node); + if (id >= 0) { + if (id >= nodeUsageModCounts.length) { + nodeUsageModCounts = Arrays.copyOf(nodeUsageModCounts, id + 30); } - nodeUsageModCounts[node.id]++; + nodeUsageModCounts[id]++; } else { assert false; } @@ -506,7 +517,7 @@ * {@code type}. * * @param type the type of node to return - * @return an {@link Iterable} providing all the matching nodes. + * @return an {@link Iterable} providing all the matching nodes */ public NodeIterable getNodes(final Class type) { final NodeClass nodeClass = NodeClass.get(type); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.graph/src/com/oracle/graal/graph/IterableNodeType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/IterableNodeType.java Fri Sep 13 23:12:10 2013 +0200 @@ -0,0 +1,32 @@ +/* + * 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.graph; + +/** + * A marker for a node type supporting {@linkplain Graph#getNodes(Class) fast iteration} of its + * instances in a graph. The support for fast iteration comes with a memory cost (e.g., extra data + * structures {@link Graph}) so only node types for which fast iteration provides a compilation + * performance benefit should implement this interface. + */ +public interface IterableNodeType { +} diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Fri Sep 13 23:12:10 2013 +0200 @@ -111,9 +111,6 @@ public interface ValueNumberable { } - public interface IterableNodeType { - } - private Graph graph; int id; @@ -236,11 +233,7 @@ if (usage1 == null) { return 1; } - int count = 2; - for (int i = 0; i < extraUsages.length && extraUsages[i] != null; i++) { - count++; - } - return count; + return 2 + indexOfLastNonNull(extraUsages) + 1; } } @@ -252,6 +245,40 @@ } /** + * Finds the index of the last non-null entry in a node array. The search assumes that all + * non-null entries precede the first null entry in the array. + * + * @param nodes the array to search + * @return the index of the last non-null entry in {@code nodes} if it exists, else -1 + */ + private static int indexOfLastNonNull(Node[] nodes) { + if (nodes.length == 0 || nodes[0] == null) { + return -1; + } + if (nodes[nodes.length - 1] != null) { + return nodes.length - 1; + } + + // binary search + int low = 0; + int high = nodes.length - 1; + while (true) { + int mid = (low + high) >>> 1; + if (nodes[mid] == null) { + if (nodes[mid - 1] != null) { + return mid - 1; + } + high = mid - 1; + } else { + if (mid == nodes.length - 1 || nodes[mid + 1] == null) { + return mid; + } + low = mid + 1; + } + } + } + + /** * Adds a given node to this node's {@linkplain #usages() usages}. * * @param node the node to add @@ -264,37 +291,23 @@ usage1 = node; } else { int length = extraUsages.length; - int start = extraUsages.length >> 1; - if (start < length && extraUsages[start] == null) { - start = 0; - } - for (int i = start; i < length; i++) { - if (extraUsages[i] == null) { - extraUsages[i] = node; - return; + if (length == 0) { + extraUsages = new Node[4]; + extraUsages[0] = node; + } else { + int lastNonNull = indexOfLastNonNull(extraUsages); + if (lastNonNull == length - 1) { + extraUsages = Arrays.copyOf(extraUsages, length * 2 + 1); + extraUsages[length] = node; + } else if (lastNonNull == -1) { + extraUsages[0] = node; + } else { + extraUsages[lastNonNull + 1] = node; } } - extraUsages = Arrays.copyOf(extraUsages, length * 2 + 1); - extraUsages[length] = node; } } - private Node removeFirstExtraUsage() { - Node res = null; - if (extraUsages.length > 0) { - res = extraUsages[0]; - for (int i = 1; i < extraUsages.length; ++i) { - Node n = extraUsages[i]; - extraUsages[i - 1] = n; - if (n == null) { - break; - } - } - extraUsages[extraUsages.length - 1] = null; - } - return res; - } - /** * Removes a given node from this node's {@linkplain #usages() usages}. * @@ -305,36 +318,47 @@ // It is critical that this method maintains the invariant that // the usage list has no null element preceding a non-null element incUsageModCount(); - if (usage0 == null) { - return false; - } if (usage0 == node) { - usage0 = usage1; if (usage1 != null) { - usage1 = removeFirstExtraUsage(); + int lastNonNull = indexOfLastNonNull(extraUsages); + if (lastNonNull >= 0) { + usage0 = extraUsages[lastNonNull]; + extraUsages[lastNonNull] = null; + } else { + // usage1 is the last element + usage0 = usage1; + usage1 = null; + } + } else { + // usage0 is the last element + usage0 = null; } return true; } - if (usage1 == null) { - return false; - } if (usage1 == node) { - usage1 = removeFirstExtraUsage(); + int lastNonNull = indexOfLastNonNull(extraUsages); + if (lastNonNull >= 0) { + usage1 = extraUsages[lastNonNull]; + extraUsages[lastNonNull] = null; + } else { + // usage1 is the last element + usage1 = null; + } return true; } - int length = extraUsages.length; - for (int i = 0; i < length; i++) { - if (extraUsages[i] == node) { - for (int j = i + 1; j < length; j++) { - Node toMove = extraUsages[j]; - extraUsages[j - 1] = toMove; - if (toMove == null) { - break; + int lastNonNull = indexOfLastNonNull(extraUsages); + if (lastNonNull >= 0) { + for (int i = 0; i <= lastNonNull; ++i) { + Node n = extraUsages[i]; + if (n == node) { + if (i < lastNonNull) { + extraUsages[i] = extraUsages[lastNonNull]; + extraUsages[lastNonNull] = null; + } else { + extraUsages[i] = null; } + return true; } - extraUsages[length - 1] = null; - - return true; } } return false; diff -r 2bd626188d31 -r e9fc19eb3efb 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 Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Fri Sep 13 23:12:10 2013 +0200 @@ -31,7 +31,6 @@ import com.oracle.graal.graph.Graph.DuplicationReplacement; import com.oracle.graal.graph.Node.Input; -import com.oracle.graal.graph.Node.IterableNodeType; import com.oracle.graal.graph.Node.Successor; import com.oracle.graal.graph.Node.Verbosity; @@ -185,14 +184,14 @@ } this.nameTemplate = newNameTemplate == null ? newShortName : newNameTemplate; this.shortName = newShortName; - if (Node.IterableNodeType.class.isAssignableFrom(clazz)) { + if (IterableNodeType.class.isAssignableFrom(clazz)) { this.iterableId = nextIterableId++; List existingClasses = new LinkedList<>(); for (FieldIntrospection nodeClass : allClasses.values()) { if (clazz.isAssignableFrom(nodeClass.clazz)) { existingClasses.add((NodeClass) nodeClass); } - if (nodeClass.clazz.isAssignableFrom(clazz) && Node.IterableNodeType.class.isAssignableFrom(nodeClass.clazz)) { + if (nodeClass.clazz.isAssignableFrom(clazz) && IterableNodeType.class.isAssignableFrom(nodeClass.clazz)) { NodeClass superNodeClass = (NodeClass) nodeClass; superNodeClass.iterableIds = Arrays.copyOf(superNodeClass.iterableIds, superNodeClass.iterableIds.length + 1); superNodeClass.iterableIds[superNodeClass.iterableIds.length - 1] = this.iterableId; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Fri Sep 13 23:12:10 2013 +0200 @@ -45,7 +45,7 @@ import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.LIRInstruction.ValueProcedure; -import com.oracle.graal.lir.StandardOp.ParametersOp; +import com.oracle.graal.lir.StandardOp.LabelOp; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.nodes.*; @@ -214,7 +214,7 @@ }; for (Block block : lir.codeEmittingOrder()) { for (LIRInstruction op : lir.lir(block)) { - if (op instanceof ParametersOp) { + if (op instanceof LabelOp) { // Don't consider this as a definition } else { op.forEachTemp(defProc); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Fri Sep 13 23:12:10 2013 +0200 @@ -46,7 +46,6 @@ import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.StandardOp.ParametersOp; import com.oracle.graal.lir.StandardOp.PlaceholderOp; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.amd64.AMD64ControlFlow.CondMoveOp; @@ -162,9 +161,8 @@ } } params[params.length - 1] = rbpParam; - ParametersOp paramsOp = new ParametersOp(params); - append(paramsOp); + emitIncomingValues(params); saveRbp = new SaveRbp(new PlaceholderOp(currentBlock, lir.lir(currentBlock).size())); append(saveRbp.placeholder); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java Fri Sep 13 23:12:10 2013 +0200 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.ptx; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.*; +import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.asm.*; +import com.oracle.graal.nodes.*; + +/** + * HotSpot PTX specific backend. + */ +public class PTXHotSpotBackend extends HotSpotBackend { + + public PTXHotSpotBackend(HotSpotRuntime runtime, TargetDescription target) { + super(runtime, target); + } + + @Override + public FrameMap newFrameMap() { + throw new InternalError("NYI"); + } + + @Override + public TargetMethodAssembler newAssembler(LIRGenerator lirGen, CompilationResult compilationResult) { + throw new InternalError("NYI"); + } + + @Override + public void emitCode(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod installedCodeOwner) { + throw new InternalError("NYI"); + } + + @Override + protected AbstractAssembler createAssembler(FrameMap frameMap) { + throw new InternalError("NYI"); + } + + @Override + public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir) { + throw new InternalError("NYI"); + } +} diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotGraalRuntime.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotGraalRuntime.java Fri Sep 13 23:12:10 2013 +0200 @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.ptx; + +import com.oracle.graal.ptx.*; +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.*; + +/** + * PTX specific implementation of {@link HotSpotGraalRuntime}. + */ +public class PTXHotSpotGraalRuntime extends HotSpotGraalRuntime { + + protected PTXHotSpotGraalRuntime() { + } + + /** + * Called from C++ code to retrieve the singleton instance, creating it first if necessary. + */ + public static HotSpotGraalRuntime makeInstance() { + HotSpotGraalRuntime graalRuntime = graalRuntime(); + if (graalRuntime == null) { + HotSpotGraalRuntimeFactory factory = findFactory("PTX"); + if (factory != null) { + graalRuntime = factory.createRuntime(); + } else { + graalRuntime = new PTXHotSpotGraalRuntime(); + } + graalRuntime.completeInitialization(); + } + return graalRuntime; + } + + protected Architecture createArchitecture() { + return new PTX(); + } + + @Override + protected TargetDescription createTarget() { + final int stackFrameAlignment = 16; + final int implicitNullCheckLimit = 4096; + final boolean inlineObjects = true; + return new TargetDescription(createArchitecture(), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects); + } + + @Override + protected HotSpotBackend createBackend() { + return new PTXHotSpotBackend(getRuntime(), getTarget()); + } + + @Override + protected HotSpotRuntime createRuntime() { + return new PTXHotSpotRuntime(config, this); + } + + @Override + protected Value[] getNativeABICallerSaveRegisters() { + throw new InternalError("NYI"); + } +} diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotRegisterConfig.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotRegisterConfig.java Fri Sep 13 23:12:10 2013 +0200 @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.ptx; + +import static com.oracle.graal.ptx.PTX.*; + +import java.util.*; + +import com.oracle.graal.ptx.*; +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.CallingConvention.Type; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; + +public class PTXHotSpotRegisterConfig implements RegisterConfig { + + private final Architecture architecture; + + private final Register[] allocatable; + + private final HashMap categorized = new HashMap<>(); + + private final RegisterAttributes[] attributesMap; + + @Override + public Register[] getAllocatableRegisters() { + return allocatable.clone(); + } + + public Register[] getAllocatableRegisters(PlatformKind kind) { + if (categorized.containsKey(kind)) { + return categorized.get(kind); + } + + ArrayList list = new ArrayList<>(); + for (Register reg : getAllocatableRegisters()) { + if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) { + list.add(reg); + } + } + + Register[] ret = list.toArray(new Register[0]); + categorized.put(kind, ret); + return ret; + } + + @Override + public RegisterAttributes[] getAttributesMap() { + return attributesMap.clone(); + } + + private final Register[] javaGeneralParameterRegisters; + private final Register[] nativeGeneralParameterRegisters; + + private static Register[] initAllocatable() { + Register[] registers = new Register[] { + param0, param1, param2, param3, + param4, param5, param6, param7, + r0, r1, r2, r3, r4, r5, r6, r7, + r8, r9, r10, r11, r12, r13, r14, r15, + retReg, + }; + + return registers; + } + + public PTXHotSpotRegisterConfig(Architecture architecture) { + this.architecture = architecture; + + javaGeneralParameterRegisters = paramRegisters; + nativeGeneralParameterRegisters = gprRegisters; + + allocatable = initAllocatable(); + attributesMap = RegisterAttributes.createMap(this, PTX.allRegisters); + } + + @Override + public Register[] getCallerSaveRegisters() { + // No caller save registers; return empty array + return new Register[]{}; + } + + @Override + public Register getRegisterForRole(int index) { + throw new UnsupportedOperationException(); + } + + @Override + public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target, boolean stackOnly) { + if (type == Type.NativeCall) { + return callingConvention(nativeGeneralParameterRegisters, returnType, parameterTypes, type, target, stackOnly); + } + return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, type, target, stackOnly); + } + + public Register[] getCallingConventionRegisters(Type type, Kind kind) { + assert architecture.canStoreValue(REG, kind); + return type == Type.NativeCall ? nativeGeneralParameterRegisters : javaGeneralParameterRegisters; + } + + private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, Type type, TargetDescription target, boolean stackOnly) { + AllocatableValue[] locations = new AllocatableValue[parameterTypes.length]; + + int currentGeneral = 0; + int currentStackOffset = 0; + + for (int i = 0; i < parameterTypes.length; i++) { + final Kind kind = parameterTypes[i].getKind(); + + switch (kind) { + case Byte: + case Boolean: + case Short: + case Char: + case Int: + case Long: + case Float: + case Double: + case Object: + if (!stackOnly && currentGeneral < generalParameterRegisters.length) { + Register register = generalParameterRegisters[currentGeneral++]; + locations[i] = register.asValue(kind); + } + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + + if (locations[i] == null) { + locations[i] = StackSlot.get(kind.getStackKind(), currentStackOffset, !type.out); + currentStackOffset += Math.max(target.arch.getSizeInBytes(kind), target.wordSize); + } + } + + Kind returnKind = returnType == null ? Kind.Void : returnType.getKind(); + AllocatableValue returnLocation = returnKind == Kind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(returnKind); + return new CallingConvention(currentStackOffset, returnLocation, locations); + } + + @Override + public Register getReturnRegister(Kind kind) { + switch (kind) { + case Boolean: + case Byte: + case Char: + case Short: + case Int: + case Long: + case Object: + case Float: + case Double: + return retReg; + case Void: + case Illegal: + return null; + default: + throw new UnsupportedOperationException("no return register for type " + kind); + } + } + + @Override + public Register getFrameRegister() { + // No frame register + return null; + } + + public CalleeSaveLayout getCalleeSaveLayout() { + return null; + } + + @Override + public String toString() { + return String.format("Allocatable: " + Arrays.toString(getAllocatableRegisters()) + "%n" + "CallerSave: " + Arrays.toString(getCallerSaveRegisters()) + "%n"); + } +} diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotRuntime.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotRuntime.java Fri Sep 13 23:12:10 2013 +0200 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.ptx; + +import static com.oracle.graal.ptx.PTX.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.nodes.spi.*; + +public class PTXHotSpotRuntime extends HotSpotRuntime { + + public PTXHotSpotRuntime(HotSpotVMConfig config, HotSpotGraalRuntime graalRuntime) { + super(config, graalRuntime); + + } + + @Override + public void registerReplacements(Replacements replacements) { + //TODO: Do we need to implement this functionality for PTX? + } + + // PTX code does not use stack or stack pointer + @Override + public Register stackPointerRegister() { + return Register.None; + } + + // PTX code does not have heap register + @Override + public Register heapBaseRegister() { + return Register.None; + } + + // Thread register is %tid. + @Override + public Register threadRegister() { + return tid; + } + + @Override + protected RegisterConfig createRegisterConfig() { + return new PTXHotSpotRegisterConfig(graalRuntime.getTarget().arch); + } +} diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -39,7 +39,6 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.HeapAccess.BarrierType; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.Lowerable.LoweringType; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; @@ -249,10 +248,10 @@ StructuredGraph graph = parse(snippet); HighTierContext highContext = new HighTierContext(runtime(), new Assumptions(false), replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); MidTierContext midContext = new MidTierContext(runtime(), new Assumptions(false), replacements, runtime().getTarget(), OptimisticOptimizations.ALL); - new InliningPhase(new InliningPhase.InlineEverythingPolicy()).apply(graph, highContext); - new LoweringPhase(LoweringType.BEFORE_GUARDS).apply(graph, highContext); + new InliningPhase(new InliningPhase.InlineEverythingPolicy(), new CanonicalizerPhase(true)).apply(graph, highContext); + new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, highContext); new GuardLoweringPhase().apply(graph, midContext); - new LoweringPhase(LoweringType.AFTER_GUARDS).apply(graph, midContext); + new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, midContext); new WriteBarrierAdditionPhase().apply(graph); Debug.dump(graph, "After Write Barrier Addition"); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -36,7 +36,6 @@ import com.oracle.graal.hotspot.phases.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.Lowerable.LoweringType; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.graph.*; @@ -633,14 +632,14 @@ public AssertionError call() { final StructuredGraph graph = parse(snippet); HighTierContext highTierContext = new HighTierContext(runtime(), new Assumptions(false), replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); - new InliningPhase().apply(graph, highTierContext); + new InliningPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext); MidTierContext midTierContext = new MidTierContext(runtime(), new Assumptions(false), replacements, runtime().getTarget(), OptimisticOptimizations.ALL); - new LoweringPhase(LoweringType.BEFORE_GUARDS).apply(graph, highTierContext); + new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext); new GuardLoweringPhase().apply(graph, midTierContext); new SafepointInsertionPhase().apply(graph); - new LoweringPhase(LoweringType.AFTER_GUARDS).apply(graph, highTierContext); + new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext); new WriteBarrierAdditionPhase().apply(graph); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerThread.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerThread.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerThread.java Fri Sep 13 23:12:10 2013 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.hotspot; -import static com.oracle.graal.compiler.GraalDebugConfig.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import java.io.*; @@ -52,7 +51,7 @@ @Override public void run() { GraalDebugConfig hotspotDebugConfig = null; - if (DebugEnabled.getValue()) { + if (Debug.isEnabled()) { PrintStream log = graalRuntime().getVMToCompiler().log(); DebugEnvironment.initialize(log); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java Fri Sep 13 23:12:10 2013 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.hotspot; +import static com.oracle.graal.compiler.GraalDebugConfig.*; import static java.nio.file.Files.*; import java.io.*; @@ -30,6 +31,7 @@ import java.nio.file.*; import java.util.*; +import com.oracle.graal.debug.*; import com.oracle.graal.hotspot.logging.*; import com.oracle.graal.options.*; @@ -174,6 +176,19 @@ } /** + * Called from VM code once all Graal command line options have been processed by + * {@link #setOption(String)}. + * + * @param ciTime the value of the CITime HotSpot VM option + */ + public static void finalizeOptions(boolean ciTime) { + if (areDebugScopePatternsEnabled() || ciTime) { + assert !Debug.Initialization.isDebugInitialized(); + System.setProperty(Debug.Initialization.INITIALIZER_PROPERTY_NAME, "true"); + } + } + + /** * Wraps some given text to one or more lines of a given maximum width. * * @param text text to wrap diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Fri Sep 13 23:12:10 2013 +0200 @@ -38,7 +38,7 @@ private static final long serialVersionUID = -4744897993263044184L; - private final HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean(); + private static final HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean(); HotSpotVMConfig(CompilerToVM c2vm) { c2vm.initializeConfiguration(this); @@ -52,9 +52,9 @@ * @return value of option * @throws IllegalArgumentException if option doesn't exist */ - private int getVMOptionInt(String name) { + public static int getVMOptionInt(String name) { String value = diagnostic.getVMOption(name).getValue(); - return new Integer(value).intValue(); + return Integer.valueOf(value).intValue(); } /** @@ -64,7 +64,7 @@ * @param defaultValue default value if option is not exists (e.g. development options) * @return value of option or defaultValue if option doesn't exist */ - private int getVMOption(String name, int defaultValue) { + public static int getVMOption(String name, int defaultValue) { try { return getVMOptionInt(name); } catch (IllegalArgumentException e) { @@ -79,9 +79,9 @@ * @return value of option * @throws IllegalArgumentException if option doesn't exist */ - private boolean getVMOption(String name) { + public static boolean getVMOption(String name) { String value = diagnostic.getVMOption(name).getValue(); - return new Boolean(value).booleanValue(); + return Boolean.valueOf(value).booleanValue(); } /** @@ -91,7 +91,7 @@ * @param defaultValue default value if option is not exists (e.g. development options) * @return value of option or defaultValue if option doesn't exist */ - private boolean getVMOption(String name, boolean defaultValue) { + public static boolean getVMOption(String name, boolean defaultValue) { try { return getVMOption(name); } catch (IllegalArgumentException e) { diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Fri Sep 13 23:12:10 2013 +0200 @@ -29,6 +29,7 @@ import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.java.GraphBuilderPhase.*; import static com.oracle.graal.phases.GraalOptions.*; +import static com.oracle.graal.phases.common.InliningUtil.*; import java.io.*; import java.lang.reflect.*; @@ -51,7 +52,6 @@ import com.oracle.graal.options.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; -import com.oracle.graal.phases.common.*; import com.oracle.graal.printer.*; import com.oracle.graal.replacements.*; @@ -105,8 +105,6 @@ private PrintStream log = System.out; - private boolean quietMeterAndTime; - private long compilerStartTime; public VMToCompilerImpl(HotSpotGraalRuntime compiler) { @@ -165,13 +163,12 @@ } if (config.ciTime) { - quietMeterAndTime = (Meter.getValue() == null && Time.getValue() == null); - DebugEnabled.setValue(true); - Meter.setValue(""); - Time.setValue(""); + BytecodesParsed.setConditional(false); + InlinedBytecodes.setConditional(false); + CompilationTime.setConditional(false); } - if (DebugEnabled.getValue()) { + if (Debug.isEnabled()) { DebugEnvironment.initialize(log); String summary = DebugValueSummary.getValue(); @@ -374,7 +371,7 @@ CompilationStatistics.clear(phase); if (graalRuntime.getConfig().ciTime) { parsedBytecodesPerSecond = MetricRateInPhase.snapshot(phase, parsedBytecodesPerSecond, BytecodesParsed, CompilationTime, TimeUnit.SECONDS); - inlinedBytecodesPerSecond = MetricRateInPhase.snapshot(phase, inlinedBytecodesPerSecond, InliningUtil.InlinedBytecodes, CompilationTime, TimeUnit.SECONDS); + inlinedBytecodesPerSecond = MetricRateInPhase.snapshot(phase, inlinedBytecodesPerSecond, InlinedBytecodes, CompilationTime, TimeUnit.SECONDS); } } @@ -476,7 +473,7 @@ CompilationTask.withinEnqueue.set(Boolean.FALSE); } - if (Debug.isEnabled() && !quietMeterAndTime) { + if (Debug.isEnabled() && areDebugScopePatternsEnabled()) { List topLevelMaps = DebugValueMap.getTopLevelMaps(); List debugValues = KeyRegistry.getDebugValues(); if (debugValues.size() > 0) { diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Fri Sep 13 23:12:10 2013 +0200 @@ -167,7 +167,7 @@ return true; } - private static final String SystemClassName = MetaUtil.toInternalName(System.class.getName()); + private static final String SystemClassName = "Ljava/lang/System;"; @Override public Constant readConstantValue(Constant receiver) { diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Fri Sep 13 23:12:10 2013 +0200 @@ -85,7 +85,6 @@ import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.spi.Lowerable.LoweringType; import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.tiers.*; @@ -637,11 +636,11 @@ graph.replaceFixedWithFixed(storeIndexed, memoryWrite); } else if (n instanceof UnsafeLoadNode) { - if (tool.getLoweringType().ordinal() > LoweringType.BEFORE_GUARDS.ordinal()) { + if (graph.getGuardsPhase().ordinal() > StructuredGraph.GuardsStage.FLOATING_GUARDS.ordinal()) { UnsafeLoadNode load = (UnsafeLoadNode) n; assert load.kind() != Kind.Illegal; boolean compressible = (!load.object().isNullConstant() && load.accessKind() == Kind.Object); - if (addReadBarrier(load, tool)) { + if (addReadBarrier(load)) { unsafeLoadSnippets.lower(load, tool); } else { IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, load.accessKind(), load.displacement(), load.offset(), graph, 1); @@ -676,14 +675,8 @@ StoreHubNode storeHub = (StoreHubNode) n; WriteNode hub = createWriteHub(graph, wordKind, storeHub.getObject(), storeHub.getValue()); graph.replaceFixed(storeHub, hub); - } else if (n instanceof FixedGuardNode) { - FixedGuardNode node = (FixedGuardNode) n; - GuardingNode guard = tool.createGuard(node.condition(), node.getReason(), node.getAction(), node.isNegated()); - ValueAnchorNode newAnchor = graph.add(new ValueAnchorNode(guard.asNode())); - node.replaceAtUsages(guard.asNode()); - graph.replaceFixedWithFixed(node, newAnchor); } else if (n instanceof CommitAllocationNode) { - if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) { + if (graph.getGuardsPhase() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { CommitAllocationNode commit = (CommitAllocationNode) n; ValueNode[] allocations = new ValueNode[commit.getVirtualObjects().size()]; @@ -759,7 +752,7 @@ graph.removeFixed(commit); } } else if (n instanceof OSRStartNode) { - if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) { + if (graph.getGuardsPhase() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { OSRStartNode osrStart = (OSRStartNode) n; StartNode newStart = graph.add(new StartNode()); LocalNode buffer = graph.unique(new LocalNode(0, StampFactory.forKind(wordKind()))); @@ -788,31 +781,31 @@ } else if (n instanceof CheckCastDynamicNode) { checkcastDynamicSnippets.lower((CheckCastDynamicNode) n); } else if (n instanceof InstanceOfNode) { - if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) { + if (graph.getGuardsPhase() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { instanceofSnippets.lower((InstanceOfNode) n, tool); } } else if (n instanceof InstanceOfDynamicNode) { - if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) { + if (graph.getGuardsPhase() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { instanceofSnippets.lower((InstanceOfDynamicNode) n, tool); } } else if (n instanceof NewInstanceNode) { - if (tool.getLoweringType() == LoweringType.AFTER_FSA) { + if (graph.getGuardsPhase() == StructuredGraph.GuardsStage.AFTER_FSA) { newObjectSnippets.lower((NewInstanceNode) n); } } else if (n instanceof NewArrayNode) { - if (tool.getLoweringType() == LoweringType.AFTER_FSA) { + if (graph.getGuardsPhase() == StructuredGraph.GuardsStage.AFTER_FSA) { newObjectSnippets.lower((NewArrayNode) n); } } else if (n instanceof DynamicNewArrayNode) { - if (tool.getLoweringType() == LoweringType.AFTER_FSA) { + if (graph.getGuardsPhase() == StructuredGraph.GuardsStage.AFTER_FSA) { newObjectSnippets.lower((DynamicNewArrayNode) n); } } else if (n instanceof MonitorEnterNode) { - if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) { + if (graph.getGuardsPhase() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { monitorSnippets.lower((MonitorEnterNode) n, tool); } } else if (n instanceof MonitorExitNode) { - if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) { + if (graph.getGuardsPhase() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { monitorSnippets.lower((MonitorExitNode) n, tool); } } else if (n instanceof G1PreWriteBarrier) { @@ -830,7 +823,7 @@ } else if (n instanceof G1ArrayRangePostWriteBarrier) { writeBarrierSnippets.lower((G1ArrayRangePostWriteBarrier) n, tool); } else if (n instanceof NewMultiArrayNode) { - if (tool.getLoweringType() == LoweringType.AFTER_FSA) { + if (graph.getGuardsPhase() == StructuredGraph.GuardsStage.AFTER_FSA) { newObjectSnippets.lower((NewMultiArrayNode) n); } } else if (n instanceof LoadExceptionObjectNode) { @@ -850,8 +843,8 @@ } } - private static boolean addReadBarrier(UnsafeLoadNode load, LoweringTool tool) { - if (useG1GC() && tool.getLoweringType() == LoweringType.AFTER_GUARDS && load.object().kind() == Kind.Object && load.accessKind() == Kind.Object && + private static boolean addReadBarrier(UnsafeLoadNode load) { + if (useG1GC() && load.graph().getGuardsPhase() == StructuredGraph.GuardsStage.FIXED_DEOPTS && load.object().kind() == Kind.Object && load.accessKind() == Kind.Object && !ObjectStamp.isObjectAlwaysNull(load.object())) { ResolvedJavaType type = ObjectStamp.typeOrNull(load.object()); if (type != null && !type.isArray()) { diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CStringNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CStringNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CStringNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -44,7 +44,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { byte[] formatBytes = string.getBytes(); long cstring = unsafe.allocateMemory(formatBytes.length + 1); for (int i = 0; i < formatBytes.length; i++) { diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/VerifyHotSpotOptionsPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/VerifyHotSpotOptionsPhase.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/VerifyHotSpotOptionsPhase.java Fri Sep 13 23:12:10 2013 +0200 @@ -57,31 +57,41 @@ for (OptionDescriptor desc : opts) { if (HotSpotOptions.isHotSpotOption(desc)) { HotSpotResolvedObjectType holder = (HotSpotResolvedObjectType) runtime.lookupJavaType(desc.getDeclaringClass()); - if (!checked.contains(holder)) { - checked.add(holder); - for (ResolvedJavaMethod method : holder.getMethods()) { - if (method.isClassInitializer()) { - StructuredGraph graph = new StructuredGraph(method); - new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); - new VerifyHotSpotOptionsPhase(holder, runtime).apply(graph); - } - } - } + checkType(holder, desc, runtime, checked); } } } return true; } + private static void checkType(HotSpotResolvedObjectType type, OptionDescriptor option, HotSpotRuntime runtime, Set checked) { + if (!checked.contains(type)) { + checked.add(type); + HotSpotResolvedObjectType superType = type.getSupertype(); + if (superType != null && !MetaUtil.isJavaLangObject(superType)) { + checkType(superType, option, runtime, checked); + } + for (ResolvedJavaMethod method : type.getMethods()) { + if (method.isClassInitializer()) { + StructuredGraph graph = new StructuredGraph(method); + new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); + new VerifyHotSpotOptionsPhase(type, runtime, option).apply(graph); + } + } + } + } + private final HotSpotRuntime runtime; private final ResolvedJavaType declaringClass; private final ResolvedJavaType optionValueType; private final Set boxingTypes; + private final OptionDescriptor option; - public VerifyHotSpotOptionsPhase(ResolvedJavaType declaringClass, HotSpotRuntime runtime) { + public VerifyHotSpotOptionsPhase(ResolvedJavaType declaringClass, HotSpotRuntime runtime, OptionDescriptor option) { this.runtime = runtime; this.declaringClass = declaringClass; this.optionValueType = runtime.lookupJavaType(OptionValue.class); + this.option = option; this.boxingTypes = new HashSet<>(); for (Class c : new Class[]{Boolean.class, Byte.class, Short.class, Character.class, Integer.class, Float.class, Long.class, Double.class}) { this.boxingTypes.add(runtime.lookupJavaType(c)); @@ -136,7 +146,9 @@ private void error(Node node, String message) { String loc = GraphUtil.approxSourceLocation(node); - throw new GraalInternalError(String.format("HotSpot option declarer %s contains code pattern implying action other than initialization of an option:%n %s%n %s", + throw new GraalInternalError(String.format("The " + option.getName() + " option is declared in " + option.getDeclaringClass() + + " whose class hierarchy contains a class initializer (in %s) with a code pattern at or near %s implying an action other than initialization of an option:%n%n %s%n%n" + + "The recommended solution is to move " + option.getName() + " into a separate class (e.g., " + option.getDeclaringClass().getName() + ".Options).%n", toJavaName(declaringClass), loc, message)); } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -26,7 +26,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; -import com.oracle.graal.graph.Node.IterableNodeType; import com.oracle.graal.loop.phases.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -37,7 +36,7 @@ import com.oracle.graal.phases.tiers.*; import com.oracle.graal.replacements.nodes.*; -public class ArrayCopyNode extends MacroNode implements Virtualizable, IterableNodeType, Lowerable { +public class ArrayCopyNode extends MacroNode implements Virtualizable, Lowerable { public ArrayCopyNode(Invoke invoke) { super(invoke); @@ -87,7 +86,7 @@ // additions, etc. PhaseContext context = new PhaseContext(tool.getRuntime(), tool.assumptions(), tool.getReplacements()); new CanonicalizerPhase(true).apply(snippetGraph, context); - new LoopFullUnrollPhase(true).apply(snippetGraph, context); + new LoopFullUnrollPhase(new CanonicalizerPhase(true)).apply(snippetGraph, context); new CanonicalizerPhase(true).apply(snippetGraph, context); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -66,7 +66,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { ConstantNode target = getConstantCallTarget(tool.getRuntime(), tool.assumptions()); if (target != null) { diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Fri Sep 13 23:12:10 2013 +0200 @@ -167,7 +167,7 @@ */ public static boolean clearPendingException(Word thread) { boolean result = thread.readObject(threadPendingExceptionOffset(), PENDING_EXCEPTION_LOCATION) != null; - thread.writeObject(threadPendingExceptionOffset(), null); + thread.writeObject(threadPendingExceptionOffset(), null, PENDING_EXCEPTION_LOCATION); return result; } @@ -178,7 +178,7 @@ */ public static Object getAndClearObjectResult(Word thread) { Object result = thread.readObject(objectResultOffset(), OBJECT_RESULT_LOCATION); - thread.writeObject(objectResultOffset(), null); + thread.writeObject(objectResultOffset(), null, OBJECT_RESULT_LOCATION); return result; } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -47,7 +47,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { ConstantNode callerClassNode = getCallerClassNode(tool.getRuntime()); if (callerClassNode != null) { diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopyNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopyNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopyNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -92,8 +92,8 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { - if (loweringType == LoweringType.AFTER_FSA) { + public void lower(LoweringTool tool) { + if (graph().getGuardsPhase() == StructuredGraph.GuardsStage.AFTER_FSA) { UnsafeArrayCopySnippets.Templates templates = tool.getReplacements().getSnippetTemplateCache(UnsafeArrayCopySnippets.Templates.class); templates.lower(this); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Fri Sep 13 23:12:10 2013 +0200 @@ -112,7 +112,7 @@ * jump. When the block is seen the second time, a MergeNode is created to correctly merge the * now two different predecessor states. */ - private static class BlockPlaceholderNode extends FixedWithNextNode implements Node.IterableNodeType { + private static class BlockPlaceholderNode extends FixedWithNextNode implements IterableNodeType { public BlockPlaceholderNode() { super(StampFactory.forVoid()); @@ -242,7 +242,7 @@ // remove dead FrameStates for (Node n : currentGraph.getNodes(FrameState.class)) { - if (n.usages().count() == 0 && n.predecessor() == null) { + if (n.usages().isEmpty() && n.predecessor() == null) { n.safeDelete(); } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64FrameMap.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64FrameMap.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64FrameMap.java Fri Sep 13 23:12:10 2013 +0200 @@ -28,12 +28,12 @@ /** * AMD64 specific frame map. - * + * * This is the format of an AMD64 stack frame: - * + * *
  *   Base       Contents
- * 
+ *
  *            :                                :  -----
  *   caller   | incoming overflow argument n   |    ^
  *   frame    :     ...                        :    | positive
@@ -55,9 +55,9 @@
  *            :     ...                        :    | positive   |      |
  *            | outgoing overflow argument 0   |    | offsets    v      v
  *    %sp-->  +--------------------------------+---------------------------
- * 
+ *
  * 
- * + * * The spill slot area also includes stack allocated memory blocks (ALLOCA blocks). The size of such * a block may be greater than the size of a normal spill slot or the word size. *

@@ -67,7 +67,7 @@ * call-free methods also have this space reserved. Then the VM can use the memory at offset 0 * relative to the stack pointer. */ -public final class AMD64FrameMap extends FrameMap { +public class AMD64FrameMap extends FrameMap { public AMD64FrameMap(CodeCacheProvider runtime, TargetDescription target, RegisterConfig registerConfig) { super(runtime, target, registerConfig); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMemOp.java --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMemOp.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMemOp.java Fri Sep 13 23:12:10 2013 +0200 @@ -208,6 +208,12 @@ case Long: masm.ld_return_address("u64", asRegister(result), addr.getBase(), addr.getDisplacement()); break; + case Float: + masm.ld_return_address("f32", asRegister(result), addr.getBase(), addr.getDisplacement()); + break; + case Double: + masm.ld_return_address("f64", asRegister(result), addr.getBase(), addr.getDisplacement()); + break; default: throw GraalInternalError.shouldNotReachHere(); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXParameterOp.java --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXParameterOp.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXParameterOp.java Fri Sep 13 23:12:10 2013 +0200 @@ -48,6 +48,9 @@ for (int i = 0; i < argCount; i++) { Kind paramKind = params[i].getKind(); switch (paramKind) { + case Byte : + masm.param_8_decl(asRegister(params[i]), (i == (argCount - 1))); + break; case Int : masm.param_32_decl(asIntReg(params[i]), (i == (argCount - 1))); break; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java Fri Sep 13 23:12:10 2013 +0200 @@ -116,7 +116,7 @@ /** * Gets the frame size of the compiled frame, not including the size of the * {@link Architecture#getReturnAddressSize() return address slot}. - * + * * @return The size of the frame (in bytes). */ public int frameSize() { @@ -136,7 +136,7 @@ /** * Gets the total frame size of the compiled frame, including the size of the * {@link Architecture#getReturnAddressSize() return address slot}. - * + * * @return The total size of the frame (in bytes). */ public abstract int totalFrameSize(); @@ -149,7 +149,7 @@ /** * Aligns the given frame size to the stack alignment size and return the aligned size. - * + * * @param size the initial frame size to be aligned * @return the aligned frame size */ @@ -181,7 +181,7 @@ /** * Computes the offset of a stack slot relative to the frame register. - * + * * @param slot a stack slot * @return the offset of the stack slot */ @@ -197,7 +197,7 @@ /** * Computes the index of a stack slot relative to slot 0. This is also the bit index of stack * slots in the reference map. - * + * * @param slot a stack slot * @return the index of the stack slot */ @@ -209,7 +209,7 @@ /** * Gets the offset from the stack pointer to the stack area where callee-saved registers are * stored. - * + * * @return The offset to the callee save area (in bytes). */ public abstract int offsetToCalleeSaveArea(); @@ -217,7 +217,7 @@ /** * Informs the frame map that the compiled code calls a particular method, which may need stack * space for outgoing arguments. - * + * * @param cc The calling convention for the called method. */ public void callsMethod(CallingConvention cc) { @@ -226,7 +226,7 @@ /** * Reserves space for stack-based outgoing arguments. - * + * * @param argsSize The amount of space (in bytes) to reserve for stack-based outgoing arguments. */ public void reserveOutgoing(int argsSize) { @@ -239,7 +239,7 @@ * Reserves a new spill slot in the frame of the method being compiled. The returned slot is * aligned on its natural alignment, i.e., an 8-byte spill slot is aligned at an 8-byte * boundary. - * + * * @param kind The kind of the spill slot to be reserved. * @param additionalOffset * @return A spill slot denoting the reserved memory area. @@ -247,9 +247,20 @@ protected abstract StackSlot allocateNewSpillSlot(PlatformKind kind, int additionalOffset); /** + * Returns the spill slot size for the given {@link PlatformKind}. + * The default value is the size in bytes for the target architecture. + * @param kind the {@link PlatformKind} to be stored in the spill slot. + * @return the size in bytes + */ + protected int spillSlotSize(PlatformKind kind) { + return target.arch.getSizeInBytes(kind); + } + + /** * Reserves a spill slot in the frame of the method being compiled. The returned slot is aligned - * on its natural alignment, i.e., an 8-byte spill slot is aligned at an 8-byte boundary. - * + * on its natural alignment, i.e., an 8-byte spill slot is aligned at an 8-byte boundary, + * unless overridden by a subclass. + * * @param kind The kind of the spill slot to be reserved. * @return A spill slot denoting the reserved memory area. */ @@ -267,7 +278,7 @@ } } } - int size = target.arch.getSizeInBytes(kind); + int size = spillSlotSize(kind); spillSize = NumUtil.roundUp(spillSize + size, size); return allocateNewSpillSlot(kind, 0); } @@ -288,7 +299,7 @@ /** * Reserves a block of memory in the frame of the method being compiled. The returned block is * aligned on a word boundary. If the requested size is 0, the method returns {@code null}. - * + * * @param size The size to reserve (in bytes). * @param refs Specifies if the block is all references. If true, the block will be in all * reference maps for this method. The caller is responsible to initialize the memory @@ -340,7 +351,7 @@ * Marks the specified location as a reference in the reference map of the debug information. * The tracked location can be a {@link RegisterValue} or a {@link StackSlot}. Note that a * {@link Constant} is automatically tracked. - * + * * @param location The location to be added to the reference map. * @param registerRefMap A register reference map, as created by {@link #initRegisterRefMap()}. * @param frameRefMap A frame reference map, as created by {@link #initFrameRefMap()}. diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java Fri Sep 13 23:12:10 2013 +0200 @@ -54,12 +54,30 @@ */ public static class LabelOp extends LIRInstruction { + private static final Value[] NO_VALUES = new Value[0]; + + /** + * In the LIR, every register and variable must be defined before it is used. For method + * parameters that are passed in fixed registers, exception objects passed to the exception + * handler in a fixed register, or any other use of a fixed register not defined in this + * method, an artificial definition is necessary. To avoid spill moves to be inserted + * between the label at the beginning of a block an an actual definition in the second + * instruction of a block, the registers are defined here in the label. + */ + @Def({REG, STACK}) private Value[] incomingValues; + private final Label label; private final boolean align; public LabelOp(Label label, boolean align) { this.label = label; this.align = align; + this.incomingValues = NO_VALUES; + } + + public void setIncomingValues(Value[] values) { + assert incomingValues.length == 0; + incomingValues = values; } @Override @@ -121,25 +139,6 @@ } /** - * Meta-operation that defines the incoming method parameters. In the LIR, every register and - * variable must be defined before it is used. This operation is the definition point of method - * parameters, but is otherwise a no-op. In particular, it is not the actual method prologue. - */ - public static final class ParametersOp extends LIRInstruction { - - @Def({REG, STACK}) protected Value[] params; - - public ParametersOp(Value[] params) { - this.params = params; - } - - @Override - public void emitCode(TargetMethodAssembler tasm) { - // No code to emit. - } - } - - /** * Placeholder for a LIR instruction that will be subsequently replaced. */ public static class PlaceholderOp extends LIRInstruction { diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java Fri Sep 13 23:12:10 2013 +0200 @@ -231,7 +231,7 @@ StructuredGraph graph = graph(); if (endsToMerge.size() == 1) { AbstractEndNode end = endsToMerge.get(0); - assert end.usages().count() == 0; + assert end.usages().isEmpty(); newExit = graph.add(new BeginNode()); end.replaceAtPredecessor(newExit); end.safeDelete(); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java Fri Sep 13 23:12:10 2013 +0200 @@ -25,13 +25,13 @@ import static com.oracle.graal.phases.GraalOptions.*; import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.NodeClass.NodeClassIterator; import com.oracle.graal.graph.NodeClass.Position; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.tiers.*; public abstract class LoopTransformations { @@ -53,7 +53,7 @@ loop.inside().duplicate().insertBefore(loop); } - public static void fullUnroll(LoopEx loop, MetaAccessProvider runtime, Assumptions assumptions, boolean canonicalizeReads) { + public static void fullUnroll(LoopEx loop, PhaseContext context, CanonicalizerPhase canonicalizer) { // assert loop.isCounted(); //TODO (gd) strenghten : counted with known trip count int iterations = 0; LoopBeginNode loopBegin = loop.loopBegin(); @@ -61,7 +61,7 @@ while (!loopBegin.isDeleted()) { int mark = graph.getMark(); peel(loop); - new CanonicalizerPhase.Instance(runtime, assumptions, canonicalizeReads, mark, null).apply(graph); + canonicalizer.applyIncremental(graph, context, mark); if (iterations++ > UNROLL_LIMIT || graph.getNodeCount() > MaximumDesiredSize.getValue() * 3) { throw new BailoutException("FullUnroll : Graph seems to grow out of proportion"); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopFullUnrollPhase.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopFullUnrollPhase.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopFullUnrollPhase.java Fri Sep 13 23:12:10 2013 +0200 @@ -26,15 +26,16 @@ import com.oracle.graal.loop.*; import com.oracle.graal.nodes.*; import com.oracle.graal.phases.*; +import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; public class LoopFullUnrollPhase extends BasePhase { private static final DebugMetric FULLY_UNROLLED_LOOPS = Debug.metric("FullUnrolls"); - private final boolean canonicalizeReads; + private final CanonicalizerPhase canonicalizer; - public LoopFullUnrollPhase(boolean canonicalizeReads) { - this.canonicalizeReads = canonicalizeReads; + public LoopFullUnrollPhase(CanonicalizerPhase canonicalizer) { + this.canonicalizer = canonicalizer; } @Override @@ -48,7 +49,7 @@ for (LoopEx loop : dataCounted.countedLoops()) { if (LoopPolicies.shouldFullUnroll(loop)) { Debug.log("FullUnroll %s", loop); - LoopTransformations.fullUnroll(loop, context.getRuntime(), context.getAssumptions(), canonicalizeReads); + LoopTransformations.fullUnroll(loop, context, canonicalizer); FULLY_UNROLLED_LOOPS.increment(); Debug.dump(graph, "After fullUnroll %s", loop); peeled = true; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractBeginNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractBeginNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractBeginNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -32,7 +32,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -public abstract class AbstractBeginNode extends FixedWithNextNode implements StateSplit, LIRLowerable, Simplifiable, Node.IterableNodeType, GuardingNode { +public abstract class AbstractBeginNode extends FixedWithNextNode implements StateSplit, LIRLowerable, Simplifiable, GuardingNode { @Input(notDataflow = true) private FrameState stateAfter; @@ -185,9 +185,4 @@ throw new UnsupportedOperationException(); } } - - @Override - public AbstractBeginNode asNode() { - return this; - } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractEndNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractEndNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractEndNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -28,7 +28,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -public abstract class AbstractEndNode extends FixedNode implements Node.IterableNodeType, LIRLowerable { +public abstract class AbstractEndNode extends FixedNode implements IterableNodeType, LIRLowerable { protected AbstractEndNode() { super(StampFactory.forVoid()); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSinkNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSinkNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSinkNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -25,7 +25,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.type.*; -public abstract class ControlSinkNode extends FixedNode implements Node.IterableNodeType { +public abstract class ControlSinkNode extends FixedNode implements IterableNodeType { public ControlSinkNode(Stamp stamp) { super(stamp); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -37,7 +37,7 @@ * */ @NodeInfo(shortName = "Deopt", nameTemplate = "Deopt {p#reason/s}") -public class DeoptimizeNode extends ControlSinkNode implements Node.IterableNodeType, Lowerable, LIRLowerable, DeoptimizingNode { +public class DeoptimizeNode extends ControlSinkNode implements IterableNodeType, Lowerable, LIRLowerable, DeoptimizingNode { @Input private FrameState deoptState; @@ -59,7 +59,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EntryMarkerNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EntryMarkerNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EntryMarkerNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -29,7 +29,7 @@ * This node will be inserted at point specified by {@link StructuredGraph#getEntryBCI()}, usually * by the graph builder. */ -public class EntryMarkerNode extends AbstractBeginNode implements Node.IterableNodeType, Simplifiable, LIRLowerable { +public class EntryMarkerNode extends AbstractBeginNode implements IterableNodeType, Simplifiable, LIRLowerable { @Override public void simplify(SimplifierTool tool) { diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -31,7 +31,7 @@ import com.oracle.graal.nodes.util.*; @NodeInfo(nameTemplate = "FixedGuard(!={p#negated}) {p#reason/s}") -public final class FixedGuardNode extends DeoptimizingFixedWithNextNode implements Simplifiable, Lowerable, Node.IterableNodeType, GuardingNode { +public final class FixedGuardNode extends DeoptimizingFixedWithNextNode implements Simplifiable, Lowerable, IterableNodeType, GuardingNode { @Input private LogicNode condition; private final DeoptimizationReason reason; @@ -106,9 +106,12 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { - if (loweringType == LoweringType.BEFORE_GUARDS) { - tool.getRuntime().lower(this, tool); + public void lower(LoweringTool tool) { + if (graph().getGuardsPhase() == StructuredGraph.GuardsStage.FLOATING_GUARDS) { + GuardingNode guard = tool.createGuard(condition(), getReason(), getAction(), isNegated()); + ValueAnchorNode newAnchor = graph().add(new ValueAnchorNode(guard.asNode())); + this.replaceAtUsages(guard.asNode()); + graph().replaceFixedWithFixed(this, newAnchor); } else { FixedNode next = next(); setNext(null); @@ -130,11 +133,6 @@ } @Override - public FixedGuardNode asNode() { - return this; - } - - @Override public boolean canDeoptimize() { return true; } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -35,4 +35,9 @@ assertTrue(this.successors().isNotEmpty() || this.predecessor() != null, "FixedNode should not float"); return super.verify(); } + + @Override + public FixedNode asNode() { + return this; + } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FloatingGuardedNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FloatingGuardedNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FloatingGuardedNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -49,10 +49,4 @@ updateUsages(this.guard == null ? null : this.guard.asNode(), guard == null ? null : guard.asNode()); this.guard = guard; } - - @Override - public FloatingNode asNode() { - return this; - } - } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java Fri Sep 13 23:12:10 2013 +0200 @@ -35,7 +35,7 @@ * stack) at a particular point in the abstract interpretation. */ @NodeInfo(nameTemplate = "FrameState@{p#method/s}:{p#bci}") -public final class FrameState extends VirtualState implements Node.IterableNodeType { +public final class FrameState extends VirtualState implements IterableNodeType { protected final int localsSize; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -42,7 +42,7 @@ * control flow would have reached the guarded node (without taking exceptions into account). */ @NodeInfo(nameTemplate = "Guard(!={p#negated}) {p#reason/s}") -public final class GuardNode extends FloatingGuardedNode implements Canonicalizable, Node.IterableNodeType, GuardingNode, GuardedNode { +public final class GuardNode extends FloatingGuardedNode implements Canonicalizable, IterableNodeType, GuardingNode, GuardedNode { @Input private LogicNode condition; private final DeoptimizationReason reason; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardedValueNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardedValueNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardedValueNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -34,7 +34,7 @@ * * A GuardedValueNode will only go away if its guard is null or {@link StructuredGraph#start()}. */ -public class GuardedValueNode extends FloatingGuardedNode implements LIRLowerable, Virtualizable, Node.IterableNodeType, GuardingNode, Canonicalizable, ValueProxy { +public class GuardedValueNode extends FloatingGuardedNode implements LIRLowerable, Virtualizable, IterableNodeType, GuardingNode, Canonicalizable, ValueProxy { @Input private ValueNode object; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -76,8 +76,8 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { - if (loweringType == LoweringType.AFTER_GUARDS) { + public void lower(LoweringTool tool) { + if (graph().getGuardsPhase() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { throw new GraalInternalError("Cannot create guards in after-guard lowering"); } FixedGuardNode guard = graph().add(new FixedGuardNode(condition, reason, action, negated)); @@ -115,11 +115,6 @@ @ConstantNodeParameter DeoptimizationAction action, @ConstantNodeParameter Stamp stamp); @Override - public ValueNode asNode() { - return this; - } - - @Override public ValueNode getOriginalValue() { return object; } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InfopointNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InfopointNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InfopointNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -23,14 +23,13 @@ package com.oracle.graal.nodes; import com.oracle.graal.api.code.*; -import com.oracle.graal.graph.Node.IterableNodeType; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; /** * Nodes of this type are inserted into the graph to denote points of interest to debugging. */ -public class InfopointNode extends AbstractStateSplit implements LIRLowerable, IterableNodeType { +public class InfopointNode extends AbstractStateSplit implements LIRLowerable { public final InfopointReason reason; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -35,7 +35,7 @@ * The {@code InvokeNode} represents all kinds of method calls. */ @NodeInfo(nameTemplate = "Invoke#{p#targetMethod/s}") -public final class InvokeNode extends AbstractStateSplit implements StateSplit, Node.IterableNodeType, Invoke, LIRLowerable, MemoryCheckpoint.Single { +public final class InvokeNode extends AbstractStateSplit implements StateSplit, IterableNodeType, Invoke, LIRLowerable, MemoryCheckpoint.Single { @Input private CallTargetNode callTarget; @Input private FrameState deoptState; @@ -108,7 +108,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } @@ -133,11 +133,6 @@ } @Override - public FixedNode asNode() { - return this; - } - - @Override public FrameState stateDuring() { FrameState stateAfter = stateAfter(); if (stateAfter == null) { diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -32,7 +32,7 @@ import com.oracle.graal.nodes.util.*; @NodeInfo(nameTemplate = "Invoke!#{p#targetMethod/s}") -public class InvokeWithExceptionNode extends ControlSplitNode implements Node.IterableNodeType, Invoke, MemoryCheckpoint.Single, LIRLowerable { +public class InvokeWithExceptionNode extends ControlSplitNode implements IterableNodeType, Invoke, MemoryCheckpoint.Single, LIRLowerable { private static final double EXCEPTION_PROBA = 1e-5; @@ -119,11 +119,6 @@ } @Override - public FixedNode asNode() { - return this; - } - - @Override public void setNext(FixedNode x) { if (x != null) { this.setNext(AbstractBeginNode.begin(x)); @@ -133,7 +128,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LocalNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LocalNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LocalNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -29,7 +29,7 @@ * The {@code Local} instruction is a placeholder for an incoming argument to a function call. */ @NodeInfo(nameTemplate = "Local({p#index})") -public final class LocalNode extends AbstractLocalNode implements Node.IterableNodeType { +public final class LocalNode extends AbstractLocalNode implements IterableNodeType { public LocalNode(int index, Stamp stamp) { super(index, stamp); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNegationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNegationNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNegationNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -28,7 +28,7 @@ /** * Logic node that negates its argument. */ -public class LogicNegationNode extends LogicNode implements Canonicalizable, Node.IterableNodeType { +public class LogicNegationNode extends LogicNode implements Canonicalizable, IterableNodeType { @Input private LogicNode input; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -30,4 +30,22 @@ public LogicNode() { super(StampFactory.condition()); } + + public static LogicNode and(LogicNode a, LogicNode b, double shortCircuitProbability) { + return and(a, false, b, false, shortCircuitProbability); + } + + public static LogicNode and(LogicNode a, boolean negateA, LogicNode b, boolean negateB, double shortCircuitProbability) { + StructuredGraph graph = a.graph(); + ShortCircuitOrNode notAorNotB = graph.unique(new ShortCircuitOrNode(a, !negateA, b, !negateB, shortCircuitProbability)); + return graph.unique(new LogicNegationNode(notAorNotB)); + } + + public static LogicNode or(LogicNode a, LogicNode b, double shortCircuitProbability) { + return or(a, false, b, false, shortCircuitProbability); + } + + public static LogicNode or(LogicNode a, boolean negateA, LogicNode b, boolean negateB, double shortCircuitProbability) { + return a.graph().unique(new ShortCircuitOrNode(a, negateA, b, negateB, shortCircuitProbability)); + } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -31,7 +31,7 @@ import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; -public class LoopBeginNode extends MergeNode implements Node.IterableNodeType, LIRLowerable { +public class LoopBeginNode extends MergeNode implements IterableNodeType, LIRLowerable { private double loopFrequency; private int nextEndIndex; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopEndNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopEndNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopEndNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -72,7 +72,7 @@ @Override public boolean verify() { assertTrue(loopBegin != null, "must have a loop begin"); - assertTrue(usages().count() == 0, "LoopEnds can not be used"); + assertTrue(usages().isEmpty(), "LoopEnds can not be used"); return super.verify(); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopExitNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopExitNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopExitNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -22,9 +22,10 @@ */ package com.oracle.graal.nodes; +import com.oracle.graal.graph.*; import com.oracle.graal.nodes.spi.*; -public class LoopExitNode extends BeginStateSplitNode { +public class LoopExitNode extends BeginStateSplitNode implements IterableNodeType { @Input(notDataflow = true) private LoopBeginNode loopBegin; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -33,7 +33,7 @@ /** * Denotes the merging of multiple control-flow paths. */ -public class MergeNode extends BeginStateSplitNode implements Node.IterableNodeType, LIRLowerable { +public class MergeNode extends BeginStateSplitNode implements IterableNodeType, LIRLowerable { @Input(notDataflow = true) private final NodeInputList ends = new NodeInputList<>(this); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -34,7 +34,7 @@ * variable. */ @NodeInfo(nameTemplate = "{p#type/s}Phi({i#values})") -public class PhiNode extends FloatingNode implements Canonicalizable, Node.IterableNodeType, GuardingNode { +public class PhiNode extends FloatingNode implements Canonicalizable, IterableNodeType, GuardingNode { public static enum PhiType { Value(null), // normal value phis @@ -248,9 +248,4 @@ public boolean isLoopPhi() { return merge() instanceof LoopBeginNode; } - - @Override - public PhiNode asNode() { - return this; - } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -36,7 +36,7 @@ * is as narrow or narrower than the PiNode's type. The PiNode, and therefore also the scheduling * restriction enforced by the anchor, will go away. */ -public class PiNode extends FloatingGuardedNode implements LIRLowerable, Virtualizable, Node.IterableNodeType, GuardingNode, Canonicalizable, ValueProxy { +public class PiNode extends FloatingGuardedNode implements LIRLowerable, Virtualizable, IterableNodeType, GuardingNode, Canonicalizable, ValueProxy { @Input private ValueNode object; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -35,7 +35,7 @@ * loop. */ @NodeInfo(nameTemplate = "{p#type/s}Proxy") -public class ProxyNode extends FloatingNode implements Node.IterableNodeType, ValueNumberable, Canonicalizable, Virtualizable, LIRLowerable, ValueProxy, GuardingNode { +public class ProxyNode extends FloatingNode implements IterableNodeType, ValueNumberable, Canonicalizable, Virtualizable, LIRLowerable, ValueProxy, GuardingNode { @Input(notDataflow = true) private AbstractBeginNode proxyPoint; @Input private ValueNode value; @@ -120,8 +120,4 @@ public ValueNode getOriginalValue() { return value; } - - public ValueNode asNode() { - return this; - } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ReturnNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ReturnNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ReturnNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -26,7 +26,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -public final class ReturnNode extends ControlSinkNode implements LIRLowerable, Node.IterableNodeType { +public final class ReturnNode extends ControlSinkNode implements LIRLowerable, IterableNodeType { @Input private ValueNode result; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SafepointNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SafepointNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SafepointNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -30,7 +30,7 @@ /** * Marks a position in the graph where a safepoint should be emitted. */ -public class SafepointNode extends DeoptimizingFixedWithNextNode implements LIRLowerable, Node.IterableNodeType { +public class SafepointNode extends DeoptimizingFixedWithNextNode implements LIRLowerable, IterableNodeType { public SafepointNode() { this(StampFactory.forVoid()); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ShortCircuitAndNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ShortCircuitAndNode.java Thu Sep 05 16:36:40 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2013, 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.nodes; - -import com.oracle.graal.nodes.spi.*; - -/** - * The short-circuit AND (i.e. {@code &&} in Java) operator. - */ -public class ShortCircuitAndNode extends ShortCircuitBooleanNode implements Canonicalizable { - - public ShortCircuitAndNode(LogicNode x, boolean xNegated, LogicNode y, boolean yNegated, double shortCircuitProbability) { - super(x, xNegated, y, yNegated, shortCircuitProbability); - } - - @Override - public LogicNode canonical(CanonicalizerTool tool) { - ShortCircuitBooleanNode ret = canonicalizeNegation(); - if (ret != null) { - return ret; - } - - LogicNode x = getX(); - LogicNode y = getY(); - if (x == y) { - // @formatter:off - // a && a = a - // a && !a = false - // !a && a = false - // !a && !a = !a - // @formatter:on - if (isXNegated()) { - if (isYNegated()) { - // !a && !a = !a - return graph().unique(new LogicNegationNode(x)); - } else { - // !a && a = false - return LogicConstantNode.contradiction(graph()); - } - } else { - if (isYNegated()) { - // a && !a = false - return LogicConstantNode.contradiction(graph()); - } else { - // a && a = a - return x; - } - } - } - if (x instanceof LogicConstantNode) { - if (((LogicConstantNode) x).getValue() ^ isXNegated()) { - if (isYNegated()) { - return graph().unique(new LogicNegationNode(y)); - } else { - return y; - } - } else { - return LogicConstantNode.contradiction(graph()); - } - } - if (y instanceof LogicConstantNode) { - if (((LogicConstantNode) y).getValue() ^ isYNegated()) { - if (isXNegated()) { - return graph().unique(new LogicNegationNode(x)); - } else { - return x; - } - } else { - return LogicConstantNode.contradiction(graph()); - } - } - return this; - } - - @Override - protected ShortCircuitBooleanNode createCopy(LogicNode xCond, boolean xNeg, LogicNode yCond, boolean yNeg, double probability) { - return new ShortCircuitAndNode(xCond, xNeg, yCond, yNeg, probability); - } -} diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ShortCircuitBooleanNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ShortCircuitBooleanNode.java Thu Sep 05 16:36:40 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2013, 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.nodes; - -import com.oracle.graal.graph.*; - -/** - * Base class for the short-circuit boolean operators. - */ -public abstract class ShortCircuitBooleanNode extends LogicNode implements Node.IterableNodeType { - - @Input private LogicNode x; - @Input private LogicNode y; - private boolean xNegated; - private boolean yNegated; - private double shortCircuitProbability; - - public ShortCircuitBooleanNode(LogicNode x, boolean xNegated, LogicNode y, boolean yNegated, double shortCircuitProbability) { - this.x = x; - this.xNegated = xNegated; - this.y = y; - this.yNegated = yNegated; - this.shortCircuitProbability = shortCircuitProbability; - } - - public LogicNode getX() { - return x; - } - - public LogicNode getY() { - return y; - } - - public boolean isXNegated() { - return xNegated; - } - - public boolean isYNegated() { - return yNegated; - } - - /** - * Gets the probability that the {@link #getY() y} part of this binary node is not - * evaluated. This is the probability that this operator will short-circuit its execution. - */ - public double getShortCircuitProbability() { - return shortCircuitProbability; - } - - protected abstract ShortCircuitBooleanNode createCopy(LogicNode xCond, boolean xNeg, LogicNode yCond, boolean yNeg, double probability); - - protected ShortCircuitBooleanNode canonicalizeNegation() { - LogicNode xCond = x; - boolean xNeg = xNegated; - while (xCond instanceof LogicNegationNode) { - xCond = ((LogicNegationNode) xCond).getInput(); - xNeg = !xNeg; - } - - LogicNode yCond = y; - boolean yNeg = yNegated; - while (yCond instanceof LogicNegationNode) { - yCond = ((LogicNegationNode) yCond).getInput(); - yNeg = !yNeg; - } - - if (xCond != x || yCond != y) { - return graph().unique(createCopy(xCond, xNeg, yCond, yNeg, shortCircuitProbability)); - } else { - return null; - } - } -} diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ShortCircuitOrNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ShortCircuitOrNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ShortCircuitOrNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -22,27 +22,79 @@ */ package com.oracle.graal.nodes; +import com.oracle.graal.graph.*; import com.oracle.graal.nodes.spi.*; -/** - * The short-circuit OR (i.e. {@code ||} in Java) operator. - */ -public class ShortCircuitOrNode extends ShortCircuitBooleanNode implements Canonicalizable { +public class ShortCircuitOrNode extends LogicNode implements IterableNodeType, Canonicalizable { + + @Input private LogicNode x; + @Input private LogicNode y; + private boolean xNegated; + private boolean yNegated; + private double shortCircuitProbability; public ShortCircuitOrNode(LogicNode x, boolean xNegated, LogicNode y, boolean yNegated, double shortCircuitProbability) { - super(x, xNegated, y, yNegated, shortCircuitProbability); + this.x = x; + this.xNegated = xNegated; + this.y = y; + this.yNegated = yNegated; + this.shortCircuitProbability = shortCircuitProbability; + } + + public LogicNode getX() { + return x; + } + + public LogicNode getY() { + return y; + } + + public boolean isXNegated() { + return xNegated; + } + + public boolean isYNegated() { + return yNegated; + } + + /** + * Gets the probability that the {@link #getY() y} part of this binary node is not + * evaluated. This is the probability that this operator will short-circuit its execution. + */ + public double getShortCircuitProbability() { + return shortCircuitProbability; + } + + protected ShortCircuitOrNode canonicalizeNegation() { + LogicNode xCond = x; + boolean xNeg = xNegated; + while (xCond instanceof LogicNegationNode) { + xCond = ((LogicNegationNode) xCond).getInput(); + xNeg = !xNeg; + } + + LogicNode yCond = y; + boolean yNeg = yNegated; + while (yCond instanceof LogicNegationNode) { + yCond = ((LogicNegationNode) yCond).getInput(); + yNeg = !yNeg; + } + + if (xCond != x || yCond != y) { + return graph().unique(new ShortCircuitOrNode(xCond, xNeg, yCond, yNeg, shortCircuitProbability)); + } else { + return null; + } } @Override public LogicNode canonical(CanonicalizerTool tool) { - ShortCircuitBooleanNode ret = canonicalizeNegation(); + ShortCircuitOrNode ret = canonicalizeNegation(); if (ret != null) { return ret; } - LogicNode x = getX(); - LogicNode y = getY(); - if (x == y) { + if (getX() == getY()) { // @formatter:off // a || a = a // a || !a = true @@ -52,7 +104,7 @@ if (isXNegated()) { if (isYNegated()) { // !a || !a = !a - return graph().unique(new LogicNegationNode(x)); + return graph().unique(new LogicNegationNode(getX())); } else { // !a || a = true return LogicConstantNode.tautology(graph()); @@ -63,37 +115,32 @@ return LogicConstantNode.tautology(graph()); } else { // a || a = a - return x; + return getX(); } } } - if (x instanceof LogicConstantNode) { - if (((LogicConstantNode) x).getValue() ^ isXNegated()) { + if (getX() instanceof LogicConstantNode) { + if (((LogicConstantNode) getX()).getValue() ^ isXNegated()) { return LogicConstantNode.tautology(graph()); } else { if (isYNegated()) { - return graph().unique(new LogicNegationNode(y)); + return graph().unique(new LogicNegationNode(getY())); } else { - return y; + return getY(); } } } - if (y instanceof LogicConstantNode) { - if (((LogicConstantNode) y).getValue() ^ isYNegated()) { + if (getY() instanceof LogicConstantNode) { + if (((LogicConstantNode) getY()).getValue() ^ isYNegated()) { return LogicConstantNode.tautology(graph()); } else { if (isXNegated()) { - return graph().unique(new LogicNegationNode(x)); + return graph().unique(new LogicNegationNode(getX())); } else { - return x; + return getX(); } } } return this; } - - @Override - protected ShortCircuitBooleanNode createCopy(LogicNode xCond, boolean xNeg, LogicNode yCond, boolean yNeg, double probability) { - return new ShortCircuitOrNode(xCond, xNeg, yCond, yNeg, probability); - } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Fri Sep 13 23:12:10 2013 +0200 @@ -37,6 +37,35 @@ */ public class StructuredGraph extends Graph { + /** + * The different stages of the compilation of a {@link Graph} regarding the status of + * {@link GuardNode guards}, {@link DeoptimizingNode deoptimizations} and {@link FrameState + * framestates}. The stage of a graph progresses monotonously. + * + */ + public static enum GuardsStage { + /** + * During this stage, there can be {@link FloatingNode floating} {@link DeoptimizingNode} + * such as {@link GuardNode GuardNodes}. New {@link DeoptimizingNode DeoptimizingNodes} can + * be introduced without constraints. {@link FrameState} nodes are associated with + * {@link StateSplit} nodes. + */ + FLOATING_GUARDS, + /** + * During this stage, all {@link DeoptimizingNode DeoptimizingNodes} must be + * {@link FixedNode fixed} but new {@link DeoptimizingNode DeoptimizingNodes} can still be + * introduced. {@link FrameState} nodes are still associated with {@link StateSplit} nodes. + */ + FIXED_DEOPTS, + /** + * During this stage, all {@link DeoptimizingNode DeoptimizingNodes} must be + * {@link FixedNode fixed}. New {@link DeoptimizingNode DeoptimizingNodes} can not be + * introduced any more. {@link FrameState} nodes are now associated with + * {@link DeoptimizingNode} nodes. + */ + AFTER_FSA + } + public static final int INVOCATION_ENTRY_BCI = -1; public static final long INVALID_GRAPH_ID = -1; @@ -48,6 +77,7 @@ private final ResolvedJavaMethod method; private final long graphId; private final int entryBCI; + private GuardsStage guardsPhase = GuardsStage.FLOATING_GUARDS; /** * Creates a new Graph containing a single {@link AbstractBeginNode} as the {@link #start() @@ -386,4 +416,13 @@ singleEnd.replaceAndDelete(sux); } } + + public GuardsStage getGuardsPhase() { + return guardsPhase; + } + + public void setGuardsPhase(GuardsStage guardsPhase) { + assert guardsPhase.ordinal() >= this.guardsPhase.ordinal(); + this.guardsPhase = guardsPhase; + } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -32,7 +32,7 @@ /** * A node that attaches a type profile to a proxied input node. */ -public final class TypeProfileProxyNode extends FloatingNode implements Canonicalizable, Node.IterableNodeType, ValueProxy { +public final class TypeProfileProxyNode extends FloatingNode implements Canonicalizable, IterableNodeType, ValueProxy { @Input private ValueNode object; private final JavaTypeProfile profile; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnwindNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnwindNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnwindNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -23,14 +23,13 @@ package com.oracle.graal.nodes; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; /** * Unwinds the current frame to an exception handler in the caller frame. */ -public final class UnwindNode extends ControlSinkNode implements Lowerable, LIRLowerable, Node.IterableNodeType { +public final class UnwindNode extends ControlSinkNode implements Lowerable, LIRLowerable { @Input private ValueNode exception; @@ -50,7 +49,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -140,4 +140,8 @@ assertTrue(kind() == kind().getStackKind(), "Should have a stack kind : %s", kind()); return super.verify(); } + + public ValueNode asNode() { + return this; + } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/WriteBarrier.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/WriteBarrier.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/WriteBarrier.java Fri Sep 13 23:12:10 2013 +0200 @@ -27,7 +27,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -public abstract class WriteBarrier extends FixedWithNextNode implements Lowerable, Node.IterableNodeType { +public abstract class WriteBarrier extends FixedWithNextNode implements Lowerable, IterableNodeType { @Input private ValueNode object; @Input private LocationNode location; @@ -53,8 +53,8 @@ } @Override - public void lower(LoweringTool generator, LoweringType loweringType) { - assert loweringType == LoweringType.AFTER_FSA; + public void lower(LoweringTool generator) { + assert graph().getGuardsPhase() == StructuredGraph.GuardsStage.AFTER_FSA; generator.getRuntime().lower(this, generator); } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -150,14 +150,22 @@ return null; } + //@formatter:off /* * In reassociate, complexity comes from the handling of IntegerSub (non commutative) which can - * be mixed with IntegerAdd. if first tries to find m1, m2 which match the criterion : (a o m2) - * o m1 (m2 o a) o m1 m1 o (a o m2) m1 o (m2 o a) It then produces 4 boolean for the -/+ case - * invertA : should the final expression be like *-a (rather than a+*) aSub : should the final - * expression be like a-* (rather than a+*) invertM1 : should the final expression contain -m1 + * be mixed with IntegerAdd. It first tries to find m1, m2 which match the criterion : + * (a o m2) o m1 + * (m2 o a) o m1 + * m1 o (a o m2) + * m1 o (m2 o a) + * It then produces 4 boolean for the -/+ cases: + * invertA : should the final expression be like *-a (rather than a+*) + * aSub : should the final expression be like a-* (rather than a+*) + * invertM1 : should the final expression contain -m1 * invertM2 : should the final expression contain -m2 + * */ + //@formatter:on /** * Tries to re-associate values which satisfy the criterion. For example with a constantness * criterion : (a + 2) + 1 => a + (1 + 2)
diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -235,7 +235,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -110,7 +110,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -61,7 +61,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -48,7 +48,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { LogicNode equalComp; LogicNode lessComp; if (x().kind() == Kind.Double || x().kind() == Kind.Float) { diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -62,7 +62,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -61,7 +61,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/DynamicCounterNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/DynamicCounterNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/DynamicCounterNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -166,7 +166,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { if (!enabled) { throw new GraalInternalError("counter nodes shouldn't exist when not enabled"); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AccessNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AccessNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AccessNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -78,11 +78,6 @@ } @Override - public AccessNode asNode() { - return this; - } - - @Override public boolean canDeoptimize() { return nullCheck; } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ArrayRangeWriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ArrayRangeWriteNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ArrayRangeWriteNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -29,7 +29,7 @@ /** * Base class for nodes that modify a range of an array. */ -public abstract class ArrayRangeWriteNode extends AbstractStateSplit implements Node.IterableNodeType { +public abstract class ArrayRangeWriteNode extends AbstractStateSplit implements IterableNodeType { protected ArrayRangeWriteNode(Stamp stamp) { super(stamp); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -53,7 +53,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BranchProbabilityNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BranchProbabilityNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BranchProbabilityNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -123,7 +123,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { throw new GraalInternalError("Branch probability could not be injected, because the probability value did not reduce to a constant value."); } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -70,11 +70,6 @@ } @Override - public FloatingAccessNode asNode() { - return this; - } - - @Override public boolean canDeoptimize() { return nullCheck; } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -32,7 +32,7 @@ * A floating read of a value from memory specified in terms of an object base and an object * relative location. This node does not null check the object. */ -public final class FloatingReadNode extends FloatingAccessNode implements Node.IterableNodeType, LIRLowerable, Canonicalizable { +public final class FloatingReadNode extends FloatingAccessNode implements IterableNodeType, LIRLowerable, Canonicalizable { @Input private Node lastLocationAccess; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -58,8 +58,8 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { - if (loweringType == LoweringType.AFTER_GUARDS) { + public void lower(LoweringTool tool) { + if (graph().getGuardsPhase() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { tool.getRuntime().lower(this, tool); } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -51,7 +51,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/NullCheckNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/NullCheckNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/NullCheckNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -54,9 +54,4 @@ public DeoptimizationReason getDeoptimizationReason() { return DeoptimizationReason.NullCheckException; } - - @Override - public ValueNode asNode() { - return this; - } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRLocalNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRLocalNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRLocalNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -27,7 +27,7 @@ import com.oracle.graal.nodes.type.*; @NodeInfo(nameTemplate = "OSRLocal({p#index})") -public class OSRLocalNode extends AbstractLocalNode implements Node.IterableNodeType { +public class OSRLocalNode extends AbstractLocalNode implements IterableNodeType { public OSRLocalNode(int index, Stamp stamp) { super(index, stamp); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRStartNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRStartNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRStartNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -29,7 +29,7 @@ public class OSRStartNode extends StartNode implements Lowerable { @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -32,7 +32,7 @@ /** * Reads an {@linkplain AccessNode accessed} value. */ -public final class ReadNode extends FloatableAccessNode implements Node.IterableNodeType, LIRLowerable, Canonicalizable, PiPushable, Virtualizable { +public final class ReadNode extends FloatableAccessNode implements IterableNodeType, LIRLowerable, Canonicalizable, PiPushable, Virtualizable { public ReadNode(ValueNode object, ValueNode location, Stamp stamp, BarrierType barrierType, boolean compressible) { super(object, location, stamp, barrierType, compressible); @@ -72,7 +72,7 @@ public static ValueNode canonicalizeRead(ValueNode read, LocationNode location, ValueNode object, CanonicalizerTool tool, boolean compressible) { MetaAccessProvider runtime = tool.runtime(); - if (read.usages().count() == 0) { + if (read.usages().isEmpty()) { // Read without usages can be savely removed. return null; } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/StoreHubNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/StoreHubNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/StoreHubNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -46,7 +46,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -48,7 +48,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -49,7 +49,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -68,7 +68,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -32,7 +32,7 @@ /** * The ValueAnchor instruction keeps non-CFG (floating) nodes above a certain point in the graph. */ -public final class ValueAnchorNode extends FixedWithNextNode implements Canonicalizable, LIRLowerable, Node.IterableNodeType, Virtualizable, GuardingNode { +public final class ValueAnchorNode extends FixedWithNextNode implements Canonicalizable, LIRLowerable, IterableNodeType, Virtualizable, GuardingNode { @Input private final NodeInputList anchored; @@ -114,9 +114,4 @@ } tool.delete(); } - - @Override - public ValueNode asNode() { - return this; - } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -33,7 +33,7 @@ /** * Writes a given {@linkplain #value() value} a {@linkplain AccessNode memory location}. */ -public final class WriteNode extends AccessNode implements StateSplit, LIRLowerable, MemoryCheckpoint.Single, Node.IterableNodeType, Virtualizable { +public final class WriteNode extends AccessNode implements StateSplit, LIRLowerable, MemoryCheckpoint.Single, IterableNodeType, Virtualizable { @Input private ValueNode value; @Input(notDataflow = true) private FrameState stateAfter; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewArrayNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewArrayNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewArrayNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -23,7 +23,6 @@ package com.oracle.graal.nodes.java; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -31,7 +30,7 @@ /** * The {@code AbstractNewArrayNode} is used for all 1-dimensional array allocations. */ -public class AbstractNewArrayNode extends DeoptimizingFixedWithNextNode implements Canonicalizable, Lowerable, ArrayLengthProvider, Node.IterableNodeType { +public class AbstractNewArrayNode extends DeoptimizingFixedWithNextNode implements Canonicalizable, Lowerable, ArrayLengthProvider { @Input private ValueNode length; private final boolean fillContents; @@ -88,7 +87,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessFieldNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessFieldNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessFieldNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -83,7 +83,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -64,7 +64,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -62,7 +62,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -23,7 +23,6 @@ package com.oracle.graal.nodes.java; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -32,7 +31,7 @@ * Implements a type check where the type being checked is loaded at runtime. This is used, for * instance, to implement an object array store check. */ -public final class CheckCastDynamicNode extends FixedWithNextNode implements Canonicalizable, Lowerable, Node.IterableNodeType { +public final class CheckCastDynamicNode extends FixedWithNextNode implements Canonicalizable, Lowerable { @Input private ValueNode object; @Input private ValueNode hub; @@ -59,7 +58,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -38,7 +38,7 @@ /** * Implements a type check against a compile-time known type. */ -public final class CheckCastNode extends FixedWithNextNode implements Canonicalizable, Lowerable, Node.IterableNodeType, Virtualizable, ValueProxy { +public final class CheckCastNode extends FixedWithNextNode implements Canonicalizable, Lowerable, Virtualizable, ValueProxy { @Input private ValueNode object; private final ResolvedJavaType type; @@ -96,7 +96,7 @@ * {@code LoweringPhase.checkUsagesAreScheduled()}. */ @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { InstanceOfNode typeTest = graph().add(new InstanceOfNode(type, object, profile)); Stamp stamp = StampFactory.declared(type); if (stamp() instanceof ObjectStamp && object().stamp() instanceof ObjectStamp) { @@ -118,7 +118,7 @@ } else { // TODO (ds) replace with probability of null-seen when available double shortCircuitProbability = NOT_FREQUENT_PROBABILITY; - condition = graph().unique(new ShortCircuitOrNode(graph().unique(new IsNullNode(object)), false, typeTest, false, shortCircuitProbability)); + condition = LogicNode.or(graph().unique(new IsNullNode(object)), typeTest, shortCircuitProbability); } } GuardingPiNode checkedObject = graph().add(new GuardingPiNode(object, condition, false, forStoreCheck ? ArrayStoreException : ClassCastException, InvalidateReprofile, stamp)); @@ -159,7 +159,7 @@ if (ObjectStamp.isObjectAlwaysNull(object())) { return object(); } - if (tool.assumptions().useOptimisticAssumptions()) { + if (tool.assumptions() != null && tool.assumptions().useOptimisticAssumptions()) { ResolvedJavaType exactType = type.findUniqueConcreteSubtype(); if (exactType != null && exactType != type) { // Propagate more precise type information to usages of the checkcast. diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -78,7 +78,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -64,7 +64,7 @@ * runtime/interpreter would not have a valid location for the exception object to be rethrown. */ @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { if (isLowered()) { return; } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -50,7 +50,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -51,7 +51,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadExceptionObjectNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadExceptionObjectNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadExceptionObjectNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -44,7 +44,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -36,7 +36,7 @@ * The {@code LoadFieldNode} represents a read of a static or instance field. */ @NodeInfo(nameTemplate = "LoadField#{p#field/s}") -public final class LoadFieldNode extends AccessFieldNode implements Canonicalizable, Node.IterableNodeType, VirtualizableRoot { +public final class LoadFieldNode extends AccessFieldNode implements Canonicalizable, IterableNodeType, VirtualizableRoot { /** * Creates a new LoadFieldNode instance. diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -31,7 +31,7 @@ /** * The {@code LoadIndexedNode} represents a read from an element of an array. */ -public final class LoadIndexedNode extends AccessIndexedNode implements Node.IterableNodeType, Virtualizable { +public final class LoadIndexedNode extends AccessIndexedNode implements IterableNodeType, Virtualizable { /** * Creates a new LoadIndexedNode. diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -32,7 +32,7 @@ /** * Represents the lowered version of an atomic compare-and-swap operation{@code CompareAndSwapNode}. */ -public class LoweredCompareAndSwapNode extends AccessNode implements StateSplit, LIRLowerable, MemoryCheckpoint.Single, Node.IterableNodeType { +public class LoweredCompareAndSwapNode extends AccessNode implements StateSplit, LIRLowerable, MemoryCheckpoint.Single, IterableNodeType { @Input private ValueNode expectedValue; @Input private ValueNode newValue; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -30,7 +30,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -public class MethodCallTargetNode extends CallTargetNode implements Node.IterableNodeType, Canonicalizable { +public class MethodCallTargetNode extends CallTargetNode implements IterableNodeType, Canonicalizable { public enum InvokeKind { Interface, Special, Static, Virtual diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -50,7 +50,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -31,7 +31,7 @@ /** * The {@code MonitorEnterNode} represents a monitor release. */ -public final class MonitorExitNode extends AccessMonitorNode implements Virtualizable, Lowerable, Node.IterableNodeType, MonitorExit, MemoryCheckpoint.Single, MonitorReference { +public final class MonitorExitNode extends AccessMonitorNode implements Virtualizable, Lowerable, IterableNodeType, MonitorExit, MemoryCheckpoint.Single, MonitorReference { private int lockDepth; @@ -51,7 +51,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -33,7 +33,7 @@ * The {@code NewInstanceNode} represents the allocation of an instance class object. */ @NodeInfo(nameTemplate = "New {p#instanceClass/s}") -public final class NewInstanceNode extends DeoptimizingFixedWithNextNode implements Node.IterableNodeType, Canonicalizable, Lowerable, VirtualizableAllocation { +public final class NewInstanceNode extends DeoptimizingFixedWithNextNode implements Canonicalizable, Lowerable, VirtualizableAllocation { private final ResolvedJavaType instanceClass; private final boolean fillContents; @@ -77,7 +77,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -62,7 +62,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/SelfReplacingMethodCallTargetNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/SelfReplacingMethodCallTargetNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/SelfReplacingMethodCallTargetNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -28,7 +28,7 @@ import com.oracle.graal.api.meta.ResolvedJavaMethod; import com.oracle.graal.graph.GraalInternalError; import com.oracle.graal.graph.NodeInputList; -import com.oracle.graal.nodes.ValueNode; +import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.LIRGeneratorTool; import com.oracle.graal.nodes.spi.Lowerable; import com.oracle.graal.nodes.spi.LoweringTool; @@ -68,7 +68,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { InvokeKind invokeKind = Modifier.isStatic(replacementTargetMethod.getModifiers()) ? InvokeKind.Static : InvokeKind.Special; MethodCallTargetNode replacement = graph().add( new MethodCallTargetNode(invokeKind, replacementTargetMethod, replacementArguments.toArray(new ValueNode[replacementArguments.size()]), replacementReturnType)); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/DelegatingGraalCodeCacheProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/DelegatingGraalCodeCacheProvider.java Fri Sep 13 23:12:10 2013 +0200 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011, 2011, 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.nodes.spi; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; + +/** + * A {@link GraalCodeCacheProvider} that delegates to another {@link GraalCodeCacheProvider}. + */ +public class DelegatingGraalCodeCacheProvider extends DelegatingCodeCacheProvider implements GraalCodeCacheProvider { + + public DelegatingGraalCodeCacheProvider(CodeCacheProvider delegate) { + super(delegate); + } + + @Override + protected GraalCodeCacheProvider delegate() { + return (GraalCodeCacheProvider) super.delegate(); + } + + public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, Graph graph) { + return delegate().addMethod(method, compResult, graph); + } + + public void lower(Node n, LoweringTool tool) { + delegate().lower(n, tool); + } + + public ValueNode reconstructArrayIndex(LocationNode location) { + return delegate().reconstructArrayIndex(location); + } +} diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Lowerable.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Lowerable.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Lowerable.java Fri Sep 13 23:12:10 2013 +0200 @@ -22,11 +22,11 @@ */ package com.oracle.graal.nodes.spi; +import com.oracle.graal.nodes.*; + public interface Lowerable { - public enum LoweringType { - BEFORE_GUARDS, AFTER_GUARDS, AFTER_FSA - } + void lower(LoweringTool tool); - void lower(LoweringTool tool, LoweringType loweringType); + ValueNode asNode(); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java Fri Sep 13 23:12:10 2013 +0200 @@ -28,14 +28,11 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.Lowerable.LoweringType; public interface LoweringTool { GraalCodeCacheProvider getRuntime(); - LoweringType getLoweringType(); - Replacements getReplacements(); GuardingNode createNullCheckGuard(GuardedNode guardedNode, ValueNode object); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -31,7 +31,7 @@ import com.oracle.graal.nodes.type.*; @NodeInfo(nameTemplate = "Alloc {i#virtualObjects}") -public final class CommitAllocationNode extends FixedWithNextNode implements VirtualizableAllocation, Lowerable, Node.IterableNodeType, Simplifiable { +public final class CommitAllocationNode extends FixedWithNextNode implements VirtualizableAllocation, Lowerable, IterableNodeType, Simplifiable { @Input private final NodeInputList virtualObjects = new NodeInputList<>(this); @Input private final NodeInputList values = new NodeInputList<>(this); @@ -65,7 +65,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/EscapeObjectState.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/EscapeObjectState.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/EscapeObjectState.java Fri Sep 13 23:12:10 2013 +0200 @@ -25,7 +25,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; -public abstract class EscapeObjectState extends VirtualState implements Node.IterableNodeType { +public abstract class EscapeObjectState extends VirtualState implements IterableNodeType { @Input private VirtualObjectNode object; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -28,7 +28,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -public abstract class VirtualObjectNode extends ValueNode implements LIRLowerable, Node.IterableNodeType { +public abstract class VirtualObjectNode extends ValueNode implements LIRLowerable, IterableNodeType { private boolean hasIdentity; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Fri Sep 13 23:12:10 2013 +0200 @@ -31,24 +31,25 @@ import com.oracle.graal.graph.Graph.NodeChangedListener; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.util.*; import com.oracle.graal.phases.*; +import com.oracle.graal.phases.PhasePlan.PhasePosition; import com.oracle.graal.phases.tiers.*; public class CanonicalizerPhase extends BasePhase { private static final int MAX_ITERATION_PER_NODE = 10; private static final DebugMetric METRIC_CANONICALIZED_NODES = Debug.metric("CanonicalizedNodes"); + private static final DebugMetric METRIC_PROCESSED_NODES = Debug.metric("ProcessedNodes"); private static final DebugMetric METRIC_CANONICALIZATION_CONSIDERED_NODES = Debug.metric("CanonicalizationConsideredNodes"); private static final DebugMetric METRIC_INFER_STAMP_CALLED = Debug.metric("InferStampCalled"); private static final DebugMetric METRIC_STAMP_CHANGED = Debug.metric("StampChanged"); private static final DebugMetric METRIC_SIMPLIFICATION_CONSIDERED_NODES = Debug.metric("SimplificationConsideredNodes"); - public static final DebugMetric METRIC_GLOBAL_VALUE_NUMBERING_HITS = Debug.metric("GlobalValueNumberingHits"); + private static final DebugMetric METRIC_GLOBAL_VALUE_NUMBERING_HITS = Debug.metric("GlobalValueNumberingHits"); private final boolean canonicalizeReads; + private final CustomCanonicalizer customCanonicalizer; public interface CustomCanonicalizer { @@ -56,15 +57,57 @@ } public CanonicalizerPhase(boolean canonicalizeReads) { + this(canonicalizeReads, null); + } + + public CanonicalizerPhase(boolean canonicalizeReads, CustomCanonicalizer customCanonicalizer) { this.canonicalizeReads = canonicalizeReads; + this.customCanonicalizer = customCanonicalizer; } @Override protected void run(StructuredGraph graph, PhaseContext context) { - new Instance(context.getRuntime(), context.getAssumptions(), canonicalizeReads).run(graph); + new Instance(context.getRuntime(), context.getAssumptions(), canonicalizeReads, customCanonicalizer).run(graph); + } + + /** + * @param newNodesMark only the {@linkplain Graph#getNewNodes(int) new nodes} specified by this + * mark are processed + */ + public void applyIncremental(StructuredGraph graph, PhaseContext context, int newNodesMark) { + applyIncremental(graph, context, newNodesMark, true); + } + + public void applyIncremental(StructuredGraph graph, PhaseContext context, int newNodesMark, boolean dumpGraph) { + new Instance(context.getRuntime(), context.getAssumptions(), canonicalizeReads, newNodesMark, customCanonicalizer).apply(graph, dumpGraph); } - public static class Instance extends Phase { + /** + * @param workingSet the initial working set of nodes on which the canonicalizer works, should + * be an auto-grow node bitmap + */ + public void applyIncremental(StructuredGraph graph, PhaseContext context, Iterable workingSet) { + applyIncremental(graph, context, workingSet, true); + } + + public void applyIncremental(StructuredGraph graph, PhaseContext context, Iterable workingSet, boolean dumpGraph) { + new Instance(context.getRuntime(), context.getAssumptions(), canonicalizeReads, workingSet, customCanonicalizer).apply(graph, dumpGraph); + } + + public void applyIncremental(StructuredGraph graph, PhaseContext context, Iterable workingSet, int newNodesMark) { + applyIncremental(graph, context, workingSet, newNodesMark, true); + } + + public void applyIncremental(StructuredGraph graph, PhaseContext context, Iterable workingSet, int newNodesMark, boolean dumpGraph) { + new Instance(context.getRuntime(), context.getAssumptions(), canonicalizeReads, workingSet, newNodesMark, customCanonicalizer).apply(graph, dumpGraph); + } + + @Deprecated + public void addToPhasePlan(PhasePlan plan, PhaseContext context) { + plan.addPhase(PhasePosition.AFTER_PARSING, new Instance(context.getRuntime(), context.getAssumptions(), canonicalizeReads, customCanonicalizer)); + } + + private static final class Instance extends Phase { private final int newNodesMark; private final Assumptions assumptions; @@ -76,34 +119,19 @@ private NodeWorkList workList; private Tool tool; - public Instance(MetaAccessProvider runtime, Assumptions assumptions, boolean canonicalizeReads) { - this(runtime, assumptions, canonicalizeReads, null, 0, null); + private Instance(MetaAccessProvider runtime, Assumptions assumptions, boolean canonicalizeReads, CustomCanonicalizer customCanonicalizer) { + this(runtime, assumptions, canonicalizeReads, null, 0, customCanonicalizer); } - /** - * @param runtime - * @param assumptions - * @param workingSet the initial working set of nodes on which the canonicalizer works, - * should be an auto-grow node bitmap - * @param customCanonicalizer - * @param canonicalizeReads flag to indicate if - * {@link LoadFieldNode#canonical(CanonicalizerTool)} and - * {@link ReadNode#canonical(CanonicalizerTool)} should canonicalize reads of - * constant fields. - */ - public Instance(MetaAccessProvider runtime, Assumptions assumptions, boolean canonicalizeReads, Iterable workingSet, CustomCanonicalizer customCanonicalizer) { + private Instance(MetaAccessProvider runtime, Assumptions assumptions, boolean canonicalizeReads, Iterable workingSet, CustomCanonicalizer customCanonicalizer) { this(runtime, assumptions, canonicalizeReads, workingSet, 0, customCanonicalizer); } - /** - * @param newNodesMark only the {@linkplain Graph#getNewNodes(int) new nodes} specified by - * this mark are processed otherwise all nodes in the graph are processed - */ - public Instance(MetaAccessProvider runtime, Assumptions assumptions, boolean canonicalizeReads, int newNodesMark, CustomCanonicalizer customCanonicalizer) { + private Instance(MetaAccessProvider runtime, Assumptions assumptions, boolean canonicalizeReads, int newNodesMark, CustomCanonicalizer customCanonicalizer) { this(runtime, assumptions, canonicalizeReads, null, newNodesMark, customCanonicalizer); } - public Instance(MetaAccessProvider runtime, Assumptions assumptions, boolean canonicalizeReads, Iterable workingSet, int newNodesMark, CustomCanonicalizer customCanonicalizer) { + private Instance(MetaAccessProvider runtime, Assumptions assumptions, boolean canonicalizeReads, Iterable workingSet, int newNodesMark, CustomCanonicalizer customCanonicalizer) { super("Canonicalizer"); this.newNodesMark = newNodesMark; this.assumptions = assumptions; @@ -160,14 +188,13 @@ if (!tryCanonicalize(node)) { if (node instanceof ValueNode) { ValueNode valueNode = (ValueNode) node; - if (tryInferStamp(valueNode)) { - Constant constant = valueNode.stamp().asConstant(); - if (constant != null) { - performReplacement(valueNode, ConstantNode.forConstant(constant, runtime, valueNode.graph())); - } else { - // the improved stamp may enable additional canonicalization - tryCanonicalize(valueNode); - } + boolean improvedStamp = tryInferStamp(valueNode); + Constant constant = valueNode.stamp().asConstant(); + if (constant != null && !(node instanceof ConstantNode)) { + performReplacement(valueNode, ConstantNode.forConstant(constant, runtime, valueNode.graph())); + } else if (improvedStamp) { + // the improved stamp may enable additional canonicalization + tryCanonicalize(valueNode); } } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ExpandLogicPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ExpandLogicPhase.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ExpandLogicPhase.java Fri Sep 13 23:12:10 2013 +0200 @@ -31,33 +31,21 @@ @Override protected void run(StructuredGraph graph) { - for (ShortCircuitBooleanNode logic : graph.getNodes(ShortCircuitBooleanNode.class)) { + for (ShortCircuitOrNode logic : graph.getNodes(ShortCircuitOrNode.class)) { processBinary(logic); } - assert graph.getNodes(ShortCircuitBooleanNode.class).isEmpty(); + assert graph.getNodes(ShortCircuitOrNode.class).isEmpty(); } - private static void processBinary(ShortCircuitBooleanNode binary) { + private static void processBinary(ShortCircuitOrNode binary) { while (binary.usages().isNotEmpty()) { Node usage = binary.usages().first(); - if (usage instanceof ShortCircuitBooleanNode) { - processBinary((ShortCircuitBooleanNode) usage); + if (usage instanceof ShortCircuitOrNode) { + processBinary((ShortCircuitOrNode) usage); } else if (usage instanceof IfNode) { - if (binary instanceof ShortCircuitAndNode) { - processIf(binary.getX(), binary.isXNegated(), binary.getY(), binary.isYNegated(), (IfNode) usage, false, binary.getShortCircuitProbability()); - } else if (binary instanceof ShortCircuitOrNode) { - processIf(binary.getX(), !binary.isXNegated(), binary.getY(), !binary.isYNegated(), (IfNode) usage, true, binary.getShortCircuitProbability()); - } else { - throw GraalInternalError.shouldNotReachHere(); - } + processIf(binary.getX(), binary.isXNegated(), binary.getY(), binary.isYNegated(), (IfNode) usage, binary.getShortCircuitProbability()); } else if (usage instanceof ConditionalNode) { - if (binary instanceof ShortCircuitOrNode) { - processConditional(binary.getX(), binary.isXNegated(), binary.getY(), binary.isYNegated(), (ConditionalNode) usage, false); - } else if (binary instanceof ShortCircuitOrNode) { - processConditional(binary.getX(), !binary.isXNegated(), binary.getY(), !binary.isYNegated(), (ConditionalNode) usage, true); - } else { - throw GraalInternalError.shouldNotReachHere(); - } + processConditional(binary.getX(), binary.isXNegated(), binary.getY(), binary.isYNegated(), (ConditionalNode) usage); } else { throw GraalInternalError.shouldNotReachHere(); } @@ -65,33 +53,44 @@ binary.safeDelete(); } - private static void processIf(LogicNode x, boolean xNegated, LogicNode y, boolean yNegated, IfNode ifNode, boolean negateTargets, double shortCircuitProbability) { - AbstractBeginNode trueTarget = negateTargets ? ifNode.falseSuccessor() : ifNode.trueSuccessor(); - AbstractBeginNode falseTarget = negateTargets ? ifNode.trueSuccessor() : ifNode.falseSuccessor(); + private static void processIf(LogicNode x, boolean xNegated, LogicNode y, boolean yNegated, IfNode ifNode, double shortCircuitProbability) { + AbstractBeginNode trueTarget = ifNode.trueSuccessor(); + AbstractBeginNode falseTarget = ifNode.falseSuccessor(); double firstIfProbability = shortCircuitProbability; - double secondIfProbability = 1 - ifNode.probability(trueTarget); + /* + * P(Y | not(X)) = P(Y inter not(X)) / P(not(X)) = (P(X union Y) - P(X)) / (1 - P(X)) + * + * P(X) = shortCircuitProbability + * + * P(X union Y) = ifNode.probability(trueTarget) + */ + double secondIfProbability = (ifNode.probability(trueTarget) - shortCircuitProbability) / (1 - shortCircuitProbability); + secondIfProbability = Math.min(1.0, Math.max(0.0, secondIfProbability)); + if (Double.isNaN(secondIfProbability)) { + secondIfProbability = 0.5; + } ifNode.clearSuccessors(); Graph graph = ifNode.graph(); - MergeNode falseTargetMerge = graph.add(new MergeNode()); - falseTargetMerge.setNext(falseTarget); - EndNode firstFalseEnd = graph.add(new EndNode()); - EndNode secondFalseEnd = graph.add(new EndNode()); - falseTargetMerge.addForwardEnd(firstFalseEnd); - falseTargetMerge.addForwardEnd(secondFalseEnd); - AbstractBeginNode firstFalseTarget = AbstractBeginNode.begin(firstFalseEnd); - AbstractBeginNode secondFalseTarget = AbstractBeginNode.begin(secondFalseEnd); - AbstractBeginNode secondIf = AbstractBeginNode.begin(graph.add(new IfNode(y, yNegated ? firstFalseTarget : trueTarget, yNegated ? trueTarget : firstFalseTarget, secondIfProbability))); - IfNode firstIf = graph.add(new IfNode(x, xNegated ? secondFalseTarget : secondIf, xNegated ? secondIf : secondFalseTarget, firstIfProbability)); + MergeNode trueTargetMerge = graph.add(new MergeNode()); + trueTargetMerge.setNext(trueTarget); + EndNode firstTrueEnd = graph.add(new EndNode()); + EndNode secondTrueEnd = graph.add(new EndNode()); + trueTargetMerge.addForwardEnd(firstTrueEnd); + trueTargetMerge.addForwardEnd(secondTrueEnd); + AbstractBeginNode firstTrueTarget = AbstractBeginNode.begin(firstTrueEnd); + AbstractBeginNode secondTrueTarget = AbstractBeginNode.begin(secondTrueEnd); + AbstractBeginNode secondIf = AbstractBeginNode.begin(graph.add(new IfNode(y, yNegated ? falseTarget : secondTrueTarget, yNegated ? secondTrueTarget : falseTarget, secondIfProbability))); + IfNode firstIf = graph.add(new IfNode(x, xNegated ? secondIf : firstTrueTarget, xNegated ? firstTrueTarget : secondIf, firstIfProbability)); ifNode.replaceAtPredecessor(firstIf); ifNode.safeDelete(); } - private static void processConditional(LogicNode x, boolean xNegated, LogicNode y, boolean yNegated, ConditionalNode conditional, boolean negateTargets) { - ValueNode trueTarget = negateTargets ? conditional.falseValue() : conditional.trueValue(); - ValueNode falseTarget = negateTargets ? conditional.trueValue() : conditional.falseValue(); + private static void processConditional(LogicNode x, boolean xNegated, LogicNode y, boolean yNegated, ConditionalNode conditional) { + ValueNode trueTarget = conditional.trueValue(); + ValueNode falseTarget = conditional.falseValue(); Graph graph = conditional.graph(); ConditionalNode secondConditional = graph.unique(new ConditionalNode(y, yNegated ? falseTarget : trueTarget, yNegated ? trueTarget : falseTarget)); - ConditionalNode firstConditional = graph.unique(new ConditionalNode(x, xNegated ? falseTarget : secondConditional, xNegated ? secondConditional : falseTarget)); + ConditionalNode firstConditional = graph.unique(new ConditionalNode(x, xNegated ? secondConditional : trueTarget, xNegated ? trueTarget : secondConditional)); conditional.replaceAndDelete(firstConditional); } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java Fri Sep 13 23:12:10 2013 +0200 @@ -27,11 +27,22 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.iterators.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.StructuredGraph.GuardsStage; import com.oracle.graal.nodes.util.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.graph.*; import com.oracle.graal.phases.graph.ReentrantNodeIterator.NodeIteratorClosure; +/** + * This phase transfers {@link FrameState} nodes from {@link StateSplit} nodes to + * {@link DeoptimizingNode DeoptimizingNodes}. + * + * This allow to enter the {@link GuardsStage#AFTER_FSA AFTER_FSA} stage of the graph where no new + * node that may cause deoptimization can be introduced anymore. + *

+ * This Phase processes the graph in post order, assigning the {@link FrameState} from the last + * {@link StateSplit} node to {@link DeoptimizingNode DeoptimizingNodes}. + */ public class FrameStateAssignmentPhase extends Phase { private static class FrameStateAssignmentClosure extends NodeIteratorClosure { @@ -77,6 +88,8 @@ protected void run(StructuredGraph graph) { assert checkFixedDeopts(graph); ReentrantNodeIterator.apply(new FrameStateAssignmentClosure(), graph.start(), null, null); + + graph.setGuardsPhase(GuardsStage.AFTER_FSA); } private static boolean checkFixedDeopts(StructuredGraph graph) { diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java Fri Sep 13 23:12:10 2013 +0200 @@ -29,6 +29,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.StructuredGraph.GuardsStage; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.nodes.extended.*; @@ -42,9 +43,9 @@ * This phase lowers {@link GuardNode GuardNodes} into corresponding control-flow structure and * {@link DeoptimizeNode DeoptimizeNodes}. * - * This allow to enter a phase of the compiler where all node that may cause deoptimization are - * fixed. - * + * This allow to enter the {@link GuardsStage#FIXED_DEOPTS FIXED_DEOPTS} stage of the graph where + * all node that may cause deoptimization are fixed. + *

* It first makes a schedule in order to know where the control flow should be placed. Then, for * each block, it applies two passes. The first one tries to replace null-check guards with implicit * null checks performed by access to the objects that need to be null checked. The second phase @@ -187,6 +188,8 @@ for (Block block : schedule.getCFG().getBlocks()) { processBlock(block, schedule, context.getTarget().implicitNullCheckLimit); } + + graph.setGuardsPhase(GuardsStage.FIXED_DEOPTS); } private static void processBlock(Block block, SchedulePhase schedule, int implicitNullCheckLimit) { diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IncrementalCanonicalizerPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IncrementalCanonicalizerPhase.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IncrementalCanonicalizerPhase.java Fri Sep 13 23:12:10 2013 +0200 @@ -22,29 +22,42 @@ */ package com.oracle.graal.phases.common; -import static com.oracle.graal.phases.GraalOptions.*; +import java.util.*; +import com.oracle.graal.graph.Graph.NodeChangedListener; +import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.phases.*; -import com.oracle.graal.phases.common.CanonicalizerPhase.CustomCanonicalizer; import com.oracle.graal.phases.tiers.*; public class IncrementalCanonicalizerPhase extends PhaseSuite { - private final CustomCanonicalizer customCanonicalizer; + private final CanonicalizerPhase canonicalizer; - public IncrementalCanonicalizerPhase() { - this(null); - } - - public IncrementalCanonicalizerPhase(CustomCanonicalizer customCanonicalizer) { - this.customCanonicalizer = customCanonicalizer; + public IncrementalCanonicalizerPhase(CanonicalizerPhase canonicalizer) { + this.canonicalizer = canonicalizer; } @Override protected void run(StructuredGraph graph, C context) { - int mark = graph.getMark(); + int newNodesMark = graph.getMark(); + final Set changedNodes = new HashSet<>(); + + NodeChangedListener listener = new NodeChangedListener() { + + @Override + public void nodeChanged(Node node) { + changedNodes.add(node); + } + }; + graph.trackInputChange(listener); + graph.trackUsagesDroppedZero(listener); + super.run(graph, context); - new CanonicalizerPhase.Instance(context.getRuntime(), context.getAssumptions(), !AOTCompilation.getValue(), mark, customCanonicalizer).apply(graph); + + graph.stopTrackingInputChange(); + graph.stopTrackingUsagesDroppedZero(); + + canonicalizer.applyIncremental(graph, context, changedNodes, newNodesMark, false); } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Fri Sep 13 23:12:10 2013 +0200 @@ -39,7 +39,6 @@ import com.oracle.graal.nodes.util.*; import com.oracle.graal.options.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; -import com.oracle.graal.phases.common.CanonicalizerPhase.CustomCanonicalizer; import com.oracle.graal.phases.common.InliningUtil.InlineInfo; import com.oracle.graal.phases.common.InliningUtil.Inlineable; import com.oracle.graal.phases.common.InliningUtil.InlineableGraph; @@ -59,7 +58,7 @@ } private final InliningPolicy inliningPolicy; - private final CustomCanonicalizer customCanonicalizer; + private final CanonicalizerPhase canonicalizer; private int inliningCount; private int maxMethodPerInlining = Integer.MAX_VALUE; @@ -68,27 +67,19 @@ private static final DebugMetric metricInliningPerformed = Debug.metric("InliningPerformed"); private static final DebugMetric metricInliningConsidered = Debug.metric("InliningConsidered"); private static final DebugMetric metricInliningStoppedByMaxDesiredSize = Debug.metric("InliningStoppedByMaxDesiredSize"); - private static final DebugMetric metricInliningRuns = Debug.metric("Runs"); + private static final DebugMetric metricInliningRuns = Debug.metric("InliningRuns"); - public InliningPhase() { - this(new GreedyInliningPolicy(null), null); - } - - public InliningPhase(CustomCanonicalizer canonicalizer) { + public InliningPhase(CanonicalizerPhase canonicalizer) { this(new GreedyInliningPolicy(null), canonicalizer); } - public InliningPhase(Map hints) { - this(new GreedyInliningPolicy(hints), null); + public InliningPhase(Map hints, CanonicalizerPhase canonicalizer) { + this(new GreedyInliningPolicy(hints), canonicalizer); } - public InliningPhase(InliningPolicy policy) { - this(policy, null); - } - - private InliningPhase(InliningPolicy policy, CustomCanonicalizer customCanonicalizer) { + public InliningPhase(InliningPolicy policy, CanonicalizerPhase canonicalizer) { this.inliningPolicy = policy; - this.customCanonicalizer = customCanonicalizer; + this.canonicalizer = canonicalizer; } public void setMaxMethodsPerInlining(int max) { @@ -163,7 +154,7 @@ MethodInvocation calleeInvocation = data.pushInvocation(info, parentAssumptions, invokeProbability, invokeRelevance); for (int i = 0; i < info.numberOfMethods(); i++) { - Inlineable elem = getInlineableElement(info.methodAt(i), info.invoke(), calleeInvocation.assumptions(), context); + Inlineable elem = getInlineableElement(info.methodAt(i), info.invoke(), context.replaceAssumptions(calleeInvocation.assumptions())); info.setInlinableElement(i, elem); if (elem instanceof InlineableGraph) { data.pushGraph(((InlineableGraph) elem).getGraph(), invokeProbability * info.probabilityAt(i), invokeRelevance * info.relevanceAt(i)); @@ -200,7 +191,7 @@ if (OptCanonicalizer.getValue()) { int markBeforeCanonicalization = callerGraph.getMark(); - new CanonicalizerPhase.Instance(context.getRuntime(), callerAssumptions, !AOTCompilation.getValue(), invokeUsages, markBeforeInlining, customCanonicalizer).apply(callerGraph); + canonicalizer.applyIncremental(callerGraph, context, invokeUsages, markBeforeInlining); // process invokes that are possibly created during canonicalization for (Node newNode : callerGraph.getNewNodes(markBeforeCanonicalization)) { @@ -223,16 +214,16 @@ } } - private static Inlineable getInlineableElement(final ResolvedJavaMethod method, Invoke invoke, Assumptions assumptions, HighTierContext context) { + private Inlineable getInlineableElement(final ResolvedJavaMethod method, Invoke invoke, HighTierContext context) { Class macroNodeClass = InliningUtil.getMacroNodeClass(context.getReplacements(), method); if (macroNodeClass != null) { return new InlineableMacroNode(macroNodeClass); } else { - return new InlineableGraph(buildGraph(method, invoke, assumptions, context)); + return new InlineableGraph(buildGraph(method, invoke, context)); } } - private static StructuredGraph buildGraph(final ResolvedJavaMethod method, final Invoke invoke, final Assumptions assumptions, final HighTierContext context) { + private StructuredGraph buildGraph(final ResolvedJavaMethod method, final Invoke invoke, final HighTierContext context) { final StructuredGraph newGraph; final boolean parseBytecodes; @@ -258,7 +249,7 @@ @Override public StructuredGraph call() throws Exception { if (parseBytecodes) { - parseBytecodes(newGraph, assumptions, context); + parseBytecodes(newGraph, context); } boolean callerHasMoreInformationAboutArguments = false; @@ -285,7 +276,7 @@ } if (OptCanonicalizer.getValue()) { - new CanonicalizerPhase.Instance(context.getRuntime(), assumptions, !AOTCompilation.getValue()).apply(newGraph); + canonicalizer.apply(newGraph, context); } return newGraph; @@ -303,7 +294,7 @@ return null; } - private static StructuredGraph parseBytecodes(StructuredGraph newGraph, Assumptions assumptions, HighTierContext context) { + private StructuredGraph parseBytecodes(StructuredGraph newGraph, HighTierContext context) { boolean hasMatureProfilingInfo = newGraph.method().getProfilingInfo().isMature(); if (context.getPhasePlan() != null) { @@ -314,7 +305,7 @@ new DeadCodeEliminationPhase().apply(newGraph); if (OptCanonicalizer.getValue()) { - new CanonicalizerPhase.Instance(context.getRuntime(), assumptions, !AOTCompilation.getValue()).apply(newGraph); + canonicalizer.apply(newGraph, context); } if (CacheGraphs.getValue() && context.getGraphCache() != null) { @@ -512,7 +503,7 @@ while ((current = nextQueuedNode()) != null) { assert current.isAlive(); - if (current instanceof Invoke) { + if (current instanceof Invoke && ((Invoke) current).callTarget() instanceof MethodCallTargetNode) { if (current != start) { invokes.addLast((Invoke) current); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Fri Sep 13 23:12:10 2013 +0200 @@ -38,7 +38,7 @@ import com.oracle.graal.api.meta.ResolvedJavaType.Representation; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; -import com.oracle.graal.graph.Node.*; +import com.oracle.graal.graph.Node.Verbosity; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; @@ -707,7 +707,8 @@ if (opportunities > 0) { metricInliningTailDuplication.increment(); Debug.log("MultiTypeGuardInlineInfo starting tail duplication (%d opportunities)", opportunities); - TailDuplicationPhase.tailDuplicate(returnMerge, TailDuplicationPhase.TRUE_DECISION, replacementNodes, new PhaseContext(runtime, assumptions, replacements)); + TailDuplicationPhase.tailDuplicate(returnMerge, TailDuplicationPhase.TRUE_DECISION, replacementNodes, new PhaseContext(runtime, assumptions, replacements), new CanonicalizerPhase( + !AOTCompilation.getValue())); } } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InsertStateAfterPlaceholderPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InsertStateAfterPlaceholderPhase.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InsertStateAfterPlaceholderPhase.java Fri Sep 13 23:12:10 2013 +0200 @@ -30,7 +30,7 @@ public class InsertStateAfterPlaceholderPhase extends Phase { - private static class PlaceholderNode extends AbstractStateSplit implements StateSplit, Node.IterableNodeType, LIRLowerable, Canonicalizable { + private static class PlaceholderNode extends AbstractStateSplit implements StateSplit, IterableNodeType, LIRLowerable, Canonicalizable { public PlaceholderNode() { super(StampFactory.forVoid()); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java Fri Sep 13 23:12:10 2013 +0200 @@ -22,8 +22,6 @@ */ package com.oracle.graal.phases.common; -import static com.oracle.graal.phases.GraalOptions.*; - import com.oracle.graal.api.code.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; @@ -36,6 +34,12 @@ private static final int MAX_ITERATIONS = 256; + private final CanonicalizerPhase canonicalizer; + + public IterativeConditionalEliminationPhase(CanonicalizerPhase canonicalizer) { + this.canonicalizer = canonicalizer; + } + @Override protected void run(StructuredGraph graph, PhaseContext context) { ConditionalEliminationPhase eliminate = new ConditionalEliminationPhase(context.getRuntime()); @@ -55,7 +59,7 @@ listener.getChangedNodes().add(node); } } - new CanonicalizerPhase.Instance(context.getRuntime(), context.getAssumptions(), !AOTCompilation.getValue(), listener.getChangedNodes(), null).apply(graph); + canonicalizer.applyIncremental(graph, context, listener.getChangedNodes()); listener.getChangedNodes().clear(); if (++count > MAX_ITERATIONS) { throw new BailoutException("Number of iterations in conditional elimination phase exceeds " + MAX_ITERATIONS); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Fri Sep 13 23:12:10 2013 +0200 @@ -35,7 +35,6 @@ import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.spi.Lowerable.LoweringType; import com.oracle.graal.nodes.type.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.schedule.*; @@ -73,11 +72,6 @@ } @Override - public LoweringType getLoweringType() { - return loweringType; - } - - @Override public GuardingNode createNullCheckGuard(GuardedNode guardedNode, ValueNode object) { if (ObjectStamp.isObjectNonNull(object)) { // Short cut creation of null check guard if the object is known to be non-null. @@ -101,8 +95,8 @@ @Override public GuardingNode createGuard(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated) { - if (loweringType != LoweringType.BEFORE_GUARDS) { - throw new GraalInternalError("Cannot create guards in after-guard lowering"); + if (condition.graph().getGuardsPhase().ordinal() > StructuredGraph.GuardsStage.FLOATING_GUARDS.ordinal()) { + throw new GraalInternalError("Cannot create guards after guard lowering"); } if (OptEliminateGuards.getValue()) { for (Node usage : condition.usages()) { @@ -134,11 +128,10 @@ } } - private final LoweringType loweringType; + private final CanonicalizerPhase canonicalizer; - public LoweringPhase(LoweringType loweringType) { - super("Lowering (" + loweringType.name() + ")"); - this.loweringType = loweringType; + public LoweringPhase(CanonicalizerPhase canonicalizer) { + this.canonicalizer = canonicalizer; } private static boolean containsLowerable(NodeIterable nodes) { @@ -154,12 +147,11 @@ protected void run(final StructuredGraph graph, PhaseContext context) { int i = 0; while (true) { - Round round = new Round(i++, context); int mark = graph.getMark(); - IncrementalCanonicalizerPhase canonicalizer = new IncrementalCanonicalizerPhase<>(); - canonicalizer.appendPhase(round); - canonicalizer.apply(graph, context); + IncrementalCanonicalizerPhase incrementalCanonicalizer = new IncrementalCanonicalizerPhase<>(canonicalizer); + incrementalCanonicalizer.appendPhase(new Round(i++, context)); + incrementalCanonicalizer.apply(graph, context); if (!containsLowerable(graph.getNewNodes(mark))) { // No new lowerable nodes - done! @@ -175,7 +167,7 @@ private final SchedulePhase schedule; private Round(int iteration, PhaseContext context) { - super(String.format("Lowering iteration %d", iteration)); + super("LoweringIteration" + iteration); this.context = context; this.schedule = new SchedulePhase(); } @@ -239,7 +231,7 @@ if (node instanceof Lowerable) { assert checkUsagesAreScheduled(node); - ((Lowerable) node).lower(loweringTool, loweringType); + ((Lowerable) node).lower(loweringTool); } if (!nextNode.isAlive()) { diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/RemoveValueProxyPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/RemoveValueProxyPhase.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/RemoveValueProxyPhase.java Fri Sep 13 23:12:10 2013 +0200 @@ -39,7 +39,7 @@ FrameState stateAfter = exit.stateAfter(); if (stateAfter != null) { exit.setStateAfter(null); - if (stateAfter.usages().count() == 0) { + if (stateAfter.usages().isEmpty()) { stateAfter.safeDelete(); } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java Fri Sep 13 23:12:10 2013 +0200 @@ -42,8 +42,8 @@ /** * This class is a phase that looks for opportunities for tail duplication. The static method - * {@link #tailDuplicate(MergeNode, TailDuplicationDecision, List, PhaseContext)} can also be used - * to drive tail duplication from other places, e.g., inlining. + * {@link #tailDuplicate(MergeNode, TailDuplicationDecision, List, PhaseContext, CanonicalizerPhase)} + * can also be used to drive tail duplication from other places, e.g., inlining. */ public class TailDuplicationPhase extends BasePhase { @@ -53,6 +53,8 @@ private static final DebugMetric metricDuplicationConsidered = Debug.metric("DuplicationConsidered"); private static final DebugMetric metricDuplicationPerformed = Debug.metric("DuplicationPerformed"); + private final CanonicalizerPhase canonicalizer; + /** * This interface is used by tail duplication to let clients decide if tail duplication should * be performed. @@ -129,6 +131,10 @@ } }; + public TailDuplicationPhase(CanonicalizerPhase canonicalizer) { + this.canonicalizer = canonicalizer; + } + @Override protected void run(StructuredGraph graph, PhaseContext phaseContext) { NodesToDoubles nodeProbabilities = new ComputeProbabilityClosure(graph).apply(); @@ -137,7 +143,7 @@ // duplication. for (MergeNode merge : graph.getNodes(MergeNode.class).snapshot()) { if (!(merge instanceof LoopBeginNode) && nodeProbabilities.get(merge) >= TailDuplicationProbability.getValue()) { - tailDuplicate(merge, DEFAULT_DECISION, null, phaseContext); + tailDuplicate(merge, DEFAULT_DECISION, null, phaseContext, canonicalizer); } } } @@ -159,7 +165,7 @@ * {@link PiNode} in the duplicated branch that corresponds to the entry. * @param phaseContext */ - public static boolean tailDuplicate(MergeNode merge, TailDuplicationDecision decision, List replacements, PhaseContext phaseContext) { + public static boolean tailDuplicate(MergeNode merge, TailDuplicationDecision decision, List replacements, PhaseContext phaseContext, CanonicalizerPhase canonicalizer) { assert !(merge instanceof LoopBeginNode); assert replacements == null || replacements.size() == merge.forwardEndCount(); FixedNode fixed = merge; @@ -172,7 +178,7 @@ metricDuplicationConsidered.increment(); if (decision.doTransform(merge, fixedCount)) { metricDuplicationPerformed.increment(); - new DuplicationOperation(merge, replacements).duplicate(phaseContext); + new DuplicationOperation(merge, replacements, canonicalizer).duplicate(phaseContext); return true; } } @@ -190,6 +196,8 @@ private final HashMap bottomPhis = new HashMap<>(); private final List replacements; + private final CanonicalizerPhase canonicalizer; + /** * Initializes the tail duplication operation without actually performing any work. * @@ -197,10 +205,11 @@ * @param replacements A list of replacement {@link PiNode}s, or null. If this is non-null, * then the size of the list needs to match the number of end nodes at the merge. */ - public DuplicationOperation(MergeNode merge, List replacements) { + public DuplicationOperation(MergeNode merge, List replacements, CanonicalizerPhase canonicalizer) { this.merge = merge; this.replacements = replacements; this.graph = merge.graph(); + this.canonicalizer = canonicalizer; } /** @@ -289,7 +298,7 @@ phi.setMerge(mergeAfter); } } - new CanonicalizerPhase.Instance(phaseContext.getRuntime(), phaseContext.getAssumptions(), !AOTCompilation.getValue(), graph.getNewNodes(startMark), null).apply(graph); + canonicalizer.applyIncremental(graph, phaseContext, startMark); Debug.dump(graph, "After tail duplication at %s", merge); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java Fri Sep 13 23:12:10 2013 +0200 @@ -22,7 +22,10 @@ */ package com.oracle.graal.phases; +import java.util.regex.*; + import com.oracle.graal.debug.*; +import com.oracle.graal.debug.internal.*; import com.oracle.graal.nodes.*; /** @@ -32,19 +35,35 @@ */ public abstract class BasePhase { - private String name; - private static final DebugMetric metricPhaseRuns = Debug.metric("Runs"); - protected static final DebugMetric METRIC_PROCESSED_NODES = Debug.metric("ProcessedNodes"); + private final String name; + + private final DebugTimer phaseTimer; + private final DebugMetric phaseMetric; + + private static final Pattern NAME_PATTERN = Pattern.compile("[A-Z][A-Za-z0-9]+"); + + private static boolean checkName(String name) { + assert NAME_PATTERN.matcher(name).matches() : "illegal phase name: " + name; + return true; + } protected BasePhase() { - this.name = this.getClass().getSimpleName(); - if (name.endsWith("Phase")) { - name = name.substring(0, name.length() - "Phase".length()); + String nm = this.getClass().getSimpleName(); + if (nm.endsWith("Phase")) { + name = nm.substring(0, nm.length() - "Phase".length()); + } else { + name = nm; } + assert checkName(name); + phaseTimer = Debug.timer("PhaseTime_" + name); + phaseMetric = Debug.metric("PhaseCount_" + name); } protected BasePhase(String name) { + assert checkName(name); this.name = name; + phaseTimer = Debug.timer("PhaseTime_" + name); + phaseMetric = Debug.metric("PhaseCount_" + name); } protected String getDetailedName() { @@ -56,17 +75,20 @@ } public final void apply(final StructuredGraph graph, final C context, final boolean dumpGraph) { - Debug.scope(name, this, new Runnable() { + try (TimerCloseable a = phaseTimer.start()) { + + Debug.scope(name, this, new Runnable() { - public void run() { - BasePhase.this.run(graph, context); - metricPhaseRuns.increment(); - if (dumpGraph) { - Debug.dump(graph, "After phase %s", name); + public void run() { + BasePhase.this.run(graph, context); + phaseMetric.increment(); + if (dumpGraph) { + Debug.dump(graph, "After phase %s", name); + } + assert graph.verify(); } - assert graph.verify(); - } - }); + }); + } } public final String getName() { diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ReentrantNodeIterator.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ReentrantNodeIterator.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ReentrantNodeIterator.java Fri Sep 13 23:12:10 2013 +0200 @@ -44,6 +44,15 @@ protected abstract StateT afterSplit(AbstractBeginNode node, StateT oldState); protected abstract Map processLoop(LoopBeginNode loop, StateT initialState); + + /** + * Determine whether iteration should continue in the current state. + * + * @param currentState + */ + protected boolean continueIteration(StateT currentState) { + return true; + } } private ReentrantNodeIterator() { @@ -59,12 +68,14 @@ LoopInfo info = new LoopInfo<>(); for (LoopEndNode end : loop.loopEnds()) { - assert blockEndStates.containsKey(end) : "no end state for " + end; - info.endStates.put(end, blockEndStates.get(end)); + if (blockEndStates.containsKey(end)) { + info.endStates.put(end, blockEndStates.get(end)); + } } for (LoopExitNode exit : loop.loopExits()) { - assert blockEndStates.containsKey(exit) : "no exit state for " + exit; - info.exitStates.put(exit, blockEndStates.get(exit)); + if (blockEndStates.containsKey(exit)) { + info.exitStates.put(exit, blockEndStates.get(exit)); + } } return info; } @@ -83,64 +94,69 @@ } else { FixedNode next = ((FixedWithNextNode) current).next(); state = closure.processNode(current, state); - current = next; + current = closure.continueIteration(state) ? next : null; } } if (current != null) { state = closure.processNode(current, state); - NodeClassIterator successors = current.successors().iterator(); - if (!successors.hasNext()) { - if (current instanceof LoopEndNode) { - blockEndStates.put(current, state); - } else if (current instanceof EndNode) { - // add the end node and see if the merge is ready for processing - MergeNode merge = ((EndNode) current).merge(); - if (merge instanceof LoopBeginNode) { - Map loopExitState = closure.processLoop((LoopBeginNode) merge, state); - for (Map.Entry entry : loopExitState.entrySet()) { - blockEndStates.put(entry.getKey(), entry.getValue()); - nodeQueue.add(entry.getKey()); - } - } else { - assert !blockEndStates.containsKey(current); + if (closure.continueIteration(state)) { + NodeClassIterator successors = current.successors().iterator(); + if (!successors.hasNext()) { + if (current instanceof LoopEndNode) { blockEndStates.put(current, state); - boolean endsVisited = true; - for (AbstractEndNode forwardEnd : merge.forwardEnds()) { - if (!blockEndStates.containsKey(forwardEnd)) { - endsVisited = false; - break; + } else if (current instanceof EndNode) { + // add the end node and see if the merge is ready for processing + MergeNode merge = ((EndNode) current).merge(); + if (merge instanceof LoopBeginNode) { + Map loopExitState = closure.processLoop((LoopBeginNode) merge, state); + for (Map.Entry entry : loopExitState.entrySet()) { + blockEndStates.put(entry.getKey(), entry.getValue()); + nodeQueue.add(entry.getKey()); + } + } else { + assert !blockEndStates.containsKey(current); + blockEndStates.put(current, state); + boolean endsVisited = true; + for (AbstractEndNode forwardEnd : merge.forwardEnds()) { + if (!blockEndStates.containsKey(forwardEnd)) { + endsVisited = false; + break; + } + } + if (endsVisited) { + ArrayList states = new ArrayList<>(merge.forwardEndCount()); + for (int i = 0; i < merge.forwardEndCount(); i++) { + AbstractEndNode forwardEnd = merge.forwardEndAt(i); + assert blockEndStates.containsKey(forwardEnd); + StateT other = blockEndStates.get(forwardEnd); + states.add(other); + } + state = closure.merge(merge, states); + current = closure.continueIteration(state) ? merge : null; + continue; } } - if (endsVisited) { - ArrayList states = new ArrayList<>(merge.forwardEndCount()); - for (int i = 0; i < merge.forwardEndCount(); i++) { - AbstractEndNode forwardEnd = merge.forwardEndAt(i); - assert blockEndStates.containsKey(forwardEnd); - StateT other = blockEndStates.get(forwardEnd); - states.add(other); - } - state = closure.merge(merge, states); - current = merge; - continue; - } } - } - } else { - FixedNode firstSuccessor = (FixedNode) successors.next(); - if (!successors.hasNext()) { - current = firstSuccessor; - continue; } else { - while (successors.hasNext()) { - AbstractBeginNode successor = (AbstractBeginNode) successors.next(); - blockEndStates.put(successor, closure.afterSplit(successor, state)); - nodeQueue.add(successor); + FixedNode firstSuccessor = (FixedNode) successors.next(); + if (!successors.hasNext()) { + current = firstSuccessor; + continue; + } else { + while (successors.hasNext()) { + AbstractBeginNode successor = (AbstractBeginNode) successors.next(); + StateT successorState = closure.afterSplit(successor, state); + if (closure.continueIteration(successorState)) { + blockEndStates.put(successor, successorState); + nodeQueue.add(successor); + } + } + state = closure.afterSplit((AbstractBeginNode) firstSuccessor, state); + current = closure.continueIteration(state) ? firstSuccessor : null; + continue; } - state = closure.afterSplit((AbstractBeginNode) firstSuccessor, state); - current = firstSuccessor; - continue; } } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/HighTierContext.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/HighTierContext.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/HighTierContext.java Fri Sep 13 23:12:10 2013 +0200 @@ -52,4 +52,8 @@ public OptimisticOptimizations getOptimisticOptimizations() { return optimisticOpts; } + + public HighTierContext replaceAssumptions(Assumptions newAssumptions) { + return new HighTierContext(getRuntime(), newAssumptions, getReplacements(), getGraphCache(), getPhasePlan(), getOptimisticOptimizations()); + } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java Fri Sep 13 23:12:10 2013 +0200 @@ -34,7 +34,10 @@ public class DebugEnvironment { public static void initialize(PrintStream log) { - Debug.enable(); + if (!Debug.isEnabled()) { + log.println("WARNING: Scope debugging needs to be enabled with -esa or -D" + Debug.Initialization.INITIALIZER_PROPERTY_NAME + "=true"); + return; + } List dumpHandlers = new ArrayList<>(); dumpHandlers.add(new GraphPrinterDumpHandler()); if (PrintCFG.getValue() || PrintBackendCFG.getValue()) { diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.ptx/src/com/oracle/graal/ptx/PTX.java --- a/graal/com.oracle.graal.ptx/src/com/oracle/graal/ptx/PTX.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.ptx/src/com/oracle/graal/ptx/PTX.java Fri Sep 13 23:12:10 2013 +0200 @@ -35,83 +35,167 @@ */ public class PTX extends Architecture { - public static final RegisterCategory CPU = new RegisterCategory("CPU"); - public static final RegisterCategory FPU = new RegisterCategory("FPU"); + public static final RegisterCategory REG = new RegisterCategory("REG"); + public static final RegisterCategory SREG = new RegisterCategory("SREG"); + public static final RegisterCategory PARAM = new RegisterCategory("PARAM"); + // @formatter:off + /* Parameter State Space + * + * The parameter (.param) state space is used (1) to pass input + * arguments from the host to the kernel, (2a) to declare formal + * input and return parameters for device functions called from + * within kernel execution, and (2b) to declare locally-scoped + * byte array variables that serve as function call arguments, + * typically for passing large structures by value to a function. + * + * TODO: XXX + * The parameters are virtual symbols - just like registers. Bit, + * Till we figure out how to model a virtual register set in Graal, + * we will pretend that we can use only 8 parameters. + */ + + public static final Register param0 = new Register(0, 0, "param0", PARAM); + public static final Register param1 = new Register(1, 1, "param1", PARAM); + public static final Register param2 = new Register(2, 2, "param2", PARAM); + public static final Register param3 = new Register(3, 3, "param3", PARAM); + public static final Register param4 = new Register(4, 4, "param4", PARAM); + public static final Register param5 = new Register(5, 5, "param5", PARAM); + public static final Register param6 = new Register(6, 6, "param6", PARAM); + public static final Register param7 = new Register(7, 7, "param7", PARAM); + /* * Register State Space * - * Registers (.reg state space) are fast storage locations. The number of - * registers is limited, and will vary from platform to platform. When the - * limit is exceeded, register variables will be spilled to memory, causing - * changes in performance. For each architecture, there is a recommended - * maximum number of registers to use (see the "CUDA Programming Guide" for - * details). + * Registers (.reg state space) are fast storage locations. The + * number of GPU architectural registers is limited, and will vary + * from platform to platform. When the limit is exceeded, register + * variables will be spilled to memory, causing changes in + * performance. For each architecture, there is a recommended + * maximum number of registers to use (see the "CUDA Programming + * Guide" for details). + * + * TODD: XXX + * + * However, PTX supports virtual registers. So, the generated PTX + * code does not need to use a specified number of registers. Till + * we figure out how to model a virtual register set in Graal, we + * will pretend that we can use only 16 registers. */ - // General purpose registers - public static final Register r0 = new Register(0, 0, "r0", CPU); - public static final Register r1 = new Register(1, 1, "r1", CPU); - public static final Register r2 = new Register(2, 2, "r2", CPU); - public static final Register r3 = new Register(3, 3, "r3", CPU); - public static final Register r4 = new Register(4, 4, "r4", CPU); - public static final Register r5 = new Register(5, 5, "r5", CPU); - public static final Register r6 = new Register(6, 6, "r6", CPU); - public static final Register r7 = new Register(7, 7, "r7", CPU); + public static final Register r0 = new Register(8, 8, "r0", REG); + public static final Register r1 = new Register(9, 9, "r1", REG); + public static final Register r2 = new Register(10, 10, "r2", REG); + public static final Register r3 = new Register(11, 11, "r3", REG); + public static final Register r4 = new Register(12, 12, "r4", REG); + public static final Register r5 = new Register(13, 13, "r5", REG); + public static final Register r6 = new Register(14, 14, "r6", REG); + public static final Register r7 = new Register(15, 15, "r7", REG); - public static final Register r8 = new Register(8, 8, "r8", CPU); - public static final Register r9 = new Register(9, 9, "r9", CPU); - public static final Register r10 = new Register(10, 10, "r10", CPU); - public static final Register r11 = new Register(11, 11, "r11", CPU); - public static final Register r12 = new Register(12, 12, "r12", CPU); - public static final Register r13 = new Register(13, 13, "r13", CPU); - public static final Register r14 = new Register(14, 14, "r14", CPU); - public static final Register r15 = new Register(15, 15, "r15", CPU); + public static final Register r8 = new Register(16, 16, "r8", REG); + public static final Register r9 = new Register(17, 17, "r9", REG); + public static final Register r10 = new Register(18, 18, "r10", REG); + public static final Register r11 = new Register(19, 19, "r11", REG); + public static final Register r12 = new Register(20, 20, "r12", REG); + public static final Register r13 = new Register(21, 21, "r13", REG); + public static final Register r14 = new Register(22, 22, "r14", REG); + public static final Register r15 = new Register(23, 23, "r15", REG); + + // Define a virtual register that holds return value + public static final Register retReg = new Register(24, 24, "retReg", REG); public static final Register[] gprRegisters = { r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15 }; - // Floating point registers - public static final Register f0 = new Register(16, 0, "f0", FPU); - public static final Register f1 = new Register(17, 1, "f1", FPU); - public static final Register f2 = new Register(18, 2, "f2", FPU); - public static final Register f3 = new Register(19, 3, "f3", FPU); - public static final Register f4 = new Register(20, 4, "f4", FPU); - public static final Register f5 = new Register(21, 5, "f5", FPU); - public static final Register f6 = new Register(22, 6, "f6", FPU); - public static final Register f7 = new Register(23, 7, "f7", FPU); + public static final Register[] paramRegisters = { + param0, param1, param2, param3, param4, param5, param6, param7 + }; + + // PTX ISA Manual: Section 9:. Special Registers - public static final Register f8 = new Register(24, 8, "f8", FPU); - public static final Register f9 = new Register(25, 9, "f9", FPU); - public static final Register f10 = new Register(26, 10, "f10", FPU); - public static final Register f11 = new Register(27, 11, "f11", FPU); - public static final Register f12 = new Register(28, 12, "f12", FPU); - public static final Register f13 = new Register(29, 13, "f13", FPU); - public static final Register f14 = new Register(30, 14, "f14", FPU); - public static final Register f15 = new Register(31, 15, "f15", FPU); + // PTX includes a number of predefined, read-only variables, which + // are visible as special registers and accessed through mov or + // cvt instructions. + // Thread identifier within a Co-operative Thread Array (CTA) - %tid + public static final Register tid = new Register(100, 100, "tid", SREG); + // Number of thread IDs per CTA - %ntid + public static final Register ntid = new Register(101, 101, "ntid", SREG); + // Lane identifier + public static final Register laneid = new Register(102, 102, "laneid", SREG); + // Warp identifier + public static final Register warpid = new Register(103, 103, "warid", SREG); + // Number of warp IDs + public static final Register nwarpid = new Register(104, 104, "nwarpid", SREG); + // CTA identifier + public static final Register ctaid = new Register(105, 105, "ctaid", SREG); + // Number of CTA IDs per grid + public static final Register nctaid = new Register(106, 106, "nctaid", SREG); + // Single Multiprocessor (SM) ID + public static final Register smid = new Register(107, 107, "smid", SREG); + // Number of SM IDs + public static final Register nsmid = new Register(108, 108, "nsmid", SREG); + // Grid ID + public static final Register gridid = new Register(109, 109, "gridid", SREG); + // 32-bit mask with bit set in position equal to thread's lane number in the warp + public static final Register lanemask_eq = new Register(110, 110, "lanemask_eq", SREG); + // 32-bit mask with bits set in positions less than or equal to thread's lane number in the warp + public static final Register lanemask_le = new Register(111, 111, "lanemask_le", SREG); + // 32-bit mask with bits set in positions less than thread's lane number in the warp + public static final Register lanemask_lt = new Register(112, 112, "lanemask_lt", SREG); + // 32-bit mask with bits set in positions greater than or equal to thread's lane number in the warp + public static final Register lanemask_ge = new Register(113, 113, "lanemask_ge", SREG); + // 32-bit mask with bits set in positions greater than thread's lane number in the warp + public static final Register lanemask_gt = new Register(114, 114, "lanemask_gt", SREG); + // A predefined, read-only 32-bit unsigned 32-bit unsigned cycle counter + public static final Register clock = new Register(114, 114, "clock", SREG); + // A predefined, read-only 64-bit unsigned 32-bit unsigned cycle counter + public static final Register clock64 = new Register(115, 115, "clock64", SREG); + // Performance monitoring registers + public static final Register pm0 = new Register(116, 116, "pm0", SREG); + public static final Register pm1 = new Register(117, 117, "pm1", SREG); + public static final Register pm2 = new Register(118, 118, "pm2", SREG); + public static final Register pm3 = new Register(119, 119, "pm3", SREG); + public static final Register pm4 = new Register(120, 120, "pm4", SREG); + public static final Register pm5 = new Register(121, 121, "pm5", SREG); + public static final Register pm6 = new Register(122, 122, "pm6", SREG); + public static final Register pm7 = new Register(123, 123, "pm7", SREG); + // TODO: Add Driver-defined read-only %envreg<32> + // and %globaltimer, %globaltimer_lo and %globaltimer_hi - public static final Register[] fpuRegisters = { - f0, f1, f2, f3, f4, f5, f6, f7, - f8, f9, f10, f11, f12, f13, f14, f15 + public static final Register[] specialRegisters = { + tid, ntid, laneid, warpid, nwarpid, ctaid, + nctaid, smid, nsmid, gridid, + lanemask_eq, lanemask_le, lanemask_lt, lanemask_ge, lanemask_gt, + clock, clock64, + pm0, pm1, pm2, pm3, pm4, pm5, pm6, pm7 }; public static final Register[] allRegisters = { - // GPR + // Parameter State Space + param0, param1, param2, param3, + param4, param5, param6, param7, + // Register State Space r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, - // FPU - f0, f1, f2, f3, f4, f5, f6, f7, - f8, f9, f10, f11, f12, f13, f14, f15 + // return register + retReg, + // Special Register State Space - SREG + tid, ntid, laneid, warpid, nwarpid, ctaid, + nctaid, smid, nsmid, gridid, + lanemask_eq, lanemask_le, lanemask_lt, lanemask_ge, lanemask_gt, + clock, clock64, + pm0, pm1, pm2, pm3, pm4, pm5, pm6, pm7 }; // @formatter:on public PTX() { - super("PTX", 8, ByteOrder.LITTLE_ENDIAN, false, allRegisters, LOAD_STORE | STORE_STORE, 0, r15.encoding + 1, 8); + super("PTX", 8, ByteOrder.LITTLE_ENDIAN, false, allRegisters, + LOAD_STORE | STORE_STORE, 0, r15.encoding + 1, 8); } @Override @@ -121,7 +205,7 @@ } Kind kind = (Kind) platformKind; - if (category == CPU) { + if (category == REG) { switch (kind) { case Boolean: case Byte: @@ -130,10 +214,6 @@ case Int: case Long: case Object: - return true; - } - } else if (category == FPU) { - switch (kind) { case Float: case Double: return true; @@ -145,12 +225,12 @@ @Override public PlatformKind getLargestStorableKind(RegisterCategory category) { - if (category == CPU) { - return Kind.Long; - } else if (category == FPU) { + if (category == REG) { return Kind.Double; } else { return Kind.Illegal; } } + + } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/CheckCastTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/CheckCastTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/CheckCastTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -34,7 +34,7 @@ @Override protected void replaceProfile(StructuredGraph graph, JavaTypeProfile profile) { - CheckCastNode ccn = graph.getNodes(CheckCastNode.class).first(); + CheckCastNode ccn = graph.getNodes().filter(CheckCastNode.class).first(); if (ccn != null) { CheckCastNode ccnNew = graph.add(new CheckCastNode(ccn.type(), ccn.object(), profile, false)); graph.replaceFixedWithFixed(ccn, ccnNew); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -53,7 +53,7 @@ Assumptions assumptions = new Assumptions(true); HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, phasePlan, OptimisticOptimizations.ALL); Debug.dump(graph, "Graph"); - new InliningPhase().apply(graph, context); + new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); Debug.dump(graph, "Graph"); new CanonicalizerPhase(true).apply(graph, context); new DeadCodeEliminationPhase().apply(graph); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java Fri Sep 13 23:12:10 2013 +0200 @@ -93,7 +93,7 @@ */ protected InstanceOfUsageReplacer createReplacer(FloatingNode instanceOf, Instantiation instantiation, Node usage, final StructuredGraph graph) { InstanceOfUsageReplacer replacer; - if (usage instanceof IfNode || usage instanceof FixedGuardNode || usage instanceof ShortCircuitBooleanNode || usage instanceof GuardingPiNode) { + if (usage instanceof IfNode || usage instanceof FixedGuardNode || usage instanceof ShortCircuitOrNode || usage instanceof GuardingPiNode) { replacer = new NonMaterializationUsageReplacer(instantiation, ConstantNode.forInt(1, graph), ConstantNode.forInt(0, graph), instanceOf, usage); } else { assert usage instanceof ConditionalNode : "unexpected usage of " + instanceOf + ": " + usage; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Fri Sep 13 23:12:10 2013 +0200 @@ -67,7 +67,7 @@ } } - private boolean tryIntrinsify(MethodCallTargetNode methodCallTargetNode, List cleanUpReturnList) { + protected boolean tryIntrinsify(MethodCallTargetNode methodCallTargetNode, List cleanUpReturnList) { ResolvedJavaMethod target = methodCallTargetNode.targetMethod(); NodeIntrinsic intrinsic = target.getAnnotation(Node.NodeIntrinsic.class); ResolvedJavaType declaringClass = target.getDeclaringClass(); @@ -94,7 +94,7 @@ // Clean up checkcast instructions inserted by javac if the return type is generic. cleanUpReturnList.add(newInstance); - } else if (target.getAnnotation(Fold.class) != null) { + } else if (isFoldable(target)) { ResolvedJavaType[] parameterTypes = MetaUtil.resolveJavaTypes(MetaUtil.signatureToTypes(target), declaringClass); // Prepare the arguments for the reflective method call @@ -128,9 +128,16 @@ } /** + * Permits a subclass to override the default definition of "foldable". + */ + protected boolean isFoldable(ResolvedJavaMethod method) { + return method.getAnnotation(Fold.class) != null; + } + + /** * Converts the arguments of an invoke node to object values suitable for use as the arguments * to a reflective invocation of a Java constructor or method. - * + * * @param folding specifies if the invocation is for handling a {@link Fold} annotation * @return the arguments for the reflective invocation or null if an argument of {@code invoke} * that is expected to be constant isn't diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Fri Sep 13 23:12:10 2013 +0200 @@ -44,6 +44,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.tiers.*; import com.oracle.graal.replacements.Snippet.DefaultSnippetInliningPolicy; import com.oracle.graal.replacements.Snippet.SnippetInliningPolicy; import com.oracle.graal.word.phases.*; @@ -160,7 +161,7 @@ /** * Registers a method substitution. - * + * * @param originalMember a method or constructor being substituted * @param substituteMethod the substitute method * @return the original method @@ -181,7 +182,7 @@ /** * Registers a macro substitution. - * + * * @param originalMethod a method or constructor being substituted * @param macro the substitute macro node class * @return the original method @@ -215,7 +216,7 @@ /** * Creates a preprocessed graph for a snippet or method substitution. - * + * * @param method the snippet or method substitution for which a graph will be created * @param original the original method if {@code method} is a {@linkplain MethodSubstitution * substitution} otherwise null @@ -331,23 +332,28 @@ new WordTypeVerificationPhase(runtime, target.wordKind).apply(graph); if (OptCanonicalizer.getValue()) { new WordTypeRewriterPhase(runtime, target.wordKind).apply(graph); - new CanonicalizerPhase.Instance(runtime, assumptions, true).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime, assumptions, ReplacementsImpl.this)); } } }); return graph; } + protected Object beforeInline(@SuppressWarnings("unused") MethodCallTargetNode callTarget, @SuppressWarnings("unused") StructuredGraph callee) { + return null; + } + /** * Called after a graph is inlined. - * + * * @param caller the graph into which {@code callee} was inlined * @param callee the graph that was inlined into {@code caller} + * @param beforeInlineData value returned by {@link #beforeInline}. */ - protected void afterInline(StructuredGraph caller, StructuredGraph callee) { + protected void afterInline(StructuredGraph caller, StructuredGraph callee, Object beforeInlineData) { if (OptCanonicalizer.getValue()) { new WordTypeRewriterPhase(runtime, target.wordKind).apply(caller); - new CanonicalizerPhase.Instance(runtime, assumptions, true).apply(caller); + new CanonicalizerPhase(true).apply(caller, new PhaseContext(runtime, assumptions, ReplacementsImpl.this)); } } @@ -361,7 +367,7 @@ new DeadCodeEliminationPhase().apply(graph); if (OptCanonicalizer.getValue()) { - new CanonicalizerPhase.Instance(runtime, assumptions, true).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime, assumptions, ReplacementsImpl.this)); } } @@ -380,7 +386,7 @@ InliningUtil.inline(callTarget.invoke(), originalGraph, true); Debug.dump(graph, "after inlining %s", callee); - afterInline(graph, originalGraph); + afterInline(graph, originalGraph, null); substituteCallsOriginal = true; } else { StructuredGraph intrinsicGraph = InliningUtil.getIntrinsicGraph(ReplacementsImpl.this, callee); @@ -397,9 +403,10 @@ } targetGraph = parseGraph(callee, policy); } + Object beforeInlineData = beforeInline(callTarget, targetGraph); InliningUtil.inline(callTarget.invoke(), targetGraph, true); Debug.dump(graph, "after inlining %s", callee); - afterInline(graph, targetGraph); + afterInline(graph, targetGraph, beforeInlineData); } } } @@ -427,7 +434,7 @@ /** * Resolves a name to a class. - * + * * @param className the name of the class to resolve * @param optional if true, resolution failure returns null * @return the resolved class or null if resolution fails and {@code optional} is true diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Fri Sep 13 23:12:10 2013 +0200 @@ -41,6 +41,7 @@ import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.tiers.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; import com.oracle.graal.replacements.Snippet.VarargsParameter; import com.oracle.graal.replacements.nodes.*; @@ -388,6 +389,8 @@ ResolvedJavaMethod method = snippetGraph.method(); Signature signature = method.getSignature(); + PhaseContext context = new PhaseContext(runtime, replacements.getAssumptions(), replacements); + // Copy snippet graph, replacing constant parameters with given arguments StructuredGraph snippetCopy = new StructuredGraph(snippetGraph.name, snippetGraph.method()); IdentityHashMap nodeReplacements = new IdentityHashMap<>(); @@ -425,7 +428,7 @@ new NodeIntrinsificationPhase(runtime).apply(snippetCopy); new WordTypeRewriterPhase(runtime, target.wordKind).apply(snippetCopy); - new CanonicalizerPhase.Instance(runtime, replacements.getAssumptions(), true, 0, null).apply(snippetCopy); + new CanonicalizerPhase(true).apply(snippetCopy, context); } NodeIntrinsificationVerificationPhase.verify(snippetCopy); @@ -481,8 +484,8 @@ if (loopBegin != null) { LoopEx loop = new LoopsData(snippetCopy).loop(loopBegin); int mark = snippetCopy.getMark(); - LoopTransformations.fullUnroll(loop, runtime, replacements.getAssumptions(), true); - new CanonicalizerPhase.Instance(runtime, replacements.getAssumptions(), true, mark, null).apply(snippetCopy); + LoopTransformations.fullUnroll(loop, context, new CanonicalizerPhase(true)); + new CanonicalizerPhase(true).applyIncremental(snippetCopy, context, mark); } FixedNode explodeLoopNext = explodeLoop.next(); explodeLoop.clearSuccessors(); @@ -528,8 +531,6 @@ ReturnNode retNode = null; StartNode entryPointNode = snippet.start(); - new DeadCodeEliminationPhase().apply(snippetCopy); - nodes = new ArrayList<>(snippet.getNodeCount()); for (Node node : snippet.getNodes()) { if (node == entryPointNode || node == entryPointNode.stateAfter()) { diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -64,7 +64,7 @@ public static native void storeInt(Object obj, @ConstantNodeParameter int displacement, long offset, int value); @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, value.kind(), displacement, offset, graph(), 1); WriteNode write = graph().add(new WriteNode(object, value, location, BarrierType.NONE, value.kind() == Kind.Object)); graph().replaceFixedWithFixed(this, write); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -79,7 +79,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { boolean nullCheck = false; StructuredGraph replacementGraph = getSnippetGraph(tool); if (replacementGraph == null) { diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -36,7 +36,6 @@ import com.oracle.graal.loop.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.spi.Lowerable.LoweringType; import com.oracle.graal.phases.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; import com.oracle.graal.phases.common.*; @@ -118,7 +117,7 @@ if (ex.counted().isConstantMaxTripCount()) { long constant = ex.counted().constantMaxTripCount(); if (constant <= UNROLL_LIMIT) { - LoopTransformations.fullUnroll(ex, runtime, assumptions, canonicalizeReads); + LoopTransformations.fullUnroll(ex, context, canonicalizer); Debug.dump(resultGraph, "After loop unrolling %d times", constant); canonicalizer.apply(resultGraph, context); @@ -131,7 +130,7 @@ } new DeadCodeEliminationPhase().apply(resultGraph); - new PartialEscapePhase(true).apply(resultGraph, context); + new PartialEscapePhase(true, canonicalizer).apply(resultGraph, context); if (TruffleInlinePrinter.getValue()) { InlinePrinterProcessor.printTree(); @@ -161,7 +160,7 @@ frameState.replaceAtUsages(null); frameState.safeDelete(); } - new CanonicalizerPhase.Instance(runtime, new Assumptions(false), true).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime, new Assumptions(false), replacements)); new DeadCodeEliminationPhase().apply(graph); } @@ -169,34 +168,36 @@ StructuredGraph graphResult = Debug.scope("Truffle", new DebugDumpScope("Comparison: " + methodName), new Callable() { + @SuppressWarnings("deprecation") public StructuredGraph call() { Assumptions assumptions = new Assumptions(false); StructuredGraph graph = parse(methodName); - CanonicalizerPhase.Instance canonicalizerPhase = new CanonicalizerPhase.Instance(runtime, assumptions, true); - canonicalizerPhase.apply(graph); + PhaseContext context = new PhaseContext(runtime, assumptions, replacements); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); + canonicalizer.apply(graph, context); // Additional inlining. final PhasePlan plan = new PhasePlan(); GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getEagerDefault(), TruffleCompilerImpl.Optimizations); plan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); - plan.addPhase(PhasePosition.AFTER_PARSING, canonicalizerPhase); + canonicalizer.addToPhasePlan(plan, context); plan.addPhase(PhasePosition.AFTER_PARSING, new DeadCodeEliminationPhase()); new ConvertDeoptimizeToGuardPhase().apply(graph); - canonicalizerPhase.apply(graph); + canonicalizer.apply(graph, context); new DeadCodeEliminationPhase().apply(graph); - HighTierContext context = new HighTierContext(runtime, assumptions, replacements, null, plan, OptimisticOptimizations.NONE); - InliningPhase inliningPhase = new InliningPhase(); - inliningPhase.apply(graph, context); + HighTierContext highTierContext = new HighTierContext(runtime, assumptions, replacements, null, plan, OptimisticOptimizations.NONE); + InliningPhase inliningPhase = new InliningPhase(canonicalizer); + inliningPhase.apply(graph, highTierContext); removeFrameStates(graph); new ConvertDeoptimizeToGuardPhase().apply(graph); - canonicalizerPhase.apply(graph); + canonicalizer.apply(graph, context); new DeadCodeEliminationPhase().apply(graph); - new LoweringPhase(LoweringType.BEFORE_GUARDS).apply(graph, context); - canonicalizerPhase.apply(graph); + new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, context); + canonicalizer.apply(graph, context); new DeadCodeEliminationPhase().apply(graph); return graph; } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Fri Sep 13 23:12:10 2013 +0200 @@ -31,6 +31,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.internal.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node; import com.oracle.graal.hotspot.*; @@ -65,9 +66,8 @@ public class PartialEvaluator { private final MetaAccessProvider metaAccessProvider; - private final ResolvedJavaType nodeClass; private final ResolvedJavaMethod executeHelperMethod; - private final CustomCanonicalizer customCanonicalizer; + private final CanonicalizerPhase canonicalizer; private final ResolvedJavaType[] skippedExceptionTypes; private final Replacements replacements; private Set constantReceivers; @@ -76,8 +76,8 @@ public PartialEvaluator(MetaAccessProvider metaAccessProvider, Replacements replacements, TruffleCache truffleCache) { this.metaAccessProvider = metaAccessProvider; - this.nodeClass = metaAccessProvider.lookupJavaType(com.oracle.truffle.api.nodes.Node.class); - this.customCanonicalizer = new PartialEvaluatorCanonicalizer(metaAccessProvider, nodeClass); + CustomCanonicalizer customCanonicalizer = new PartialEvaluatorCanonicalizer(metaAccessProvider); + this.canonicalizer = new CanonicalizerPhase(!AOTCompilation.getValue(), customCanonicalizer); this.skippedExceptionTypes = TruffleCompilerImpl.getSkippedExceptionTypes(metaAccessProvider); this.replacements = replacements; this.cache = HotSpotGraalRuntime.graalRuntime().getCache(); @@ -113,6 +113,7 @@ Debug.scope("createGraph", graph, new Runnable() { + @SuppressWarnings("deprecation") @Override public void run() { new GraphBuilderPhase(metaAccessProvider, config, TruffleCompilerImpl.Optimizations).apply(graph); @@ -122,8 +123,8 @@ thisNode.replaceAndDelete(ConstantNode.forObject(node, metaAccessProvider, graph)); // Canonicalize / constant propagate. - CanonicalizerPhase.Instance canonicalizerPhase = new CanonicalizerPhase.Instance(metaAccessProvider, assumptions, !AOTCompilation.getValue(), null, customCanonicalizer); - canonicalizerPhase.apply(graph); + PhaseContext baseContext = new PhaseContext(metaAccessProvider, assumptions, replacements); + canonicalizer.apply(graph, baseContext); // Intrinsify methods. new ReplaceIntrinsicsPhase(replacements).apply(graph); @@ -148,29 +149,29 @@ for (Constant c : constantReceivers) { histogram.add(c.asObject().getClass().getSimpleName()); } - histogram.print(TTY.out().out()); + new DebugHistogramAsciiPrinter(TTY.out().out()).print(histogram); } // Additional inlining. final PhasePlan plan = new PhasePlan(); GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(metaAccessProvider, config, TruffleCompilerImpl.Optimizations); plan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); - plan.addPhase(PhasePosition.AFTER_PARSING, canonicalizerPhase); + canonicalizer.addToPhasePlan(plan, baseContext); plan.addPhase(PhasePosition.AFTER_PARSING, new ReplaceIntrinsicsPhase(replacements)); new ConvertDeoptimizeToGuardPhase().apply(graph); - canonicalizerPhase.apply(graph); + canonicalizer.apply(graph, baseContext); new DeadCodeEliminationPhase().apply(graph); HighTierContext context = new HighTierContext(metaAccessProvider, assumptions, replacements, cache, plan, OptimisticOptimizations.NONE); - InliningPhase inliningPhase = new InliningPhase(customCanonicalizer); + InliningPhase inliningPhase = new InliningPhase(canonicalizer); inliningPhase.apply(graph, context); // Convert deopt to guards. new ConvertDeoptimizeToGuardPhase().apply(graph); // Canonicalize / constant propagate. - canonicalizerPhase.apply(graph); + canonicalizer.apply(graph, context); for (NeverPartOfCompilationNode neverPartOfCompilationNode : graph.getNodes(NeverPartOfCompilationNode.class)) { Throwable exception = new VerificationError(neverPartOfCompilationNode.getMessage()); @@ -179,7 +180,7 @@ // EA frame and clean up. new VerifyFrameDoesNotEscapePhase().apply(graph, false); - new PartialEscapePhase(false).apply(graph, context); + new PartialEscapePhase(false, canonicalizer).apply(graph, context); new VerifyNoIntrinsicsLeftPhase().apply(graph, false); for (MaterializeFrameNode materializeNode : graph.getNodes(MaterializeFrameNode.class).snapshot()) { materializeNode.replaceAtUsages(materializeNode.getFrame()); @@ -202,7 +203,7 @@ new ConvertDeoptimizeToGuardPhase().apply(graph); // Canonicalize / constant propagate. - canonicalizerPhase.apply(graph); + canonicalizer.apply(graph, context); } }); @@ -228,7 +229,7 @@ StructuredGraph inlineGraph = replacements.getMethodSubstitution(methodCallTargetNode.targetMethod()); NewFrameNode otherNewFrame = null; if (inlineGraph == null) { - inlineGraph = parseGraph(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), assumptions, !AOTCompilation.getValue()); + inlineGraph = parseGraph(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), assumptions); otherNewFrame = inlineGraph.getNodes(NewFrameNode.class).first(); } @@ -256,7 +257,7 @@ } while (changed && newFrameNode.isAlive() && newFrameNode.usages().isNotEmpty()); } - private StructuredGraph parseGraph(final ResolvedJavaMethod targetMethod, final NodeInputList arguments, final Assumptions assumptions, final boolean canonicalizeReads) { + private StructuredGraph parseGraph(final ResolvedJavaMethod targetMethod, final NodeInputList arguments, final Assumptions assumptions) { final StructuredGraph graph = truffleCache.lookup(targetMethod, arguments, assumptions); Debug.scope("parseGraph", targetMethod, new Runnable() { @@ -265,13 +266,14 @@ public void run() { // Canonicalize / constant propagate. - new CanonicalizerPhase.Instance(metaAccessProvider, assumptions, canonicalizeReads, null, customCanonicalizer).apply(graph); + PhaseContext context = new PhaseContext(metaAccessProvider, assumptions, replacements); + canonicalizer.apply(graph, context); // Intrinsify methods. new ReplaceIntrinsicsPhase(replacements).apply(graph); // Inline trivial getter methods - new InlineTrivialGettersPhase(metaAccessProvider, assumptions, customCanonicalizer).apply(graph); + new InlineTrivialGettersPhase(metaAccessProvider, canonicalizer).apply(graph, context); // Convert deopt to guards. new ConvertDeoptimizeToGuardPhase().apply(graph); @@ -286,9 +288,9 @@ if (ex.counted().isConstantMaxTripCount()) { long constant = ex.counted().constantMaxTripCount(); if (constant <= TruffleConstantUnrollLimit.getValue() || targetMethod.getAnnotation(ExplodeLoop.class) != null) { - LoopTransformations.fullUnroll(ex, metaAccessProvider, assumptions, canonicalizeReads); + LoopTransformations.fullUnroll(ex, context, canonicalizer); Debug.dump(graph, "After loop unrolling %d times", constant); - new CanonicalizerPhase.Instance(metaAccessProvider, assumptions, canonicalizeReads, null, customCanonicalizer).apply(graph); + canonicalizer.apply(graph, context); unrolled = true; break; } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java Fri Sep 13 23:12:10 2013 +0200 @@ -27,7 +27,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.type.*; import com.oracle.graal.phases.common.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.nodes.Node.Child; @@ -35,40 +34,30 @@ final class PartialEvaluatorCanonicalizer implements CanonicalizerPhase.CustomCanonicalizer { private final MetaAccessProvider metaAccessProvider; - private final ResolvedJavaType nodeClass; - PartialEvaluatorCanonicalizer(MetaAccessProvider metaAccessProvider, ResolvedJavaType nodeClass) { + PartialEvaluatorCanonicalizer(MetaAccessProvider metaAccessProvider) { this.metaAccessProvider = metaAccessProvider; - this.nodeClass = nodeClass; } @Override public ValueNode canonicalize(ValueNode node) { if (node instanceof LoadFieldNode) { LoadFieldNode loadFieldNode = (LoadFieldNode) node; - if (!loadFieldNode.isStatic() && - loadFieldNode.object().isConstant() && - !loadFieldNode.object().isNullConstant() && - ((loadFieldNode.kind() == Kind.Object && loadFieldNode.field().getAnnotation(Child.class) != null) || Modifier.isFinal(loadFieldNode.field().getModifiers()) || loadFieldNode.field().getAnnotation( - CompilerDirectives.CompilationFinal.class) != null)) { - Constant constant = loadFieldNode.field().readValue(loadFieldNode.object().asConstant()); - return ConstantNode.forConstant(constant, metaAccessProvider, node.graph()); - } - } else if (node instanceof LoadIndexedNode) { - LoadIndexedNode loadIndexedNode = (LoadIndexedNode) node; - Stamp stamp = loadIndexedNode.array().stamp(); - if (stamp.kind() == Kind.Object && loadIndexedNode.array().isConstant() && !loadIndexedNode.array().isNullConstant() && loadIndexedNode.index().isConstant()) { - ObjectStamp objectStamp = (ObjectStamp) stamp; - ResolvedJavaType type = objectStamp.type(); - if (type != null && type.isArray() && this.nodeClass.isAssignableFrom(type.getComponentType())) { - Object array = loadIndexedNode.array().asConstant().asObject(); - int index = loadIndexedNode.index().asConstant().asInt(); - Object value = Array.get(array, index); - return ConstantNode.forObject(value, metaAccessProvider, node.graph()); + if (!loadFieldNode.isStatic() && loadFieldNode.object().isConstant() && !loadFieldNode.object().isNullConstant()) { + if (Modifier.isFinal(loadFieldNode.field().getModifiers()) || (loadFieldNode.kind() == Kind.Object && loadFieldNode.field().getAnnotation(Child.class) != null) || + loadFieldNode.field().getAnnotation(CompilerDirectives.CompilationFinal.class) != null) { + Constant constant = loadFieldNode.field().readValue(loadFieldNode.object().asConstant()); + assert verifyFieldValue(loadFieldNode.field(), constant); + return ConstantNode.forConstant(constant, metaAccessProvider, node.graph()); } } } return node; } + + private static boolean verifyFieldValue(ResolvedJavaField field, Constant constant) { + assert field.getAnnotation(Child.class) == null || constant.isNull() || constant.asObject() instanceof com.oracle.truffle.api.nodes.Node : "@Child field value must be a Node: " + field; + return true; + } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java Fri Sep 13 23:12:10 2013 +0200 @@ -112,7 +112,7 @@ optimizeGraph(newGraph, tmpAssumptions); PhaseContext context = new PhaseContext(metaAccessProvider, tmpAssumptions, replacements); - PartialEscapePhase partialEscapePhase = new PartialEscapePhase(false); + PartialEscapePhase partialEscapePhase = new PartialEscapePhase(false, new CanonicalizerPhase(!AOTCompilation.getValue())); partialEscapePhase.apply(newGraph, context); cache.put(method, newGraph); @@ -153,7 +153,7 @@ ConditionalEliminationPhase conditionalEliminationPhase = new ConditionalEliminationPhase(metaAccessProvider); ConvertDeoptimizeToGuardPhase convertDeoptimizeToGuardPhase = new ConvertDeoptimizeToGuardPhase(); CanonicalizerPhase canonicalizerPhase = new CanonicalizerPhase(!AOTCompilation.getValue()); - EarlyReadEliminationPhase readEliminationPhase = new EarlyReadEliminationPhase(); + EarlyReadEliminationPhase readEliminationPhase = new EarlyReadEliminationPhase(canonicalizerPhase); int maxNodes = TruffleCompilerOptions.TruffleOperationCacheMaxNodes.getValue(); @@ -180,6 +180,8 @@ private static void contractGraph(StructuredGraph newGraph, ConditionalEliminationPhase conditionalEliminationPhase, ConvertDeoptimizeToGuardPhase convertDeoptimizeToGuardPhase, CanonicalizerPhase canonicalizerPhase, EarlyReadEliminationPhase readEliminationPhase, PhaseContext context) { + new ReplaceLoadFinalPhase().apply(newGraph); + // Canonicalize / constant propagate. canonicalizerPhase.apply(newGraph, context); @@ -306,14 +308,18 @@ private static boolean checkArgumentStamps(StructuredGraph graph, NodeInputList arguments) { assert graph.getNodes(LocalNode.class).count() <= arguments.count(); - for (LocalNode localNode : graph.getNodes(LocalNode.class)) { - Stamp newStamp = localNode.stamp().meet(arguments.get(localNode.index()).stamp()); - if (!newStamp.equals(localNode.stamp())) { - if (TruffleCompilerOptions.TraceTruffleCacheDetails.getValue()) { - TTY.println(String.format("[truffle] graph cache entry too specific for method %s argument %s previous stamp %s new stamp %s.", graph.method(), localNode, localNode.stamp(), - newStamp)); + FrameState startState = graph.start().stateAfter(); + for (int i = 0; i < arguments.size(); i++) { + ValueNode localNode = startState.localAt(i); + if (localNode != null) { + Stamp newStamp = localNode.stamp().meet(arguments.get(i).stamp()); + if (!newStamp.equals(localNode.stamp())) { + if (TruffleCompilerOptions.TraceTruffleCacheDetails.getValue()) { + TTY.println(String.format("[truffle] graph cache entry too specific for method %s argument %s previous stamp %s new stamp %s.", graph.method(), localNode, localNode.stamp(), + newStamp)); + } + return false; } - return false; } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Fri Sep 13 23:12:10 2013 +0200 @@ -23,7 +23,6 @@ package com.oracle.graal.truffle; import static com.oracle.graal.api.code.CodeUtil.*; -import static com.oracle.graal.compiler.GraalDebugConfig.*; import java.util.*; import java.util.concurrent.*; @@ -84,7 +83,7 @@ this.partialEvaluator = new PartialEvaluator(metaAccessProvider, replacements, truffleCache); - if (DebugEnabled.getValue()) { + if (Debug.isEnabled()) { DebugEnvironment.initialize(System.out); } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -29,7 +29,7 @@ import com.oracle.graal.replacements.nodes.*; import com.oracle.graal.truffle.*; -public class AssumptionNode extends MacroNode implements com.oracle.graal.graph.Node.IterableNodeType, Simplifiable { +public class AssumptionNode extends MacroNode implements com.oracle.graal.graph.IterableNodeType, Simplifiable { public AssumptionNode(Invoke invoke) { super(invoke); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -27,7 +27,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; -public class BailoutNode extends MacroNode implements com.oracle.graal.graph.Node.IterableNodeType, Canonicalizable { +public class BailoutNode extends MacroNode implements Canonicalizable { public BailoutNode(Invoke invoke) { super(invoke); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/LoadIndexedFinalNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/LoadIndexedFinalNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -0,0 +1,86 @@ +/* + * 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.truffle.nodes; + +import java.lang.reflect.*; + +import sun.misc.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +/** + * @see LoadIndexedNode + */ +public final class LoadIndexedFinalNode extends AccessIndexedNode implements Canonicalizable { + + /** + * Creates a new {@link LoadIndexedFinalNode}. + * + * @param array the instruction producing the array + * @param index the instruction producing the index + * @param elementKind the element type + */ + public LoadIndexedFinalNode(ValueNode array, ValueNode index, Kind elementKind) { + super(createStamp(array, elementKind), array, index, elementKind); + } + + @Override + public ValueNode canonical(CanonicalizerTool tool) { + if (array().isConstant() && !array().isNullConstant() && index().isConstant()) { + Object array = array().asConstant().asObject(); + long index = index().asConstant().asLong(); + if (index >= 0 && index < Array.getLength(array)) { + int arrayBaseOffset = Unsafe.getUnsafe().arrayBaseOffset(array.getClass()); + int arrayIndexScale = Unsafe.getUnsafe().arrayIndexScale(array.getClass()); + Constant constant = tool.runtime().readUnsafeConstant(elementKind(), array, arrayBaseOffset + index * arrayIndexScale, elementKind() == Kind.Object); + return ConstantNode.forConstant(constant, tool.runtime(), graph()); + } + } + return this; + } + + private static Stamp createStamp(ValueNode array, Kind kind) { + ResolvedJavaType type = ObjectStamp.typeOrNull(array); + if (kind == Kind.Object && type != null) { + return StampFactory.declared(type.getComponentType()); + } else { + return StampFactory.forKind(kind); + } + } + + @Override + public boolean inferStamp() { + return updateStamp(createStamp(array(), elementKind())); + } + + @Override + public void lower(LoweringTool tool) { + LoadIndexedNode loadIndexedNode = graph().add(new LoadIndexedNode(array(), index(), elementKind())); + graph().replaceFixedWithFixed(this, loadIndexedNode); + loadIndexedNode.lower(tool); + } +} diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -77,7 +77,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { IntegerExactArithmeticSplitNode.lower(tool, this); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -26,7 +26,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; -interface IntegerExactArithmeticNode extends Lowerable, Node.IterableNodeType { +interface IntegerExactArithmeticNode extends Lowerable, IterableNodeType { IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -29,7 +29,6 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.spi.Lowerable.*; import com.oracle.graal.nodes.type.*; public abstract class IntegerExactArithmeticSplitNode extends ControlSplitNode implements LIRGenLowerable { @@ -82,7 +81,7 @@ protected abstract Value generateArithmetic(LIRGeneratorTool generator); static void lower(LoweringTool tool, IntegerExactArithmeticNode node) { - if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) { + if (node.asNode().graph().getGuardsPhase() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { FloatingNode floatingNode = (FloatingNode) node; FixedWithNextNode previous = tool.lastFixedNode(); FixedNode next = previous.next(); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -73,7 +73,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { IntegerExactArithmeticSplitNode.lower(tool, this); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -77,7 +77,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { IntegerExactArithmeticSplitNode.lower(tool, this); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverInlineMacroNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverInlineMacroNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverInlineMacroNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -26,14 +26,14 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; -public class NeverInlineMacroNode extends MacroNode implements com.oracle.graal.graph.Node.IterableNodeType { +public class NeverInlineMacroNode extends MacroNode implements com.oracle.graal.graph.IterableNodeType { public NeverInlineMacroNode(Invoke invoke) { super(invoke); } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { InvokeNode invoke = createInvoke(); graph().replaceFixedWithFixed(this, invoke); invoke.setUseForInlining(false); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverPartOfCompilationNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverPartOfCompilationNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverPartOfCompilationNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -25,7 +25,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.replacements.nodes.*; -public class NeverPartOfCompilationNode extends MacroNode implements com.oracle.graal.graph.Node.IterableNodeType { +public class NeverPartOfCompilationNode extends MacroNode implements com.oracle.graal.graph.IterableNodeType { private final String message; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameGetNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameGetNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameGetNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -25,7 +25,6 @@ import sun.misc.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.Node.IterableNodeType; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; @@ -71,7 +70,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { assert !(getFrame() instanceof NewFrameNode); StructuredGraph structuredGraph = graph(); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameSetNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameSetNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameSetNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -23,7 +23,6 @@ package com.oracle.graal.truffle.nodes.frame; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.Node.IterableNodeType; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; @@ -71,7 +70,7 @@ } @Override - public void lower(LoweringTool tool, LoweringType loweringType) { + public void lower(LoweringTool tool) { assert !(getFrame() instanceof NewFrameNode); StructuredGraph structuredGraph = graph(); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/MaterializeFrameNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/MaterializeFrameNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/MaterializeFrameNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.truffle.nodes.frame; -import com.oracle.graal.graph.Node.IterableNodeType; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.truffle.*; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -27,7 +27,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.graph.*; -import com.oracle.graal.graph.Node.IterableNodeType; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomTypeCheckNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomTypeCheckNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomTypeCheckNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -26,7 +26,7 @@ import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; -public final class CustomTypeCheckNode extends LogicNode implements Lowerable, Virtualizable, com.oracle.graal.graph.Node.IterableNodeType { +public final class CustomTypeCheckNode extends LogicNode implements Lowerable, Virtualizable, com.oracle.graal.graph.IterableNodeType { @Input private ValueNode condition; @Input private ValueNode object; @@ -50,8 +50,8 @@ return customType; } - public void lower(LoweringTool tool, LoweringType loweringType) { - if (loweringType == LoweringType.BEFORE_GUARDS) { + public void lower(LoweringTool tool) { + if (graph().getGuardsPhase() == StructuredGraph.GuardsStage.FLOATING_GUARDS) { this.replaceAtUsages(graph().unique(new IntegerEqualsNode(condition, ConstantNode.forInt(1, graph())))); this.safeDelete(); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/TypeCastNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/TypeCastNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/TypeCastNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -28,7 +28,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -public final class TypeCastNode extends FixedWithNextNode implements Lowerable, com.oracle.graal.graph.Node.IterableNodeType, ValueProxy, Virtualizable { +public final class TypeCastNode extends FixedWithNextNode implements Lowerable, com.oracle.graal.graph.IterableNodeType, ValueProxy, Virtualizable { @Input private ValueNode receiver; @Input private ValueNode object; @@ -59,8 +59,8 @@ return customType; } - public void lower(LoweringTool tool, LoweringType loweringType) { - if (loweringType == LoweringType.BEFORE_GUARDS) { + public void lower(LoweringTool tool) { + if (graph().getGuardsPhase() == StructuredGraph.GuardsStage.FLOATING_GUARDS) { ValueAnchorNode valueAnchorNode = graph().add(new ValueAnchorNode()); UnsafeCastNode unsafeCast = graph().unique(new UnsafeCastNode(object, this.stamp(), (GuardingNode) valueAnchorNode)); this.replaceAtUsages(unsafeCast); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeCustomizationNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeCustomizationNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeCustomizationNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -27,7 +27,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -public final class UnsafeCustomizationNode extends FloatingNode implements LIRLowerable, com.oracle.graal.graph.Node.IterableNodeType { +public final class UnsafeCustomizationNode extends FloatingNode implements LIRLowerable, com.oracle.graal.graph.IterableNodeType { @Input private ValueNode receiver; private final Object customType; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/InlineTrivialGettersPhase.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/InlineTrivialGettersPhase.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/InlineTrivialGettersPhase.java Fri Sep 13 23:12:10 2013 +0200 @@ -22,9 +22,6 @@ */ package com.oracle.graal.truffle.phases; -import static com.oracle.graal.phases.GraalOptions.*; - -import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; import com.oracle.graal.java.*; @@ -33,27 +30,25 @@ import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; -import com.oracle.graal.phases.common.CanonicalizerPhase.CustomCanonicalizer; +import com.oracle.graal.phases.tiers.*; import com.oracle.graal.truffle.*; /** * Inline all trivial getters (i.e. simple field loads). */ -public class InlineTrivialGettersPhase extends Phase { +public class InlineTrivialGettersPhase extends BasePhase { private static final int TRIVIAL_GETTER_SIZE = 5; private final MetaAccessProvider metaAccessProvider; - private final Assumptions assumptions; - private final CustomCanonicalizer customCanonicalizer; + private final CanonicalizerPhase canonicalizer; - public InlineTrivialGettersPhase(MetaAccessProvider metaAccessProvider, Assumptions assumptions, CustomCanonicalizer customCanonicalizer) { + public InlineTrivialGettersPhase(MetaAccessProvider metaAccessProvider, CanonicalizerPhase canonicalizer) { this.metaAccessProvider = metaAccessProvider; - this.assumptions = assumptions; - this.customCanonicalizer = customCanonicalizer; + this.canonicalizer = canonicalizer; } @Override - protected void run(StructuredGraph graph) { + protected void run(StructuredGraph graph, PhaseContext context) { for (MethodCallTargetNode methodCallTarget : graph.getNodes(MethodCallTargetNode.class)) { if (methodCallTarget.isAlive()) { InvokeKind invokeKind = methodCallTarget.invokeKind(); @@ -66,7 +61,7 @@ int mark = graph.getMark(); InliningUtil.inline(methodCallTarget.invoke(), inlineGraph, false); Debug.dump(graph, "After inlining trivial getter %s", targetMethod.toString()); - new CanonicalizerPhase.Instance(metaAccessProvider, assumptions, !AOTCompilation.getValue(), mark, customCanonicalizer).apply(graph); + canonicalizer.applyIncremental(graph, context, mark); } } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/ReplaceLoadFinalPhase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/ReplaceLoadFinalPhase.java Fri Sep 13 23:12:10 2013 +0200 @@ -0,0 +1,53 @@ +/* + * 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.truffle.phases; + +import java.lang.reflect.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.phases.*; +import com.oracle.graal.truffle.nodes.*; +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.nodes.Node.Children; + +public class ReplaceLoadFinalPhase extends Phase { + + @Override + protected void run(StructuredGraph graph) { + for (LoadIndexedNode loadIndexedNode : graph.getNodes(LoadIndexedNode.class)) { + if (loadIndexedNode.array() instanceof LoadFieldNode) { + LoadFieldNode loadFieldNode = (LoadFieldNode) loadIndexedNode.array(); + if (!loadFieldNode.isStatic() && isCompilationFinal(loadFieldNode.field())) { + graph.replaceFixedWithFixed(loadIndexedNode, graph.add(new LoadIndexedFinalNode(loadIndexedNode.array(), loadIndexedNode.index(), loadIndexedNode.elementKind()))); + } + } + } + } + + private static boolean isCompilationFinal(ResolvedJavaField field) { + assert (field.getAnnotation(Children.class) == null && field.getAnnotation(CompilerDirectives.CompilationFinal.class) == null) || Modifier.isFinal(field.getModifiers()) : "field needs to be declared as final"; + return Modifier.isFinal(field.getModifiers()) && (field.getAnnotation(Children.class) != null || field.getAnnotation(CompilerDirectives.CompilationFinal.class) != null); + } +} diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/VerifyNoIntrinsicsLeftPhase.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/VerifyNoIntrinsicsLeftPhase.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/VerifyNoIntrinsicsLeftPhase.java Fri Sep 13 23:12:10 2013 +0200 @@ -23,7 +23,6 @@ package com.oracle.graal.truffle.phases; import com.oracle.graal.graph.*; -import com.oracle.graal.graph.Node.IterableNodeType; import com.oracle.graal.nodes.*; import com.oracle.graal.phases.*; import com.oracle.graal.truffle.*; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/MaterializedObjectState.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/MaterializedObjectState.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/MaterializedObjectState.java Fri Sep 13 23:12:10 2013 +0200 @@ -29,7 +29,7 @@ /** * This class encapsulated the materialized state of an escape analyzed object. */ -public final class MaterializedObjectState extends EscapeObjectState implements Node.IterableNodeType, Node.ValueNumberable { +public final class MaterializedObjectState extends EscapeObjectState implements IterableNodeType, Node.ValueNumberable { @Input private ValueNode materializedValue; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/VirtualObjectState.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/VirtualObjectState.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/VirtualObjectState.java Fri Sep 13 23:12:10 2013 +0200 @@ -31,7 +31,7 @@ /** * This class encapsulated the virtual state of an escape analyzed object. */ -public final class VirtualObjectState extends EscapeObjectState implements Node.IterableNodeType, Node.ValueNumberable { +public final class VirtualObjectState extends EscapeObjectState implements IterableNodeType, Node.ValueNumberable { @Input private final NodeInputList fieldValues; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EarlyReadEliminationPhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EarlyReadEliminationPhase.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EarlyReadEliminationPhase.java Fri Sep 13 23:12:10 2013 +0200 @@ -25,13 +25,14 @@ import static com.oracle.graal.phases.GraalOptions.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.schedule.*; import com.oracle.graal.phases.tiers.*; public class EarlyReadEliminationPhase extends EffectsPhase { - public EarlyReadEliminationPhase() { - super(1); + public EarlyReadEliminationPhase(CanonicalizerPhase canonicalizer) { + super(1, canonicalizer); } @Override diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java Fri Sep 13 23:12:10 2013 +0200 @@ -22,8 +22,6 @@ */ package com.oracle.graal.virtual.phases.ea; -import static com.oracle.graal.phases.GraalOptions.*; - import java.util.concurrent.*; import com.oracle.graal.debug.*; @@ -47,9 +45,11 @@ } private final int maxIterations; + private final CanonicalizerPhase canonicalizer; - public EffectsPhase(int maxIterations) { + public EffectsPhase(int maxIterations, CanonicalizerPhase canonicalizer) { this.maxIterations = maxIterations; + this.canonicalizer = canonicalizer; } @Override @@ -90,7 +90,7 @@ listener.getChangedNodes().add(node); } } - new CanonicalizerPhase.Instance(context.getRuntime(), context.getAssumptions(), !AOTCompilation.getValue(), listener.getChangedNodes(), null).apply(graph); + canonicalizer.applyIncremental(graph, context, listener.getChangedNodes()); return true; } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java Fri Sep 13 23:12:10 2013 +0200 @@ -60,13 +60,13 @@ @Override public Boolean call() { boolean progress = false; - PartialEscapePhase ea = new PartialEscapePhase(false); + PartialEscapePhase ea = new PartialEscapePhase(false, canonicalizer); boolean eaResult = ea.runAnalysis(graph, context); progress |= eaResult; Map hints = PEAInliningHints.getValue() ? PartialEscapePhase.getHints(graph) : null; - InliningPhase inlining = new InliningPhase(hints); + InliningPhase inlining = new InliningPhase(hints, new CanonicalizerPhase(true)); inlining.setMaxMethodsPerInlining(simple ? 1 : Integer.MAX_VALUE); inlining.apply(graph, context); progress |= inlining.getInliningCount() > 0; @@ -75,7 +75,7 @@ if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) { canonicalizer.apply(graph, context); - new IterativeConditionalEliminationPhase().apply(graph, context); + new IterativeConditionalEliminationPhase(canonicalizer).apply(graph, context); } return progress; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java Fri Sep 13 23:12:10 2013 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.virtual.phases.ea; import static com.oracle.graal.phases.GraalOptions.*; +import static com.oracle.graal.virtual.phases.ea.PartialEscapePhase.Options.*; import java.util.*; @@ -33,25 +34,29 @@ import com.oracle.graal.nodes.util.*; import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.options.*; +import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.graph.*; import com.oracle.graal.phases.schedule.*; import com.oracle.graal.phases.tiers.*; public class PartialEscapePhase extends EffectsPhase { - //@formatter:off - @Option(help = "") - public static final OptionValue OptEarlyReadElimination = new OptionValue<>(true); - //@formatter:on + static class Options { + + //@formatter:off + @Option(help = "") + public static final OptionValue OptEarlyReadElimination = new OptionValue<>(true); + //@formatter:on + } private final boolean readElimination; - public PartialEscapePhase(boolean iterative) { - this(iterative, OptEarlyReadElimination.getValue()); + public PartialEscapePhase(boolean iterative, CanonicalizerPhase canonicalizer) { + this(iterative, OptEarlyReadElimination.getValue(), canonicalizer); } - public PartialEscapePhase(boolean iterative, boolean readElimination) { - super(iterative ? EscapeAnalysisIterations.getValue() : 1); + public PartialEscapePhase(boolean iterative, boolean readElimination, CanonicalizerPhase canonicalizer) { + super(iterative ? EscapeAnalysisIterations.getValue() : 1, canonicalizer); this.readElimination = readElimination; } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ImplicitCastTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ImplicitCastTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2012, 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.truffle.api.dsl.test; + +import org.junit.*; + +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.dsl.test.ImplicitCastTestFactory.ImplicitCast0NodeFactory; +import com.oracle.truffle.api.dsl.test.NodeContainerTest.Str; +import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; +import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; +import com.oracle.truffle.api.frame.*; + +public class ImplicitCastTest { + + @TypeSystem({int.class, boolean.class, String.class, Str.class}) + static class ImplicitCast0Types { + + @ImplicitCast + boolean castInt(int intvalue) { + return intvalue == 1 ? true : false; + } + + @ImplicitCast + boolean castString(String strvalue) { + return strvalue.equals("1"); + } + + } + + @TypeSystemReference(ImplicitCast0Types.class) + @NodeChild(value = "operand", type = ImplicitCast0Node.class) + abstract static class ImplicitCast0Node extends ValueNode { + + public abstract Object executeEvaluated(VirtualFrame frame, Object value2); + + @Specialization(order = 1) + public String op1(String value) throws RuntimeException { + return value; + } + + @Specialization(order = 2) + public boolean op1(boolean value) throws RuntimeException { + return value; + } + + } + + @Test + public void testImplicitCast0() { + ImplicitCast0Node node = ImplicitCast0NodeFactory.create(null); + TestRootNode root = new TestRootNode<>(node); + Assert.assertEquals("2", root.getNode().executeEvaluated(null, "2")); + Assert.assertEquals(true, root.getNode().executeEvaluated(null, 1)); + Assert.assertEquals("1", root.getNode().executeEvaluated(null, "1")); + Assert.assertEquals(true, root.getNode().executeEvaluated(null, 1)); + Assert.assertEquals(true, root.getNode().executeEvaluated(null, true)); + } + + // TODO assert implicit casts only in one direction + + // test example that covers the most cases + +} diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -37,6 +37,17 @@ public class PolymorphicTest { + private static void assertParent(Node expectedParent, Node child) { + Node parent = child.getParent(); + while (parent != null && parent != expectedParent) { + parent = parent.getParent(); + } + + if (parent != expectedParent) { + assertEquals(expectedParent, parent); + } + } + @Test public void testJustSpecialize() { TestRootNode node = TestHelper.createRoot(Node1Factory.getInstance()); @@ -45,8 +56,8 @@ assertEquals("(int,boolean)", executeWith(node, 42, false)); assertEquals("(boolean,int)", executeWith(node, false, 42)); assertEquals(Kind.SPECIALIZED, node.getNode().getClass().getAnnotation(NodeInfo.class).kind()); - assertEquals(node.getNode(), node.getNode().getLeft().getParent()); - assertEquals(node.getNode(), node.getNode().getRight().getParent()); + assertParent(node.getNode(), node.getNode().getLeft()); + assertParent(node.getNode(), node.getNode().getRight()); } @Test @@ -55,8 +66,8 @@ assertEquals("(int,boolean)", executeWith(node, 42, false)); assertEquals("(int,int)", executeWith(node, 42, 42)); assertEquals(Kind.POLYMORPHIC, node.getNode().getClass().getAnnotation(NodeInfo.class).kind()); - assertEquals(node.getNode(), node.getNode().getLeft().getParent()); - assertEquals(node.getNode(), node.getNode().getRight().getParent()); + assertParent(node.getNode(), node.getNode().getLeft()); + assertParent(node.getNode(), node.getNode().getRight()); } @Test @@ -66,8 +77,8 @@ assertEquals("(boolean,boolean)", executeWith(node, true, false)); assertEquals("(int,int)", executeWith(node, 42, 42)); assertEquals(Kind.POLYMORPHIC, node.getNode().getClass().getAnnotation(NodeInfo.class).kind()); - assertEquals(node.getNode(), node.getNode().getLeft().getParent()); - assertEquals(node.getNode(), node.getNode().getRight().getParent()); + assertParent(node.getNode(), node.getNode().getLeft()); + assertParent(node.getNode(), node.getNode().getRight()); } @Test @@ -78,17 +89,17 @@ assertEquals("(boolean,boolean)", executeWith(node, true, false)); assertEquals("(int,int)", executeWith(node, 42, 42)); assertEquals(Kind.GENERIC, node.getNode().getClass().getAnnotation(NodeInfo.class).kind()); - assertEquals(node.getNode(), node.getNode().getLeft().getParent()); - assertEquals(node.getNode(), node.getNode().getRight().getParent()); + assertParent(node.getNode(), node.getNode().getLeft()); + assertParent(node.getNode(), node.getNode().getRight()); } @Test public void testGenericInitial() { TestRootNode node = TestHelper.createRoot(Node1Factory.getInstance()); - assertEquals("(generic,generic)", executeWith(node, "", "")); + assertEquals("(generic,generic)", executeWith(node, "1", "1")); assertEquals(Kind.GENERIC, node.getNode().getClass().getAnnotation(NodeInfo.class).kind()); - assertEquals(node.getNode(), node.getNode().getLeft().getParent()); - assertEquals(node.getNode(), node.getNode().getRight().getParent()); + assertParent(node.getNode(), node.getNode().getLeft()); + assertParent(node.getNode(), node.getNode().getRight()); } @Test @@ -99,8 +110,8 @@ assertEquals("(generic,generic)", executeWith(node, "", "")); assertEquals(Kind.GENERIC, node.getNode().getClass().getAnnotation(NodeInfo.class).kind()); /* Assertions for bug GRAAL-425 */ - assertEquals(node.getNode(), node.getNode().getLeft().getParent()); - assertEquals(node.getNode(), node.getNode().getRight().getParent()); + assertParent(node.getNode(), node.getNode().getLeft()); + assertParent(node.getNode(), node.getNode().getRight()); } @SuppressWarnings("unused") diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TypeSystemTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TypeSystemTest.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TypeSystemTest.java Fri Sep 13 23:12:10 2013 +0200 @@ -48,6 +48,11 @@ return (int) value; } + @ImplicitCast + Str castStr(String strvalue) { + return new Str(strvalue); + } + } @TypeSystemReference(SimpleTypes.class) diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.truffle.api/src/com/oracle/truffle/api/SourceSection.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/SourceSection.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/SourceSection.java Fri Sep 13 23:12:10 2013 +0200 @@ -25,75 +25,30 @@ package com.oracle.truffle.api; /** - * Represents a contiguous text section within the source code of a guest language program. + * Description of contiguous text section within the source code of a guest language program. */ -public class SourceSection { - - private final Source source; - private final String identifier; - private final int startLine; - private final int startColumn; - private final int charIndex; - private final int charLength; - - /** - * Creates a new object representing a contiguous text section within the source code of a guest - * language program. - *

- * The starting location of the section is specified using two different coordinate: - *

    - *
  • (row, column): rows and columns are 1-based, so the first character in a source - * file is at position {@code (1,1)}.
  • - *
  • character index: 0-based offset of the character from the beginning of the source, - * so the first character in a file is at index {@code 0}.
  • - *
- * The newline that terminates each line counts as a single character for the purpose of - * a character index. The (row,column) coordinates of a newline character should never appear in - * a text section. - *

- * - * @param source object representing the complete source program that contains this section - * @param identifier an identifier used when printing the section - * @param startLine the 1-based number of the start line of the section - * @param startColumn the 1-based number of the start column of the section - * @param charIndex the 0-based index of the first character of the section - * @param charLength the length of the section in number of characters - */ - public SourceSection(Source source, String identifier, int startLine, int startColumn, int charIndex, int charLength) { - this.source = source; - this.identifier = identifier; - this.startLine = startLine; - this.startColumn = startColumn; - this.charIndex = charIndex; - this.charLength = charLength; - } +public interface SourceSection { /** * Returns the object representing the source program that contains this section. * * @return the source object */ - public final Source getSource() { - return source; - } + Source getSource(); /** * Returns 1-based line number of the first character in this source section (inclusive). * * @return the starting line number */ - public final int getStartLine() { - return startLine; - } + int getStartLine(); /** * Returns the 1-based column number of the first character in this source section (inclusive). * * @return the starting column number */ - public final int getStartColumn() { - return startColumn; - } + int getStartColumn(); /** * Returns the 0-based index of the first character in this source section. @@ -103,9 +58,7 @@ * * @return the starting character index */ - public final int getCharIndex() { - return charIndex; - } + int getCharIndex(); /** * Returns the length of this source section in characters. @@ -115,85 +68,28 @@ * * @return the number of characters in the section */ - public final int getCharLength() { - return charLength; - } + int getCharLength(); + + /** + * Returns the index of the text position immediately following the last character in the + * section. + * + * @return the end position of the section + */ + int getCharEndIndex(); /** * Returns the identifier of this source section that is used for printing the section. * * @return the identifier of the section */ - public final String getIdentifier() { - return identifier; - } + String getIdentifier(); /** * Returns text of the code represented by this source section. * * @return the code as a String object */ - public final String getCode() { - return getSource().getCode().substring(charIndex, charIndex + charLength); - } - - @Override - public String toString() { - return String.format("%s:%d", source.getName(), startLine); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + charIndex; - result = prime * result + charLength; - result = prime * result + ((identifier == null) ? 0 : identifier.hashCode()); - result = prime * result + ((source == null) ? 0 : source.hashCode()); - result = prime * result + startColumn; - result = prime * result + startLine; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof SourceSection)) { - return false; - } - SourceSection other = (SourceSection) obj; - if (charIndex != other.charIndex) { - return false; - } - if (charLength != other.charLength) { - return false; - } - if (identifier == null) { - if (other.identifier != null) { - return false; - } - } else if (!identifier.equals(other.identifier)) { - return false; - } - if (source == null) { - if (other.source != null) { - return false; - } - } else if (!source.equals(other.source)) { - return false; - } - if (startColumn != other.startColumn) { - return false; - } - if (startLine != other.startLine) { - return false; - } - return true; - } + String getCode(); } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultSourceSection.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultSourceSection.java Fri Sep 13 23:12:10 2013 +0200 @@ -0,0 +1,164 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.impl; + +import com.oracle.truffle.api.*; + +/** + * Represents a contiguous text section within the source code of a guest language program. + */ +public class DefaultSourceSection implements SourceSection { + + private final Source source; + private final String identifier; + private final int startLine; + private final int startColumn; + private final int charIndex; + private final int charLength; + + /** + * Creates a new object representing a contiguous text section within the source code of a guest + * language program's text. + *

+ * The starting location of the section is specified using two different coordinate: + *

    + *
  • (row, column): rows and columns are 1-based, so the first character in a source + * file is at position {@code (1,1)}.
  • + *
  • character index: 0-based offset of the character from the beginning of the source, + * so the first character in a file is at index {@code 0}.
  • + *
+ * The newline that terminates each line counts as a single character for the purpose of + * a character index. The (row,column) coordinates of a newline character should never appear in + * a text section. + *

+ * + * @param source object representing the complete source program that contains this section + * @param identifier an identifier used when printing the section + * @param startLine the 1-based number of the start line of the section + * @param startColumn the 1-based number of the start column of the section + * @param charIndex the 0-based index of the first character of the section + * @param charLength the length of the section in number of characters + */ + public DefaultSourceSection(Source source, String identifier, int startLine, int startColumn, int charIndex, int charLength) { + this.source = source; + this.identifier = identifier; + this.startLine = startLine; + this.startColumn = startColumn; + this.charIndex = charIndex; + this.charLength = charLength; + } + + public final Source getSource() { + return source; + } + + public final int getStartLine() { + return startLine; + } + + public final int getStartColumn() { + return startColumn; + } + + public final int getCharIndex() { + return charIndex; + } + + public final int getCharLength() { + return charLength; + } + + public final int getCharEndIndex() { + return charIndex + charLength; + } + + public final String getIdentifier() { + return identifier; + } + + public final String getCode() { + return getSource().getCode().substring(charIndex, charIndex + charLength); + } + + @Override + public String toString() { + return String.format("%s:%d", source.getName(), startLine); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + charIndex; + result = prime * result + charLength; + result = prime * result + ((identifier == null) ? 0 : identifier.hashCode()); + result = prime * result + ((source == null) ? 0 : source.hashCode()); + result = prime * result + startColumn; + result = prime * result + startLine; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof DefaultSourceSection)) { + return false; + } + DefaultSourceSection other = (DefaultSourceSection) obj; + if (charIndex != other.charIndex) { + return false; + } + if (charLength != other.charLength) { + return false; + } + if (identifier == null) { + if (other.identifier != null) { + return false; + } + } else if (!identifier.equals(other.identifier)) { + return false; + } + if (source == null) { + if (other.source != null) { + return false; + } + } else if (!source.equals(other.source)) { + return false; + } + if (startColumn != other.startColumn) { + return false; + } + if (startLine != other.startLine) { + return false; + } + return true; + } + +} diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java Fri Sep 13 23:12:10 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -59,6 +59,11 @@ CompilerAsserts.neverPartOfCompilation(); } + protected Node(SourceSection sourceSection) { + CompilerAsserts.neverPartOfCompilation(); + this.sourceSection = sourceSection; + } + /** * Assigns a link to a guest language source section to this node. * @@ -66,7 +71,12 @@ */ public final void assignSourceSection(SourceSection section) { if (sourceSection != null) { - throw new IllegalStateException("Source section is already assigned."); + // Patch this test during the transition to constructor-based + // source attribution, which would otherwise trigger this + // exception. This method will eventually be deprecated. + if (getSourceSection() != section) { + throw new IllegalStateException("Source section is already assigned."); + } } this.sourceSection = section; } diff -r 2bd626188d31 -r e9fc19eb3efb 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 Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Fri Sep 13 23:12:10 2013 +0200 @@ -423,6 +423,24 @@ return result; } + /** + * Get the nth parent of a node, where the 0th parent is the node itself. Returns null if there + * are less than n ancestors. + */ + public static Node getNthParent(Node node, int n) { + Node parent = node; + + for (int i = 0; i < n; i++) { + parent = parent.getParent(); + + if (parent == null) { + return null; + } + } + + return parent; + } + /** find annotation in class/interface hierarchy. */ public static T findAnnotation(Class clazz, Class annotationClass) { if (clazz.getAnnotation(annotationClass) != null) { diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java Fri Sep 13 23:12:10 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -34,6 +34,13 @@ */ public abstract class RootNode extends Node { + protected RootNode() { + } + + protected RootNode(SourceSection sourceSection) { + super(sourceSection); + } + /** * Executes this function using the specified frame and returns the result value. * diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/Utils.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/Utils.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/Utils.java Fri Sep 13 23:12:10 2013 +0200 @@ -192,6 +192,10 @@ return true; } + if (isObject(to)) { + return true; + } + // JLS 5.1.2 widening primitives if (Utils.isPrimitive(from) && Utils.isPrimitive(to)) { TypeKind fromKind = from.getKind(); @@ -257,6 +261,10 @@ return isAssignable(context, ((ArrayType) from).getComponentType(), ((ArrayType) to).getComponentType()); } + if (from instanceof ArrayType || to instanceof ArrayType) { + return false; + } + TypeElement fromType = Utils.fromTypeMirror(from); TypeElement toType = Utils.fromTypeMirror(to); if (fromType == null || toType == null) { diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTreeBuilder.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTreeBuilder.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTreeBuilder.java Fri Sep 13 23:12:10 2013 +0200 @@ -165,14 +165,18 @@ } public CodeTreeBuilder startCall(String callSite) { - return startCall(null, callSite); + return startCall((CodeTree) null, callSite); } public CodeTreeBuilder startCall(String receiver, String callSite) { + return startCall(singleString(receiver), callSite); + } + + public CodeTreeBuilder startCall(CodeTree receiver, String callSite) { if (receiver == null) { return startGroup().string(callSite).startParanthesesCommaGroup().endAfter(); } else { - return startGroup().string(receiver).string(".").string(callSite).startParanthesesCommaGroup().endAfter(); + return startGroup().tree(receiver).string(".").string(callSite).startParanthesesCommaGroup().endAfter(); } } @@ -336,6 +340,10 @@ return startGroup().string("if ").startParanthesesCommaGroup().endAndWhitespaceAfter().startGroup().endAfter(); } + public CodeTreeBuilder startFor() { + return startGroup().string("for ").startParantheses().endAndWhitespaceAfter().startGroup().endAfter(); + } + public boolean startIf(boolean elseIf) { if (elseIf) { startElseIf(); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeChildData.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeChildData.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeChildData.java Fri Sep 13 23:12:10 2013 +0200 @@ -49,6 +49,7 @@ DEFAULT, SHORT_CIRCUIT } + private final NodeData parent; private final Element sourceElement; private final AnnotationMirror sourceAnnotationMirror; @@ -64,8 +65,9 @@ private NodeData nodeData; - public NodeChildData(Element sourceElement, AnnotationMirror sourceMirror, String name, TypeMirror nodeType, TypeMirror originalNodeType, Element accessElement, Cardinality cardinality, - ExecutionKind executionKind) { + public NodeChildData(NodeData parent, Element sourceElement, AnnotationMirror sourceMirror, String name, TypeMirror nodeType, TypeMirror originalNodeType, Element accessElement, + Cardinality cardinality, ExecutionKind executionKind) { + this.parent = parent; this.sourceElement = sourceElement; this.sourceAnnotationMirror = sourceMirror; this.name = name; @@ -84,6 +86,31 @@ this.executeWith = executeWith; } + public boolean needsImplicitCast(ProcessorContext context) { + if (!parent.needsRewrites(context)) { + return false; + } + + boolean used = false; + SpecializationData generic = parent.getGenericSpecialization(); + for (ActualParameter param : generic.getParameters()) { + if (!param.getSpecification().isSignature()) { + continue; + } + NodeChildData child = parent.findChild(param.getSpecification().getName()); + if (child == this) { + used = true; + break; + } + } + + if (!used) { + return false; + } + + return getNodeData().getTypeSystem().getImplicitCasts() != null && !getNodeData().getTypeSystem().getImplicitCasts().isEmpty(); + } + public ExecutableTypeData findExecutableType(ProcessorContext context, TypeData targetType) { ExecutableTypeData executableType = nodeData.findExecutableType(targetType, getExecuteWith().size()); if (executableType == null) { diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Fri Sep 13 23:12:10 2013 +0200 @@ -62,12 +62,17 @@ return node.getNodeId() + "Factory"; } + private static String nodeCastClassName(NodeData node, TypeData type) { + String nodeid = resolveNodeId(node); + if (type == null) { + return nodeid + "ImplicitCast"; + } else { + return Utils.firstLetterUpperCase(Utils.getSimpleName(type.getPrimitiveType())) + "Cast"; + } + } + private static String nodeSpecializationClassName(SpecializationData specialization) { - String nodeid = specialization.getNode().getNodeId(); - if (nodeid.endsWith("Node") && !nodeid.equals("Node")) { - nodeid = nodeid.substring(0, nodeid.length() - 4); - } - + String nodeid = resolveNodeId(specialization.getNode()); String name = Utils.firstLetterUpperCase(nodeid); name += Utils.firstLetterUpperCase(specialization.getId()); name += "Node"; @@ -75,10 +80,7 @@ } private static String nodePolymorphicClassName(NodeData node, SpecializationData specialization) { - String nodeid = node.getNodeId(); - if (nodeid.endsWith("Node") && !nodeid.equals("Node")) { - nodeid = nodeid.substring(0, nodeid.length() - 4); - } + String nodeid = resolveNodeId(node); String name = Utils.firstLetterUpperCase(nodeid); if (specialization == node.getGenericPolymorphicSpecialization()) { @@ -89,10 +91,22 @@ return name; } + private static String resolveNodeId(NodeData node) { + String nodeid = node.getNodeId(); + if (nodeid.endsWith("Node") && !nodeid.equals("Node")) { + nodeid = nodeid.substring(0, nodeid.length() - 4); + } + return nodeid; + } + private static String valueNameEvaluated(ActualParameter targetParameter) { return valueName(targetParameter) + "Evaluated"; } + private static String typeName(ActualParameter param) { + return param.getLocalName() + "Type"; + } + private static String valueName(ActualParameter param) { return param.getLocalName(); } @@ -147,7 +161,8 @@ } } - private void addInternalValueParameterNames(CodeTreeBuilder builder, TemplateMethod source, TemplateMethod specialization, String unexpectedValueName, boolean forceFrame, boolean includeImplicit) { + private void addInternalValueParameterNames(CodeTreeBuilder builder, TemplateMethod source, TemplateMethod specialization, String unexpectedValueName, boolean forceFrame, boolean includeImplicit, + Map customNames) { if (forceFrame && specialization.getSpecification().findParameterSpec("frame") != null) { builder.string("frameValue"); } @@ -166,7 +181,9 @@ ActualParameter sourceParameter = source.findParameter(parameter.getLocalName()); - if (unexpectedValueName != null && parameter.getLocalName().equals(unexpectedValueName)) { + if (customNames != null && customNames.containsKey(parameter.getLocalName())) { + builder.string(customNames.get(parameter.getLocalName())); + } else if (unexpectedValueName != null && parameter.getLocalName().equals(unexpectedValueName)) { builder.cast(parameter.getType(), CodeTreeBuilder.singleString("ex.getResult()")); } else if (sourceParameter != null) { builder.string(valueName(sourceParameter, parameter)); @@ -298,10 +315,7 @@ } private static String baseClassName(NodeData node) { - String nodeid = node.getNodeId(); - if (nodeid.endsWith("Node") && !nodeid.equals("Node")) { - nodeid = nodeid.substring(0, nodeid.length() - 4); - } + String nodeid = resolveNodeId(node); String name = Utils.firstLetterUpperCase(nodeid); name += "BaseNode"; return name; @@ -362,7 +376,7 @@ builder.startThrow().startNew(getContext().getType(UnsupportedOperationException.class)); builder.startCall("createInfo0"); builder.doubleQuote("Unsupported values"); - addInternalValueParameterNames(builder, current, current, null, false, true); + addInternalValueParameterNames(builder, current, current, null, false, true, null); builder.end().end().end(); } @@ -422,7 +436,11 @@ } @Override + @SuppressWarnings("unchecked") protected void createChildren(NodeData node) { + List casts = new ArrayList<>(getElement().getEnclosedElements()); + getElement().getEnclosedElements().clear(); + Map> childTypes = new LinkedHashMap<>(); if (node.getDeclaredNodes() != null && !node.getDeclaredNodes().isEmpty()) { for (NodeData nodeChild : node.getDeclaredNodes()) { @@ -432,14 +450,35 @@ } if (node.needsFactory() || node.getNodeDeclaringChildren().size() > 0) { - add(new NodeFactoryFactory(context, childTypes), node); + NodeFactoryFactory factory = new NodeFactoryFactory(context, childTypes); + add(factory, node); + factory.getElement().getEnclosedElements().addAll(casts); + } + } + + protected CodeTree createCastType(NodeData node, TypeData sourceType, TypeData targetType, boolean expect, CodeTree value) { + if (targetType == null) { + return value; + } else if (sourceType != null && !sourceType.needsCastTo(getContext(), targetType)) { + return value; } + + CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); + String targetMethodName; + if (expect) { + targetMethodName = TypeSystemCodeGenerator.expectTypeMethodName(targetType); + } else { + targetMethodName = TypeSystemCodeGenerator.asTypeMethodName(targetType); + } + startCallTypeSystemMethod(getContext(), builder, node, targetMethodName); + builder.tree(value); + builder.end().end(); + return builder.getRoot(); } private class NodeFactoryFactory extends ClassElementFactory { private final Map> childTypes; - private CodeTypeElement generatedNode; public NodeFactoryFactory(ProcessorContext context, Map> childElements) { @@ -853,7 +892,8 @@ ExecutableElement getter = (ExecutableElement) child.getAccessElement(); CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), getter); method.getModifiers().remove(Modifier.ABSTRACT); - method.createBuilder().startReturn().string("this.").string(child.getName()).end(); + CodeTreeBuilder builder = method.createBuilder(); + builder.startReturn().string("this.").string(child.getName()).end(); clazz.add(method); } } @@ -1107,29 +1147,58 @@ builder.startStatement(); String fieldName = var.getSimpleName().toString(); - CodeTree fieldInit = CodeTreeBuilder.singleString(var.getSimpleName().toString()); - builder.string("this.").string(var.getSimpleName().toString()); - NodeChildData child = node.findChild(fieldName); - if (child != null) { - CreateCastData createCast = node.findCast(child.getName()); - if (createCast != null) { - fieldInit = createTemplateMethodCall(builder, null, node.getGenericSpecialization(), createCast, null, child.getName()); - } - } - - if (Utils.isAssignable(getContext(), var.asType(), getContext().getTruffleTypes().getNode())) { - builder.string(" = adoptChild(").tree(fieldInit).string(")"); - } else if (Utils.isAssignable(getContext(), var.asType(), getContext().getTruffleTypes().getNodeArray())) { - builder.string(" = adoptChildren(").tree(fieldInit).string(")"); - } else { - builder.string(" = ").tree(fieldInit); - } + + CodeTree init = createStaticCast(builder, child, fieldName); + init = createAdoptChild(builder, var.asType(), init); + + builder.string("this.").string(fieldName).string(" = ").tree(init); builder.end(); } return method; } + private CodeTree createStaticCast(CodeTreeBuilder parent, NodeChildData child, String fieldName) { + NodeData parentNode = getModel().getNode(); + if (child != null) { + CreateCastData createCast = parentNode.findCast(child.getName()); + if (createCast != null) { + return createTemplateMethodCall(parent, null, parentNode.getGenericSpecialization(), createCast, null, fieldName); + } + } + return CodeTreeBuilder.singleString(fieldName); + } + + private CodeTree createAdoptChild(CodeTreeBuilder parent, TypeMirror type, CodeTree value) { + CodeTreeBuilder builder = new CodeTreeBuilder(parent); + if (Utils.isAssignable(getContext(), type, getContext().getTruffleTypes().getNode())) { + builder.string("adoptChild(").tree(value).string(")"); + } else if (Utils.isAssignable(getContext(), type, getContext().getTruffleTypes().getNodeArray())) { + builder.string("adoptChildren(").tree(value).string(")"); + } else { + builder.tree(value); + } + return builder.getRoot(); + } + + private CodeTree createCopyArray(CodeTreeBuilder parent, NodeChildData child, TypeMirror arrayType, CodeBlock accessElement) { + CodeTreeBuilder builder = parent.create(); + NodeData node = getModel().getNode(); + builder.string("new ").type(arrayType).string(" {"); + builder.startCommaGroup(); + for (ActualParameter parameter : getModel().getParameters()) { + NodeChildData foundChild = node.findChild(parameter.getSpecification().getName()); + if (foundChild == child) { + builder.startGroup(); + builder.tree(accessElement.create(builder, String.valueOf(parameter.getIndex()))); + builder.end(); + } + } + builder.end(); + builder.end().string("}"); + return builder.getRoot(); + } + private CodeExecutableElement createCopyConstructor(CodeTypeElement type, ExecutableElement superConstructor) { CodeExecutableElement method = new CodeExecutableElement(null, type.getSimpleName().toString()); CodeTreeBuilder builder = method.createBuilder(); @@ -1141,34 +1210,22 @@ for (VariableElement var : type.getFields()) { builder.startStatement(); - String varName = var.getSimpleName().toString(); - builder.string("this.").string(varName); - if (Utils.isAssignable(getContext(), var.asType(), getContext().getTruffleTypes().getNode())) { - builder.string(" = adoptChild(copy.").string(varName).string(")"); - } else if (Utils.isAssignable(getContext(), var.asType(), getContext().getTruffleTypes().getNodeArray())) { - NodeData node = getModel().getNode(); - NodeChildData child = node.findChild(varName); - if (child != null) { - builder.string(" = adoptChildren("); - builder.string("new ").type((child.getNodeType())).string(" {"); - builder.startCommaGroup(); - for (ActualParameter parameter : getModel().getParameters()) { - NodeChildData foundChild = node.findChild(parameter.getSpecification().getName()); - if (foundChild == child) { - builder.startGroup(); - builder.string("copy.").string(varName).string("[").string(String.valueOf(parameter.getIndex())).string("]"); - builder.end(); - } + final String varName = var.getSimpleName().toString(); + final TypeMirror varType = var.asType(); + + final String copyAccess = "copy." + varName; + CodeTree init = CodeTreeBuilder.singleString(copyAccess); + if (Utils.isAssignable(getContext(), var.asType(), getContext().getTruffleTypes().getNodeArray())) { + NodeChildData child = getModel().getNode().findChild(varName); + init = createCopyArray(builder, child, varType, new CodeBlock() { + + public CodeTree create(CodeTreeBuilder parent, String index) { + return CodeTreeBuilder.singleString(copyAccess + "[" + index + "]"); } - - builder.end().string("})"); - } else { - builder.string(" = adoptChildren(copy.").string(varName).string(")"); - } - } else { - builder.string(" = copy.").string(varName); + }); } - builder.end(); + init = createAdoptChild(builder, varType, init); + builder.startStatement().string("this.").string(varName).string(" = ").tree(init).end(); } if (getModel().getNode().isPolymorphic()) { builder.statement("this.next0 = adoptChild(copy.next0)"); @@ -1184,7 +1241,8 @@ } private CodeVariableElement createChildField(NodeChildData child) { - CodeVariableElement var = new CodeVariableElement(child.getNodeType(), child.getName()); + TypeMirror type = child.getNodeType(); + CodeVariableElement var = new CodeVariableElement(type, child.getName()); var.getModifiers().add(Modifier.PROTECTED); DeclaredType annotationType; @@ -1223,7 +1281,7 @@ } builder.startStatement().string("String message = ").startCall("createInfo0").string("reason"); - addInternalValueParameterNames(builder, node.getGenericSpecialization(), node.getGenericSpecialization(), null, false, true); + addInternalValueParameterNames(builder, node.getGenericSpecialization(), node.getGenericSpecialization(), null, false, true, null); builder.end().end(); final String currentNodeVar = currentNode; @@ -1434,7 +1492,7 @@ guardsAnd = " && "; } - CodeTree cast = createCast(castBuilder, child, valueParam, typeGuard.getType()); + CodeTree cast = createCast(castBuilder, child, valueParam, typeGuard.getType(), checkMinimumState); if (cast != null) { castBuilder.tree(cast); } @@ -1526,7 +1584,15 @@ builder.string(" || "); } - startCallTypeSystemMethod(getContext(), builder, node, TypeSystemCodeGenerator.isTypeMethodName(targetType)); + String castMethodName; + List types = getModel().getNode().getTypeSystem().lookupSourceTypes(targetType); + if (types.size() > 1) { + castMethodName = TypeSystemCodeGenerator.isImplicitTypeMethodName(targetType); + } else { + castMethodName = TypeSystemCodeGenerator.isTypeMethodName(targetType); + } + + startCallTypeSystemMethod(getContext(), builder, node, castMethodName); builder.string(valueName(source)); builder.end().end(); // call @@ -1539,7 +1605,7 @@ return builder.getRoot(); } - private CodeTree createCast(CodeTreeBuilder parent, NodeChildData field, ActualParameter source, TypeData targetType) { + private CodeTree createCast(CodeTreeBuilder parent, NodeChildData field, ActualParameter source, TypeData targetType, boolean checkMinimumState) { NodeData node = field.getNodeData(); TypeData sourceType = source.getTypeSystemType(); @@ -1554,9 +1620,24 @@ condition = CodeTreeBuilder.singleString(valueName(shortCircuit)); } - CodeTree value = createCallTypeSystemMethod(context, parent, node, TypeSystemCodeGenerator.asTypeMethodName(targetType), CodeTreeBuilder.singleString(valueName(source))); - - return createLazyAssignment(parent, castValueName(source), targetType.getPrimitiveType(), condition, value); + String castMethodName; + List types = getModel().getNode().getTypeSystem().lookupSourceTypes(targetType); + if (types.size() > 1) { + castMethodName = TypeSystemCodeGenerator.asImplicitTypeMethodName(targetType); + } else { + castMethodName = TypeSystemCodeGenerator.asTypeMethodName(targetType); + } + + CodeTree value = createCallTypeSystemMethod(context, parent, node, castMethodName, CodeTreeBuilder.singleString(valueName(source))); + + CodeTreeBuilder builder = parent.create(); + builder.tree(createLazyAssignment(parent, castValueName(source), targetType.getPrimitiveType(), condition, value)); + if (checkMinimumState && types.size() > 1) { + CodeTree castType = createCallTypeSystemMethod(context, parent, node, TypeSystemCodeGenerator.getImplicitClass(targetType), CodeTreeBuilder.singleString(valueName(source))); + builder.tree(createLazyAssignment(builder, typeName(source), getContext().getType(Class.class), condition, castType)); + } + + return builder.getRoot(); } private CodeTree createMethodGuard(CodeTreeBuilder parent, String prefix, SpecializationData source, GuardData guard) { @@ -1595,7 +1676,6 @@ builder.tree(createRewriteGeneric(builder, source, current, currentNodeVar)); builder.end(); } else { - // simple rewrite if (current.getExceptions().isEmpty()) { builder.tree(createGenericInvoke(builder, source, current, createReplaceCall(builder, current, currentNodeVar, currentNodeVar, null), null)); } else { @@ -1669,7 +1749,7 @@ } if (current.isGeneric()) { builder.startReturn().tree(replace).string(".").startCall(EXECUTE_GENERIC_NAME); - addInternalValueParameterNames(builder, source, current, null, current.getNode().needsFrame(), true); + addInternalValueParameterNames(builder, source, current, null, current.getNode().needsFrame(), true, null); builder.end().end(); } else if (current.getMethod() == null) { if (replaceCall != null) { @@ -1696,7 +1776,19 @@ } else { replaceCall.startCall("replace"); } - replaceCall.startGroup().startNew(className).string(source).end().end(); + replaceCall.startGroup().startNew(className).string(source); + for (ActualParameter param : current.getParameters()) { + if (!param.getSpecification().isSignature()) { + continue; + } + NodeChildData child = getModel().getNode().findChild(param.getSpecification().getName()); + List types = child.getNodeData().getTypeSystem().lookupSourceTypes(param.getTypeSystemType()); + if (types.size() > 1) { + replaceCall.string(typeName(param)); + } + } + replaceCall.end().end(); + if (message == null) { replaceCall.string("message"); } else { @@ -1732,7 +1824,7 @@ builder.startReturn(); builder.startCall(currentNode + ".next0", executeCachedName(node.getGenericPolymorphicSpecialization())); - addInternalValueParameterNames(builder, node.getGenericSpecialization(), node.getGenericSpecialization(), null, true, true); + addInternalValueParameterNames(builder, node.getGenericSpecialization(), node.getGenericSpecialization(), null, true, true, null); builder.end(); builder.end(); @@ -1776,7 +1868,7 @@ executeParameterNames[i] = valueName(executeParameters.get(i)); } - builder.tree(createExecuteChildren(builder, executable, specialization, executeParameters, null, true)); + builder.tree(createExecuteChildren(builder, executable, specialization, executeParameters, null)); CodeTree primaryExecuteCall = createTemplateMethodCall(builder, null, executable, castExecutable, null, executeParameterNames); if (needsTry) { @@ -1827,134 +1919,193 @@ return createCastType(node, sourceType, castedType.getType(), hasUnexpected, value); } - protected CodeTree createCastType(NodeData node, TypeData sourceType, TypeData targetType, boolean expect, CodeTree value) { - if (targetType == null) { - return value; - } else if (!sourceType.needsCastTo(getContext(), targetType)) { - return value; - } - - CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); - String targetMethodName; - if (expect) { - targetMethodName = TypeSystemCodeGenerator.expectTypeMethodName(targetType); - } else { - targetMethodName = TypeSystemCodeGenerator.asTypeMethodName(targetType); - } - startCallTypeSystemMethod(getContext(), builder, node, targetMethodName); - - builder.tree(value); - builder.end().end(); - return builder.getRoot(); - } - protected CodeTree createExecuteChildren(CodeTreeBuilder parent, ExecutableTypeData sourceExecutable, SpecializationData specialization, List targetParameters, - ActualParameter unexpectedParameter, boolean cast) { - NodeData sourceNode = specialization.getNode(); - - CodeTreeBuilder builder = new CodeTreeBuilder(parent); - + ActualParameter unexpectedParameter) { + CodeTreeBuilder builder = parent.create(); + NodeData node = specialization.getNode(); for (ActualParameter targetParameter : targetParameters) { - NodeChildData field = sourceNode.findChild(targetParameter.getSpecification().getName()); + NodeChildData child = node.findChild(targetParameter.getSpecification().getName()); if (!targetParameter.getSpecification().isSignature()) { continue; } - TypeData targetType = targetParameter.getTypeSystemType(); ExecutableTypeData targetExecutable = null; - if (field != null) { - targetExecutable = field.findExecutableType(getContext(), targetType); + if (child != null) { + targetExecutable = child.findExecutableType(getContext(), targetType); + } + + if (targetExecutable == null) { + // TODO what to do? assertion? + continue; } - ActualParameter sourceParameter = sourceExecutable.findParameter(targetParameter.getLocalName()); - - String targetVariableName = valueName(targetParameter); - - CodeTree executionExpression = null; - if ((sourceParameter != null && cast) || sourceParameter != null) { - TypeData sourceType = sourceParameter.getTypeSystemType(); - if (targetExecutable == null || !sourceType.needsCastTo(getContext(), targetType)) { - if (field != null && field.isShortCircuit() && sourceParameter != null) { - builder.tree(createShortCircuitValue(builder, specialization, field, targetParameter.getPreviousParameter(), unexpectedParameter)); - } - builder.startStatement(); - builder.type(targetParameter.getType()).string(" "); - builder.string(targetVariableName).string(" = "); - builder.tree(CodeTreeBuilder.singleString(valueNameEvaluated(targetParameter))); - builder.end(); - continue; + CodeTree executionExpressions = createExecutionExpresssions(builder, child, sourceExecutable, targetExecutable, targetParameter, unexpectedParameter); + + String targetVarName = valueName(targetParameter); + CodeTree unexpectedTree = createCatchUnexpectedTree(builder, executionExpressions, targetVarName, specialization, sourceExecutable, targetExecutable, targetParameter, + isShortCircuit(child)); + CodeTree shortCircuitTree = createShortCircuitTree(builder, unexpectedTree, targetVarName, specialization, targetParameter, unexpectedParameter); + + if (shortCircuitTree == executionExpressions) { + if (containsNewLine(executionExpressions)) { + builder.declaration(sourceExecutable.getType().getPrimitiveType(), targetVarName); + builder.tree(shortCircuitTree); } else { - CodeTree valueTree = CodeTreeBuilder.singleString(valueNameEvaluated(targetParameter)); - executionExpression = createExpectExecutableType(sourceNode, sourceType, targetExecutable, valueTree); + builder.startStatement().type(targetParameter.getType()).string(" ").tree(shortCircuitTree).end(); } - } else if (sourceParameter == null) { - executionExpression = createExecuteChildExpression(builder, field, targetParameter, unexpectedParameter); - } - - if (executionExpression != null) { - CodeTreeVariable executionVar = new CodeTreeVariable(); - CodeTree shortCircuitTree = createShortCircuitTree(builder, executionVar, targetVariableName, specialization, targetParameter, unexpectedParameter); - CodeTree unexpectedTree = createCatchUnexpectedTree(builder, executionExpression, targetVariableName, specialization, sourceExecutable, targetExecutable, targetParameter, - shortCircuitTree != executionVar); - - executionVar.set(unexpectedTree); + } else { builder.tree(shortCircuitTree); } + + } + return builder.getRoot(); + } + + private CodeTree createExecutionExpresssions(CodeTreeBuilder parent, NodeChildData child, ExecutableTypeData sourceExecutable, ExecutableTypeData targetExecutable, ActualParameter param, + ActualParameter unexpectedParameter) { + CodeTreeBuilder builder = parent.create(); + + TypeData type = param.getTypeSystemType(); + List targetTypes = child.getNodeData().getTypeSystem().lookupSourceTypes(type); + + if (targetTypes.size() > 1) { + boolean elseIf = false; + int index = 0; + for (TypeData typeData : targetTypes) { + if (index < targetTypes.size() - 1) { + elseIf = builder.startIf(elseIf); + builder.string(typeName(param)).string(" == ").typeLiteral(typeData.getPrimitiveType()); + builder.end(); + builder.startBlock(); + } else { + builder.startElseBlock(); + } + + ExecutableTypeData implictExecutableTypeData = child.getNodeData().findExecutableType(typeData, targetExecutable.getEvaluatedCount()); + ImplicitCastData cast = child.getNodeData().getTypeSystem().lookupCast(typeData, param.getTypeSystemType()); + CodeTree execute = createExecuteExpression(parent, child, sourceExecutable, implictExecutableTypeData, param, unexpectedParameter, cast); + builder.statement(execute); + builder.end(); + index++; + } + } else { + builder.tree(createExecuteExpression(parent, child, sourceExecutable, targetExecutable, param, unexpectedParameter, null)); } return builder.getRoot(); } + private CodeTree createExecuteExpression(CodeTreeBuilder parent, NodeChildData child, ExecutableTypeData sourceExecutable, ExecutableTypeData targetExecutable, + ActualParameter targetParameter, ActualParameter unexpectedParameter, ImplicitCastData cast) { + CodeTreeBuilder builder = parent.create(); + builder.string(valueName(targetParameter)); + builder.string(" = "); + if (cast != null) { + startCallTypeSystemMethod(getContext(), builder, child.getNodeData(), cast.getMethodName()); + } + + if (targetExecutable.getType().needsCastTo(context, targetParameter.getTypeSystemType()) && cast == null) { + startCallTypeSystemMethod(getContext(), builder, child.getNodeData(), TypeSystemCodeGenerator.expectTypeMethodName(targetParameter.getTypeSystemType())); + } + + NodeData node = getModel().getNode(); + ActualParameter sourceParameter = sourceExecutable.findParameter(targetParameter.getLocalName()); + if (sourceParameter == null) { + builder.tree(createExecuteChildExpression(builder, child, targetParameter, targetExecutable, unexpectedParameter)); + } else { + CodeTree var = CodeTreeBuilder.singleString(valueNameEvaluated(targetParameter)); + builder.tree(createExpectExecutableType(node, sourceParameter.getTypeSystemType(), targetExecutable, var)); + } + + if (targetExecutable.getType().needsCastTo(context, targetParameter.getTypeSystemType())) { + builder.end().end(); + } + + if (cast != null) { + builder.end().end(); + } + + return builder.getRoot(); + } + + private boolean containsNewLine(CodeTree tree) { + if (tree.getCodeKind() == CodeTreeKind.NEW_LINE) { + return true; + } + + for (CodeTree codeTree : tree.getEnclosedElements()) { + if (containsNewLine(codeTree)) { + return true; + } + } + return false; + } + + private boolean hasUnexpected(ExecutableTypeData target, ActualParameter sourceParameter, ActualParameter targetParameter) { + List types = getModel().getNode().getTypeSystem().lookupSourceTypes(targetParameter.getTypeSystemType()); + NodeChildData child = getModel().getNode().findChild(targetParameter.getSpecification().getName()); + boolean hasUnexpected = false; + for (TypeData type : types) { + if (hasUnexpected) { + continue; + } + ExecutableTypeData execTarget = target; + if (type != execTarget.getType()) { + execTarget = child.findExecutableType(getContext(), type); + } + hasUnexpected = hasUnexpected || hasUnexpectedType(execTarget, sourceParameter, type); + } + return hasUnexpected; + } + + private boolean hasUnexpectedType(ExecutableTypeData target, ActualParameter sourceParameter, TypeData type) { + boolean targetCast = target.getType().needsCastTo(context, type); + if (targetCast && getModel().getNode().getTypeSystem().lookupCast(target.getType(), type) == null) { + return true; + } + if (sourceParameter == null) { + return target.hasUnexpectedValue(getContext()); + } else { + if (sourceParameter.getTypeSystemType().needsCastTo(getContext(), type)) { + return target.hasUnexpectedValue(getContext()); + } + return false; + } + } + private CodeTree createCatchUnexpectedTree(CodeTreeBuilder parent, CodeTree body, String targetVariableName, SpecializationData specialization, ExecutableTypeData currentExecutable, ExecutableTypeData targetExecutable, ActualParameter param, boolean shortCircuit) { CodeTreeBuilder builder = new CodeTreeBuilder(parent); - boolean unexpected = targetExecutable.hasUnexpectedValue(getContext()); - boolean cast = false; - if (targetExecutable.getType().needsCastTo(getContext(), param.getTypeSystemType())) { - unexpected = true; - cast = true; + ActualParameter sourceParameter = currentExecutable.findParameter(param.getLocalName()); + boolean unexpected = hasUnexpected(targetExecutable, sourceParameter, param); + if (!unexpected) { + return body; } - builder.startStatement(); - if (!shortCircuit) { - builder.type(param.getType()).string(" ").string(targetVariableName); + builder.declaration(param.getType(), targetVariableName); } - - if (unexpected) { - if (!shortCircuit) { - builder.end(); - } - builder.startTryBlock(); - builder.startStatement(); - builder.string(targetVariableName); - } else if (shortCircuit) { - builder.startStatement(); - builder.string(targetVariableName); - } - builder.string(" = "); - if (cast) { - builder.tree(createCastType(specialization.getNode(), targetExecutable.getType(), param.getTypeSystemType(), true, body)); - } else { + builder.startTryBlock(); + + if (containsNewLine(body)) { builder.tree(body); + } else { + builder.statement(body); } - builder.end(); - - if (unexpected) { - builder.end().startCatchBlock(getUnexpectedValueException(), "ex"); - SpecializationData generic = specialization.getNode().getGenericSpecialization(); - ActualParameter genericParameter = generic.findParameter(param.getLocalName()); - - List genericParameters = generic.getParametersAfter(genericParameter); - builder.tree(createDeoptimize(builder)); - builder.tree(createExecuteChildren(parent, currentExecutable, generic, genericParameters, genericParameter, false)); - if (specialization.isPolymorphic()) { - builder.tree(createReturnOptimizeTypes(builder, currentExecutable, specialization, param)); - } else { - builder.tree(createReturnExecuteAndSpecialize(builder, currentExecutable, specialization, param, - "Expected " + param.getLocalName() + " instanceof " + Utils.getSimpleName(param.getType()))); - } - builder.end(); // catch block + + builder.end().startCatchBlock(getUnexpectedValueException(), "ex"); + SpecializationData generic = specialization.getNode().getGenericSpecialization(); + ActualParameter genericParameter = generic.findParameter(param.getLocalName()); + + List genericParameters = generic.getParametersAfter(genericParameter); + builder.tree(createDeoptimize(builder)); + builder.tree(createExecuteChildren(parent, currentExecutable, generic, genericParameters, genericParameter)); + if (specialization.isPolymorphic()) { + builder.tree(createReturnOptimizeTypes(builder, currentExecutable, specialization, param)); + } else { + builder.tree(createReturnExecuteAndSpecialize(builder, currentExecutable, specialization, param, + "Expected " + param.getLocalName() + " instanceof " + Utils.getSimpleName(param.getType()))); } + builder.end(); // catch block return builder.getRoot(); } @@ -1969,7 +2120,7 @@ CodeTreeBuilder execute = new CodeTreeBuilder(builder); execute.startCall("next0", executeCachedName(generic)); - addInternalValueParameterNames(execute, specialization, generic, param.getLocalName(), true, true); + addInternalValueParameterNames(execute, specialization, generic, param.getLocalName(), true, true, null); execute.end(); TypeData sourceType = generic.getReturnType().getTypeSystemType(); @@ -1980,37 +2131,26 @@ return builder.getRoot(); } - private CodeTree createExecuteChildExpression(CodeTreeBuilder parent, NodeChildData targetField, ActualParameter sourceParameter, ActualParameter unexpectedParameter) { - TypeData type = sourceParameter.getTypeSystemType(); - ExecutableTypeData execType = targetField.findExecutableType(getContext(), type); - + private CodeTree createExecuteChildExpression(CodeTreeBuilder parent, NodeChildData targetChild, ActualParameter targetParameter, ExecutableTypeData targetExecutable, + ActualParameter unexpectedParameter) { CodeTreeBuilder builder = new CodeTreeBuilder(parent); - if (targetField != null) { - Element accessElement = targetField.getAccessElement(); - if (accessElement == null || accessElement.getKind() == ElementKind.METHOD) { - builder.string("this.").string(targetField.getName()); - } else if (accessElement.getKind() == ElementKind.FIELD) { - builder.string("this.").string(accessElement.getSimpleName().toString()); - } else { - throw new AssertionError(); - } - if (sourceParameter.getSpecification().isIndexed()) { - builder.string("[" + sourceParameter.getIndex() + "]"); - } + if (targetChild != null) { + builder.tree(createAccessChild(builder, targetChild, targetParameter)); builder.string("."); } - builder.startCall(execType.getMethodName()); - + builder.startCall(targetExecutable.getMethodName()); + + // TODO this should be merged with #createTemplateMethodCall int index = 0; - for (ActualParameter parameter : execType.getParameters()) { + for (ActualParameter parameter : targetExecutable.getParameters()) { if (!parameter.getSpecification().isSignature()) { builder.string(parameter.getLocalName()); } else { - if (index < targetField.getExecuteWith().size()) { - NodeChildData child = targetField.getExecuteWith().get(index); + if (index < targetChild.getExecuteWith().size()) { + NodeChildData child = targetChild.getExecuteWith().get(index); ParameterSpec spec = getModel().getSpecification().findParameterSpec(child.getName()); List specializationParams = getModel().findParameters(spec); @@ -2049,32 +2189,50 @@ return builder.getRoot(); } + private CodeTree createAccessChild(CodeTreeBuilder parent, NodeChildData targetChild, ActualParameter targetParameter) throws AssertionError { + CodeTreeBuilder builder = parent.create(); + Element accessElement = targetChild.getAccessElement(); + if (accessElement == null || accessElement.getKind() == ElementKind.METHOD) { + builder.string("this.").string(targetChild.getName()); + } else if (accessElement.getKind() == ElementKind.FIELD) { + builder.string("this.").string(accessElement.getSimpleName().toString()); + } else { + throw new AssertionError(); + } + if (targetParameter.getSpecification().isIndexed()) { + builder.string("[" + targetParameter.getIndex() + "]"); + } + return builder.getRoot(); + } + private CodeTree createShortCircuitTree(CodeTreeBuilder parent, CodeTree body, String targetVariableName, SpecializationData specialization, ActualParameter parameter, ActualParameter exceptionParam) { - CodeTreeBuilder builder = new CodeTreeBuilder(parent); - NodeChildData forField = specialization.getNode().findChild(parameter.getSpecification().getName()); - if (forField == null) { + if (!isShortCircuit(forField)) { return body; } - if (forField.getExecutionKind() != ExecutionKind.SHORT_CIRCUIT) { - return body; - } - + CodeTreeBuilder builder = new CodeTreeBuilder(parent); ActualParameter shortCircuitParam = specialization.getPreviousParam(parameter); - builder.tree(createShortCircuitValue(builder, specialization, forField, shortCircuitParam, exceptionParam)); - builder.declaration(parameter.getType(), targetVariableName, CodeTreeBuilder.createBuilder().defaultValue(parameter.getType())); builder.startIf().string(shortCircuitParam.getLocalName()).end(); builder.startBlock(); - builder.tree(body); + + if (containsNewLine(body)) { + builder.tree(body); + } else { + builder.statement(body); + } builder.end(); return builder.getRoot(); } + private boolean isShortCircuit(NodeChildData forField) { + return forField != null && forField.getExecutionKind() == ExecutionKind.SHORT_CIRCUIT; + } + private CodeTree createShortCircuitValue(CodeTreeBuilder parent, SpecializationData specialization, NodeChildData forField, ActualParameter shortCircuitParam, ActualParameter exceptionParam) { CodeTreeBuilder builder = new CodeTreeBuilder(parent); int shortCircuitIndex = 0; @@ -2109,7 +2267,7 @@ CodeTreeBuilder specializeCall = new CodeTreeBuilder(parent); specializeCall.startCall(EXECUTE_SPECIALIZE_NAME); specializeCall.string(String.valueOf(node.getSpecializations().indexOf(current))); - addInternalValueParameterNames(specializeCall, generic, node.getGenericSpecialization(), exceptionParam != null ? exceptionParam.getLocalName() : null, true, true); + addInternalValueParameterNames(specializeCall, generic, node.getGenericSpecialization(), exceptionParam != null ? exceptionParam.getLocalName() : null, true, true, null); specializeCall.doubleQuote(reason); specializeCall.end().end(); @@ -2199,6 +2357,233 @@ } } + private class BaseCastNodeFactory extends ClassElementFactory { + + protected final Set usedTargetTypes; + + public BaseCastNodeFactory(ProcessorContext context, Set usedTargetTypes) { + super(context); + this.usedTargetTypes = usedTargetTypes; + } + + @Override + protected CodeTypeElement create(NodeData m) { + CodeTypeElement type = createClass(m, modifiers(STATIC), nodeCastClassName(m, null), context.getTruffleTypes().getNode(), false); + + CodeVariableElement delegate = new CodeVariableElement(m.getNodeType(), "delegate"); + delegate.getModifiers().add(PROTECTED); + delegate.getAnnotationMirrors().add(new CodeAnnotationMirror(getContext().getTruffleTypes().getChildAnnotation())); + + type.add(delegate); + type.add(createConstructorUsingFields(modifiers(), type)); + return type; + } + + @Override + protected void createChildren(NodeData m) { + CodeTypeElement type = getElement(); + type.add(createExecute(EXECUTE_SPECIALIZE_NAME, true)); + type.add(createExecute(EXECUTE_GENERIC_NAME, false)); + + for (ExecutableTypeData targetExecutable : m.getExecutableTypes()) { + if (!usedTargetTypes.contains(targetExecutable.getType()) && targetExecutable.hasUnexpectedValue(getContext())) { + continue; + } + CodeExecutableElement execute = createCastExecute(targetExecutable, targetExecutable, false); + CodeExecutableElement expect = createCastExecute(targetExecutable, targetExecutable, true); + if (execute != null) { + getElement().add(execute); + } + if (expect != null) { + getElement().add(expect); + } + } + Set sourceTypes = new TreeSet<>(); + List casts = getModel().getTypeSystem().getImplicitCasts(); + for (ImplicitCastData cast : casts) { + sourceTypes.add(cast.getSourceType()); + } + + CodeTypeElement baseType = getElement(); + for (TypeData sourceType : sourceTypes) { + add(new SpecializedCastNodeFactory(context, baseType, sourceType, usedTargetTypes), getModel()); + } + } + + private CodeExecutableElement createExecute(String name, boolean specialize) { + NodeData node = getModel(); + TypeMirror objectType = node.getTypeSystem().getGenericType(); + CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), objectType, name, new CodeVariableElement(objectType, "value")); + if (specialize) { + method.getModifiers().add(FINAL); + } + CodeTreeBuilder builder = method.createBuilder(); + + List casts = node.getTypeSystem().getImplicitCasts(); + boolean elseIf = false; + for (ImplicitCastData cast : casts) { + elseIf = builder.startIf(elseIf); + startCallTypeSystemMethod(context, builder, getModel(), TypeSystemCodeGenerator.isTypeMethodName(cast.getSourceType())); + builder.string("value"); + builder.end().end(); + builder.end(); + builder.startBlock(); + + if (specialize) { + builder.startStatement().startCall("replace").startNew(nodeCastClassName(getModel(), cast.getSourceType())).string("delegate").end().doubleQuote("Added cast").end().end(); + } + builder.startReturn(); + + startCallTypeSystemMethod(context, builder, getModel(), cast.getMethodName()); + startCallTypeSystemMethod(context, builder, getModel(), TypeSystemCodeGenerator.asTypeMethodName(cast.getSourceType())); + builder.string("value"); + builder.end().end(); + builder.end().end(); + + builder.end(); + builder.end(); + } + + builder.startReturn().string("value").end(); + + return method; + } + + protected CodeExecutableElement createCastExecute(ExecutableTypeData sourceExecutable, ExecutableTypeData targetExecutable, boolean expect) { + ImplicitCastData cast = null; + if (!sourceExecutable.getType().equals(targetExecutable.getType())) { + cast = getModel().getTypeSystem().lookupCast(sourceExecutable.getType(), targetExecutable.getType()); + if (cast == null) { + return null; + } + } + + if (expect) { + if (targetExecutable.getEvaluatedCount() > 0) { + return null; + } else if (Utils.isObject(targetExecutable.getType().getPrimitiveType())) { + return null; + } + } + + boolean hasTargetUnexpected = targetExecutable.hasUnexpectedValue(getContext()); + boolean hasSourceUnexpected = sourceExecutable.hasUnexpectedValue(getContext()); + + CodeExecutableElement method = copyTemplateMethod(targetExecutable); + method.getModifiers().add(PUBLIC); + + CodeTreeBuilder builder = method.createBuilder(); + + if (hasSourceUnexpected && cast != null) { + builder.startTryBlock(); + } + + if (expect) { + method.getParameters().clear(); + String expectMethodName; + if (hasTargetUnexpected) { + expectMethodName = TypeSystemCodeGenerator.expectTypeMethodName(targetExecutable.getType()); + } else { + expectMethodName = TypeSystemCodeGenerator.asTypeMethodName(targetExecutable.getType()); + } + method.setSimpleName(CodeNames.of(expectMethodName)); + method.addParameter(new CodeVariableElement(getModel().getTypeSystem().getGenericType(), "value")); + } + + builder.startReturn(); + CodeTree executeCall; + if (expect) { + executeCall = createCastType(getModel(), getModel().getTypeSystem().getGenericTypeData(), sourceExecutable.getType(), hasSourceUnexpected, CodeTreeBuilder.singleString("value")); + } else { + executeCall = createTemplateMethodCall(builder, CodeTreeBuilder.singleString("delegate."), targetExecutable, sourceExecutable, null); + } + if (cast != null) { + startCallTypeSystemMethod(context, builder, getModel(), cast.getMethodName()); + builder.tree(executeCall); + builder.end().end(); + } else { + builder.tree(executeCall); + } + builder.end(); + + if (hasSourceUnexpected && cast != null) { + builder.end(); + builder.startCatchBlock(getContext().getTruffleTypes().getUnexpectedValueException(), "ex"); + builder.startStatement().startCall("replace").startNew(nodeCastClassName(getModel(), null)).string("delegate").end().doubleQuote("Removed cast").end().end(); + + if (hasTargetUnexpected) { + builder.startThrow().string("ex").end(); + } else { + builder.startThrow().startNew(getContext().getType(AssertionError.class)).end().end(); + } + builder.end(); + } + + return method; + } + + private CodeExecutableElement copyTemplateMethod(TemplateMethod targetExecutable) { + CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), targetExecutable.getMethod()); + method.getModifiers().remove(ABSTRACT); + method.getAnnotationMirrors().clear(); + Modifier visibility = Utils.getVisibility(method.getModifiers()); + if (visibility != null) { + method.getModifiers().remove(visibility); + } + int index = 0; + for (ActualParameter parameter : targetExecutable.getParameters()) { + ((CodeVariableElement) method.getParameters().get(index)).setName(parameter.getLocalName()); + index++; + } + return method; + } + + } + + private class SpecializedCastNodeFactory extends BaseCastNodeFactory { + + private final CodeTypeElement baseType; + private final TypeData sourceType; + + public SpecializedCastNodeFactory(ProcessorContext context, CodeTypeElement baseType, TypeData type, Set usedTargetTypes) { + super(context, usedTargetTypes); + this.baseType = baseType; + this.sourceType = type; + } + + @Override + protected CodeTypeElement create(NodeData m) { + CodeTypeElement type = createClass(m, modifiers(PRIVATE, STATIC, FINAL), nodeCastClassName(m, sourceType), baseType.asType(), false); + type.add(createConstructorUsingFields(modifiers(), type)); + return type; + } + + @Override + protected void createChildren(NodeData node) { + for (TypeData targetType : usedTargetTypes) { + for (ExecutableTypeData targetExecutable : node.getExecutableTypes()) { + if (targetExecutable.getType().equals(targetType)) { + ExecutableTypeData sourceExecutable = node.findExecutableType(sourceType, targetExecutable.getEvaluatedCount()); + if (sourceExecutable == null) { + // TODO what if there is no evaluated version? + continue; + } + CodeExecutableElement execute = createCastExecute(sourceExecutable, targetExecutable, false); + CodeExecutableElement expect = createCastExecute(sourceExecutable, targetExecutable, true); + if (execute != null) { + getElement().add(execute); + } + if (expect != null) { + getElement().add(expect); + } + } + } + + } + } + + } + private class SpecializedNodeFactory extends NodeBaseFactory { protected final CodeTypeElement nodeGen; @@ -2277,15 +2662,31 @@ } CodeExecutableElement superConstructor = createSuperConstructor(clazz, constructor); + CodeTree body = superConstructor.getBodyTree(); + CodeTreeBuilder builder = superConstructor.createBuilder(); + builder.tree(body); if (superConstructor != null) { if (getModel().isGeneric() && node.isPolymorphic()) { - CodeTree body = superConstructor.getBodyTree(); - CodeTreeBuilder builder = superConstructor.createBuilder(); - builder.tree(body); builder.statement("this.next0 = null"); } + for (ActualParameter param : getModel().getParameters()) { + if (!param.getSpecification().isSignature()) { + continue; + } + NodeChildData child = getModel().getNode().findChild(param.getSpecification().getName()); + List types = child.getNodeData().getTypeSystem().lookupSourceTypes(param.getTypeSystemType()); + if (types.size() > 1) { + clazz.add(new CodeVariableElement(modifiers(PRIVATE, FINAL), getContext().getType(Class.class), typeName(param))); + superConstructor.getParameters().add(new CodeVariableElement(getContext().getType(Class.class), typeName(param))); + + builder.startStatement(); + builder.string("this.").string(typeName(param)).string(" = ").string(typeName(param)); + builder.end(); + } + } + clazz.add(superConstructor); } } @@ -2333,7 +2734,7 @@ } else { CodeTreeBuilder elseBuilder = new CodeTreeBuilder(builder); elseBuilder.startReturn().startCall("this.next0", executeCachedName(polymorphic)); - addInternalValueParameterNames(elseBuilder, polymorphic, polymorphic, null, true, true); + addInternalValueParameterNames(elseBuilder, polymorphic, polymorphic, null, true, true, null); elseBuilder.end().end(); boolean forceElse = specialization.getExceptions().size() > 0; @@ -2375,7 +2776,7 @@ CodeTreeBuilder specializeCall = new CodeTreeBuilder(builder); specializeCall.startCall(EXECUTE_SPECIALIZE_NAME); specializeCall.string("0"); - addInternalValueParameterNames(specializeCall, specialization, node.getGenericSpecialization(), null, true, true); + addInternalValueParameterNames(specializeCall, specialization, node.getGenericSpecialization(), null, true, true, null); specializeCall.startGroup().doubleQuote("Uninitialized polymorphic (").string(" + depth + ").doubleQuote("/" + node.getPolymorphicDepth() + ")").end(); specializeCall.end().end(); @@ -2482,7 +2883,7 @@ builder.tree(createDeoptimize(builder)); } - builder.tree(createExecuteChildren(builder, executable, specialization, specialization.getParameters(), null, false)); + builder.tree(createExecuteChildren(builder, executable, specialization, specialization.getParameters(), null)); CodeTree returnSpecialized = null; @@ -2519,26 +2920,25 @@ CodeTreeBuilder returnBuilder = new CodeTreeBuilder(parent); if (specialization.isPolymorphic()) { returnBuilder.startCall("next0", executeCachedName(specialization)); - addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, true); + addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, true, null); returnBuilder.end(); } else if (specialization.isUninitialized()) { returnBuilder.startCall("super", EXECUTE_SPECIALIZE_NAME); returnBuilder.string("0"); - addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, true); + addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, true, null); returnBuilder.doubleQuote("Uninitialized monomorphic"); returnBuilder.end(); } else if (specialization.getMethod() == null && !node.needsRewrites(context)) { emitEncounteredSynthetic(builder, specialization); } else if (specialization.isGeneric()) { returnBuilder.startCall("super", EXECUTE_GENERIC_NAME); - addInternalValueParameterNames(returnBuilder, specialization, specialization, null, node.needsFrame(), true); + addInternalValueParameterNames(returnBuilder, specialization, specialization, null, node.needsFrame(), true, null); returnBuilder.end(); } else { returnBuilder.tree(createTemplateMethodCall(returnBuilder, null, specialization, specialization, null)); } if (!returnBuilder.isEmpty()) { - ExecutableTypeData sourceExecutableType = node.findExecutableType(specialization.getReturnType().getTypeSystemType(), 0); boolean sourceThrowsUnexpected = sourceExecutableType != null && sourceExecutableType.hasUnexpectedValue(getContext()); boolean targetSupportsUnexpected = executable.hasUnexpectedValue(getContext()); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeData.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeData.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeData.java Fri Sep 13 23:12:10 2013 +0200 @@ -32,7 +32,7 @@ import com.oracle.truffle.dsl.processor.template.*; import com.oracle.truffle.dsl.processor.typesystem.*; -public class NodeData extends Template { +public class NodeData extends Template implements Comparable { private final String nodeId; private NodeData declaringNode; @@ -90,6 +90,15 @@ return false; } + public boolean needsImplicitCast(ProcessorContext context) { + for (NodeChildData child : getChildren()) { + if (child.needsImplicitCast(context)) { + return true; + } + } + return false; + } + public int getPolymorphicDepth() { return polymorphicDepth; } @@ -574,4 +583,7 @@ return null; } + public int compareTo(NodeData o) { + return getNodeId().compareTo(o.getNodeId()); + } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeParser.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeParser.java Fri Sep 13 23:12:10 2013 +0200 @@ -332,7 +332,7 @@ nodeData.setNodeContainer(nodeContainer != null); nodeData.setTypeSystem(typeSystem); nodeData.setFields(parseFields(typeHierarchy, elements)); - nodeData.setChildren(parseChildren(elements, typeHierarchy)); + nodeData.setChildren(parseChildren(nodeData, elements, typeHierarchy)); nodeData.setExecutableTypes(groupExecutableTypes(new ExecutableTypeMethodParser(context, nodeData).parse(elements))); // resolveChildren invokes cyclic parsing. @@ -407,7 +407,7 @@ } } - private List parseChildren(List elements, final List typeHierarchy) { + private List parseChildren(NodeData parent, List elements, final List typeHierarchy) { Set shortCircuits = new HashSet<>(); for (ExecutableElement method : ElementFilter.methodsIn(elements)) { AnnotationMirror mirror = Utils.findAnnotationMirror(processingEnv, method, ShortCircuit.class); @@ -472,7 +472,7 @@ kind = ExecutionKind.SHORT_CIRCUIT; } - NodeChildData nodeChild = new NodeChildData(type, childMirror, name, childType, originalChildType, getter, cardinality, kind); + NodeChildData nodeChild = new NodeChildData(parent, type, childMirror, name, childType, originalChildType, getter, cardinality, kind); parsedChildren.add(nodeChild); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MessageContainer.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MessageContainer.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MessageContainer.java Fri Sep 13 23:12:10 2013 +0200 @@ -129,7 +129,7 @@ TypeElement rootEnclosing = Utils.findRootEnclosingType(getMessageElement()); TypeElement baseEnclosing = Utils.findRootEnclosingType(baseType); - if (rootEnclosing == null || !Utils.typeEquals(baseEnclosing.asType(), rootEnclosing.asType()) || this != message.getOriginalContainer()) { + if (rootEnclosing == null || !Utils.typeEquals(baseEnclosing.asType(), rootEnclosing.asType())) { // redirect message MessageContainer original = message.getOriginalContainer(); messageElement = baseType; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/ImplicitCastData.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/ImplicitCastData.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/ImplicitCastData.java Fri Sep 13 23:12:10 2013 +0200 @@ -26,8 +26,32 @@ public class ImplicitCastData extends TemplateMethod { - public ImplicitCastData(TemplateMethod method) { + private final TypeData sourceType; + private final TypeData targetType; + + public ImplicitCastData(TemplateMethod method, TypeData sourceType, TypeData targetType) { super(method); + this.sourceType = sourceType; + this.targetType = targetType; + } + + public TypeData getSourceType() { + return sourceType; + } + + public TypeData getTargetType() { + return targetType; + } + + @Override + public int compareTo(TemplateMethod o) { + if (o instanceof ImplicitCastData) { + // implicit casts are ordered by source type since + // its also the order in which they are checked. + TypeData otherSourceType = ((ImplicitCastData) o).getSourceType(); + return this.sourceType.compareTo(otherSourceType); + } + return super.compareTo(o); } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/ImplicitCastParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/ImplicitCastParser.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/ImplicitCastParser.java Fri Sep 13 23:12:10 2013 +0200 @@ -56,7 +56,20 @@ @Override public ImplicitCastData create(TemplateMethod method, boolean invalid) { - return new ImplicitCastData(method); + if (invalid) { + return new ImplicitCastData(method, null, null); + } + + ActualParameter target = method.findParameter("targetValue"); + ActualParameter source = method.findParameter("sourceValue"); + + TypeData targetType = target.getTypeSystemType(); + TypeData sourceType = source.getTypeSystemType(); + + if (targetType.equals(sourceType)) { + method.addError("Target type and source type of an @%s must not be the same type.", ImplicitCast.class.getSimpleName()); + } + + return new ImplicitCastData(method, sourceType, targetType); } - } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemCodeGenerator.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemCodeGenerator.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemCodeGenerator.java Fri Sep 13 23:12:10 2013 +0200 @@ -44,10 +44,22 @@ return "is" + Utils.getTypeId(type.getBoxedType()); } + public static String isImplicitTypeMethodName(TypeData type) { + return "isImplicit" + Utils.getTypeId(type.getBoxedType()); + } + public static String asTypeMethodName(TypeData type) { return "as" + Utils.getTypeId(type.getBoxedType()); } + public static String asImplicitTypeMethodName(TypeData type) { + return "asImplicit" + Utils.getTypeId(type.getBoxedType()); + } + + public static String getImplicitClass(TypeData type) { + return "getImplicit" + Utils.getTypeId(type.getBoxedType()) + "Class"; + } + public static String expectTypeMethodName(TypeData type) { return "expect" + Utils.getTypeId(type.getBoxedType()); } @@ -100,6 +112,20 @@ clazz.add(expect); } } + + CodeExecutableElement asImplicit = createAsImplicitTypeMethod(type); + if (asImplicit != null) { + clazz.add(asImplicit); + } + CodeExecutableElement isImplicit = createIsImplicitTypeMethod(type); + if (isImplicit != null) { + clazz.add(isImplicit); + } + + CodeExecutableElement typeIndex = createGetTypeIndex(type); + if (typeIndex != null) { + clazz.add(typeIndex); + } } } @@ -133,6 +159,95 @@ return field; } + private CodeExecutableElement createIsImplicitTypeMethod(TypeData type) { + TypeSystemData typeSystem = getModel(); + List casts = typeSystem.lookupByTargetType(type); + if (casts.isEmpty()) { + return null; + } + CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), getContext().getType(boolean.class), TypeSystemCodeGenerator.isImplicitTypeMethodName(type)); + method.addParameter(new CodeVariableElement(getContext().getType(Object.class), LOCAL_VALUE)); + CodeTreeBuilder builder = method.createBuilder(); + + List sourceTypes = typeSystem.lookupSourceTypes(type); + + builder.startReturn(); + String sep = ""; + for (TypeData sourceType : sourceTypes) { + builder.string(sep); + builder.startCall(isTypeMethodName(sourceType)).string(LOCAL_VALUE).end(); + sep = " || "; + } + builder.end(); + return method; + } + + private CodeExecutableElement createAsImplicitTypeMethod(TypeData type) { + TypeSystemData typeSystem = getModel(); + List casts = typeSystem.lookupByTargetType(type); + if (casts.isEmpty()) { + return null; + } + CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), type.getPrimitiveType(), TypeSystemCodeGenerator.asImplicitTypeMethodName(type)); + method.addParameter(new CodeVariableElement(getContext().getType(Object.class), LOCAL_VALUE)); + + List sourceTypes = typeSystem.lookupSourceTypes(type); + + CodeTreeBuilder builder = method.createBuilder(); + boolean elseIf = false; + for (TypeData sourceType : sourceTypes) { + elseIf = builder.startIf(elseIf); + builder.startCall(isTypeMethodName(sourceType)).string(LOCAL_VALUE).end(); + builder.end().startBlock(); + + builder.startReturn(); + ImplicitCastData cast = typeSystem.lookupCast(sourceType, type); + if (cast != null) { + builder.startCall(cast.getMethodName()); + } + builder.startCall(asTypeMethodName(sourceType)).string(LOCAL_VALUE).end(); + if (cast != null) { + builder.end(); + } + builder.end(); + builder.end(); + } + + builder.startElseBlock(); + builder.startStatement().startStaticCall(getContext().getTruffleTypes().getCompilerDirectives(), "transferToInterpreter").end().end(); + builder.startThrow().startNew(getContext().getType(IllegalArgumentException.class)).doubleQuote("Illegal type ").end().end(); + builder.end(); + return method; + } + + private CodeExecutableElement createGetTypeIndex(TypeData type) { + TypeSystemData typeSystem = getModel(); + List casts = typeSystem.lookupByTargetType(type); + if (casts.isEmpty()) { + return null; + } + CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), getContext().getType(Class.class), TypeSystemCodeGenerator.getImplicitClass(type)); + method.addParameter(new CodeVariableElement(getContext().getType(Object.class), LOCAL_VALUE)); + + List sourceTypes = typeSystem.lookupSourceTypes(type); + CodeTreeBuilder builder = method.createBuilder(); + boolean elseIf = false; + for (TypeData sourceType : sourceTypes) { + elseIf = builder.startIf(elseIf); + builder.startCall(isTypeMethodName(sourceType)).string(LOCAL_VALUE).end(); + builder.end().startBlock(); + builder.startReturn().typeLiteral(sourceType.getPrimitiveType()).end(); + builder.end(); + } + + builder.startElseBlock(); + builder.startStatement().startStaticCall(getContext().getTruffleTypes().getCompilerDirectives(), "transferToInterpreter").end().end(); + builder.startThrow().startNew(getContext().getType(IllegalArgumentException.class)).doubleQuote("Illegal type ").end().end(); + builder.end(); + + return method; + } + private CodeExecutableElement createIsTypeMethod(TypeData type) { if (!type.getTypeChecks().isEmpty()) { return null; @@ -174,8 +289,8 @@ method.addThrownType(getContext().getTruffleTypes().getUnexpectedValueException()); CodeTreeBuilder body = method.createBuilder(); - body.startIf().startCall(null, TypeSystemCodeGenerator.isTypeMethodName(expectedType)).string(LOCAL_VALUE).end().end().startBlock(); - body.startReturn().startCall(null, TypeSystemCodeGenerator.asTypeMethodName(expectedType)).string(LOCAL_VALUE).end().end(); + body.startIf().startCall(TypeSystemCodeGenerator.isTypeMethodName(expectedType)).string(LOCAL_VALUE).end().end().startBlock(); + body.startReturn().startCall(TypeSystemCodeGenerator.asTypeMethodName(expectedType)).string(LOCAL_VALUE).end().end(); body.end(); // if-block body.startThrow().startNew(getContext().getTruffleTypes().getUnexpectedValueException()).string(LOCAL_VALUE).end().end(); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemData.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemData.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemData.java Fri Sep 13 23:12:10 2013 +0200 @@ -36,6 +36,7 @@ private List primitiveTypeMirrors = new ArrayList<>(); private List boxedTypeMirrors = new ArrayList<>(); + private List implicitCasts; private List casts; private List checks; @@ -61,6 +62,14 @@ } } + public void setImplicitCasts(List implicitCasts) { + this.implicitCasts = implicitCasts; + } + + public List getImplicitCasts() { + return implicitCasts; + } + public void setCasts(List casts) { this.casts = casts; } @@ -89,6 +98,9 @@ if (casts != null) { sinks.addAll(casts); } + if (implicitCasts != null) { + sinks.addAll(implicitCasts); + } return sinks; } @@ -161,4 +173,55 @@ return getClass().getSimpleName() + "[template = " + Utils.getSimpleName(getTemplateType()) + ", types = " + types + "]"; } + public Set lookupCastSourceTypes() { + if (getImplicitCasts() == null) { + return null; + } + + Set sourceTypes = new TreeSet<>(); + for (ImplicitCastData cast : getImplicitCasts()) { + sourceTypes.add(cast.getSourceType()); + } + return sourceTypes; + } + + public List lookupByTargetType(TypeData targetType) { + if (getImplicitCasts() == null) { + return Collections.emptyList(); + } + List foundCasts = new ArrayList<>(); + for (ImplicitCastData cast : getImplicitCasts()) { + if (cast.getTargetType().equals(targetType)) { + foundCasts.add(cast); + } + } + return foundCasts; + } + + public ImplicitCastData lookupCast(TypeData sourceType, TypeData targetType) { + if (getImplicitCasts() == null) { + return null; + } + for (ImplicitCastData cast : getImplicitCasts()) { + if (cast.getSourceType().equals(sourceType) && cast.getTargetType().equals(targetType)) { + return cast; + } + } + return null; + } + + public List lookupSourceTypes(TypeData type) { + List sourceTypes = new ArrayList<>(); + sourceTypes.add(type); + if (getImplicitCasts() != null) { + for (ImplicitCastData cast : getImplicitCasts()) { + if (cast.getTargetType() == type) { + sourceTypes.add(cast.getSourceType()); + } + } + } + Collections.sort(sourceTypes); + return sourceTypes; + } + } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemParser.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemParser.java Fri Sep 13 23:12:10 2013 +0200 @@ -71,7 +71,7 @@ } typeSystem.setTypes(parseTypes(typeSystem)); - if (typeSystem.getTypes() == null) { + if (typeSystem.hasErrors()) { return typeSystem; } @@ -91,6 +91,8 @@ if (casts == null || checks == null || implicitCasts == null) { return typeSystem; } + + typeSystem.setImplicitCasts(implicitCasts); typeSystem.setCasts(casts); typeSystem.setChecks(checks); diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLTypes.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLTypes.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLTypes.java Fri Sep 13 23:12:10 2013 +0200 @@ -69,4 +69,9 @@ public boolean isBigInteger(@SuppressWarnings("unused") int value) { return true; } + + @ImplicitCast + public BigInteger castBigInteger(int value) { + return BigInteger.valueOf(value); + } } diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.java Fri Sep 13 23:12:10 2013 +0200 @@ -32,11 +32,11 @@ // Checkstyle: stop // @formatter:off public class Parser { - public static final int _EOF = 0; - public static final int _identifier = 1; - public static final int _stringLiteral = 2; - public static final int _numericLiteral = 3; - public static final int maxT = 28; + public static final int _EOF = 0; + public static final int _identifier = 1; + public static final int _stringLiteral = 2; + public static final int _numericLiteral = 3; + public static final int maxT = 28; static final boolean T = true; static final boolean x = false; @@ -120,255 +120,255 @@ } } - void SimpleLanguage() { - Function(); - while (la.kind == 4) { - Function(); - } - } - - void Function() { - Expect(4); - factory.startFunction(); - Expect(1); - String name = t.val; - StatementNode body = Block(); - factory.createFunction(body, name); - } - - StatementNode Block() { - StatementNode result; - List statements = new ArrayList<>(); - Expect(5); - while (StartOf(1)) { - StatementNode statement = Statement(); - statements.add(statement); - } - Expect(6); - result = factory.createBlock(statements); - return result; - } - - StatementNode Statement() { - StatementNode result; - result = null; - if (la.kind == 7) { - result = WhileStatement(); - } else if (la.kind == 1) { - result = AssignmentStatement(); - } else if (la.kind == 12) { - result = OutputStatement(); - } else if (la.kind == 13) { - result = ReturnStatement(); - } else SynErr(29); - return result; - } - - StatementNode WhileStatement() { - StatementNode result; - Expect(7); - Expect(8); - ConditionNode condition = Expression(); - Expect(9); - StatementNode body = Block(); - result = factory.createWhile(condition, body); - return result; - } - - StatementNode AssignmentStatement() { - StatementNode result; - Expect(1); - String name = t.val; - Expect(10); - TypedNode rvalue = Expression(); - Expect(11); - result = factory.createAssignment(name, rvalue); - return result; - } - - StatementNode OutputStatement() { - StatementNode result; - List expressions = new ArrayList<>(); - Expect(12); - while (StartOf(2)) { - TypedNode value = Expression(); - expressions.add(value); - } - Expect(11); - result = factory.createPrint(expressions); - return result; - } - - StatementNode ReturnStatement() { - StatementNode result; - Expect(13); - TypedNode value = Expression(); - Expect(11); - result = factory.createReturn(value); - return result; - } - - TypedNode Expression() { - TypedNode result; - result = ValueExpression(); - if (StartOf(3)) { - switch (la.kind) { - case 14: { - Get(); - break; - } - case 15: { - Get(); - break; - } - case 16: { - Get(); - break; - } - case 17: { - Get(); - break; - } - case 18: { - Get(); - break; - } - case 19: { - Get(); - break; - } - } - String op = t.val; - TypedNode right = ValueExpression(); - result = factory.createBinary(op, result, right); - } - return result; - } - - TypedNode ValueExpression() { - TypedNode result; - result = Term(); - while (la.kind == 20 || la.kind == 21) { - if (la.kind == 20) { - Get(); - } else { - Get(); - } - String op = t.val; - TypedNode right = Term(); - result = factory.createBinary(op, result, right); - } - return result; - } - - TypedNode Term() { - TypedNode result; - result = Factor(); - while (la.kind == 22 || la.kind == 23) { - if (la.kind == 22) { - Get(); - } else { - Get(); - } - String op = t.val; - TypedNode right = Factor(); - result = factory.createBinary(op, result, right); - } - return result; - } - - TypedNode Factor() { - TypedNode result; - result = null; - switch (la.kind) { - case 27: { - result = TimeRef(); - break; - } - case 1: { - result = VariableRef(); - break; - } - case 2: { - result = StringLiteral(); - break; - } - case 3: { - result = NumericLiteral(); - break; - } - case 24: { - result = Ternary(); - break; - } - case 8: { - Get(); - result = Expression(); - Expect(9); - break; - } - default: SynErr(30); break; - } - return result; - } - - TypedNode TimeRef() { - TypedNode result; - Expect(27); - result = factory.createTime(); - return result; - } - - TypedNode VariableRef() { - TypedNode result; - Expect(1); - result = factory.createLocal(t.val); - return result; - } - - TypedNode StringLiteral() { - TypedNode result; - Expect(2); - result = factory.createStringLiteral(t.val.substring(1, t.val.length() - 1)); - return result; - } - - TypedNode NumericLiteral() { - TypedNode result; - Expect(3); - result = factory.createNumericLiteral(t.val); - return result; - } - - TypedNode Ternary() { - TypedNode result; - TypedNode condition, thenPart, elsePart; - Expect(24); - condition = Expression(); - Expect(25); - thenPart = Expression(); - Expect(26); - elsePart = Expression(); - result = factory.createTernary(condition, thenPart, elsePart); - return result; - } - + void SimpleLanguage() { + Function(); + while (la.kind == 4) { + Function(); + } + } + + void Function() { + Expect(4); + factory.startFunction(); + Expect(1); + String name = t.val; + StatementNode body = Block(); + factory.createFunction(body, name); + } + + StatementNode Block() { + StatementNode result; + List statements = new ArrayList<>(); + Expect(5); + while (StartOf(1)) { + StatementNode statement = Statement(); + statements.add(statement); + } + Expect(6); + result = factory.createBlock(statements); + return result; + } + + StatementNode Statement() { + StatementNode result; + result = null; + if (la.kind == 7) { + result = WhileStatement(); + } else if (la.kind == 1) { + result = AssignmentStatement(); + } else if (la.kind == 12) { + result = OutputStatement(); + } else if (la.kind == 13) { + result = ReturnStatement(); + } else SynErr(29); + return result; + } + + StatementNode WhileStatement() { + StatementNode result; + Expect(7); + Expect(8); + ConditionNode condition = Expression(); + Expect(9); + StatementNode body = Block(); + result = factory.createWhile(condition, body); + return result; + } + + StatementNode AssignmentStatement() { + StatementNode result; + Expect(1); + String name = t.val; + Expect(10); + TypedNode rvalue = Expression(); + Expect(11); + result = factory.createAssignment(name, rvalue); + return result; + } + + StatementNode OutputStatement() { + StatementNode result; + List expressions = new ArrayList<>(); + Expect(12); + while (StartOf(2)) { + TypedNode value = Expression(); + expressions.add(value); + } + Expect(11); + result = factory.createPrint(expressions); + return result; + } + + StatementNode ReturnStatement() { + StatementNode result; + Expect(13); + TypedNode value = Expression(); + Expect(11); + result = factory.createReturn(value); + return result; + } + + TypedNode Expression() { + TypedNode result; + result = ValueExpression(); + if (StartOf(3)) { + switch (la.kind) { + case 14: { + Get(); + break; + } + case 15: { + Get(); + break; + } + case 16: { + Get(); + break; + } + case 17: { + Get(); + break; + } + case 18: { + Get(); + break; + } + case 19: { + Get(); + break; + } + } + String op = t.val; + TypedNode right = ValueExpression(); + result = factory.createBinary(op, result, right); + } + return result; + } + + TypedNode ValueExpression() { + TypedNode result; + result = Term(); + while (la.kind == 20 || la.kind == 21) { + if (la.kind == 20) { + Get(); + } else { + Get(); + } + String op = t.val; + TypedNode right = Term(); + result = factory.createBinary(op, result, right); + } + return result; + } + + TypedNode Term() { + TypedNode result; + result = Factor(); + while (la.kind == 22 || la.kind == 23) { + if (la.kind == 22) { + Get(); + } else { + Get(); + } + String op = t.val; + TypedNode right = Factor(); + result = factory.createBinary(op, result, right); + } + return result; + } + + TypedNode Factor() { + TypedNode result; + result = null; + switch (la.kind) { + case 27: { + result = TimeRef(); + break; + } + case 1: { + result = VariableRef(); + break; + } + case 2: { + result = StringLiteral(); + break; + } + case 3: { + result = NumericLiteral(); + break; + } + case 24: { + result = Ternary(); + break; + } + case 8: { + Get(); + result = Expression(); + Expect(9); + break; + } + default: SynErr(30); break; + } + return result; + } + + TypedNode TimeRef() { + TypedNode result; + Expect(27); + result = factory.createTime(); + return result; + } + + TypedNode VariableRef() { + TypedNode result; + Expect(1); + result = factory.createLocal(t.val); + return result; + } + + TypedNode StringLiteral() { + TypedNode result; + Expect(2); + result = factory.createStringLiteral(t.val.substring(1, t.val.length() - 1)); + return result; + } + + TypedNode NumericLiteral() { + TypedNode result; + Expect(3); + result = factory.createNumericLiteral(t.val); + return result; + } + + TypedNode Ternary() { + TypedNode result; + TypedNode condition, thenPart, elsePart; + Expect(24); + condition = Expression(); + Expect(25); + thenPart = Expression(); + Expect(26); + elsePart = Expression(); + result = factory.createTernary(condition, thenPart, elsePart); + return result; + } + public void Parse() { la = new Token(); la.val = ""; Get(); - SimpleLanguage(); - Expect(0); + SimpleLanguage(); + Expect(0); } private static final boolean[][] set = { - {T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x}, - {x,T,x,x, x,x,x,T, x,x,x,x, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x}, - {x,T,T,T, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,T, x,x}, - {x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,T, T,T,T,T, x,x,x,x, x,x,x,x, x,x} + {T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x}, + {x,T,x,x, x,x,x,T, x,x,x,x, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x}, + {x,T,T,T, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,T, x,x}, + {x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,T, T,T,T,T, x,x,x,x, x,x,x,x, x,x} }; @@ -416,37 +416,37 @@ public void SynErr(int line, int col, int n) { String s; - switch (n) { - case 0: s = "EOF expected"; break; - case 1: s = "identifier expected"; break; - case 2: s = "stringLiteral expected"; break; - case 3: s = "numericLiteral expected"; break; - case 4: s = "\"function\" expected"; break; - case 5: s = "\"{\" expected"; break; - case 6: s = "\"}\" expected"; break; - case 7: s = "\"while\" expected"; break; - case 8: s = "\"(\" expected"; break; - case 9: s = "\")\" expected"; break; - case 10: s = "\"=\" expected"; break; - case 11: s = "\";\" expected"; break; - case 12: s = "\"print\" expected"; break; - case 13: s = "\"return\" expected"; break; - case 14: s = "\"<\" expected"; break; - case 15: s = "\">\" expected"; break; - case 16: s = "\"<=\" expected"; break; - case 17: s = "\">=\" expected"; break; - case 18: s = "\"==\" expected"; break; - case 19: s = "\"!=\" expected"; break; - case 20: s = "\"+\" expected"; break; - case 21: s = "\"-\" expected"; break; - case 22: s = "\"*\" expected"; break; - case 23: s = "\"/\" expected"; break; - case 24: s = "\"#\" expected"; break; - case 25: s = "\"?\" expected"; break; - case 26: s = "\":\" expected"; break; - case 27: s = "\"time\" expected"; break; - case 28: s = "??? expected"; break; - case 29: s = "invalid Statement"; break; + switch (n) { + case 0: s = "EOF expected"; break; + case 1: s = "identifier expected"; break; + case 2: s = "stringLiteral expected"; break; + case 3: s = "numericLiteral expected"; break; + case 4: s = "\"function\" expected"; break; + case 5: s = "\"{\" expected"; break; + case 6: s = "\"}\" expected"; break; + case 7: s = "\"while\" expected"; break; + case 8: s = "\"(\" expected"; break; + case 9: s = "\")\" expected"; break; + case 10: s = "\"=\" expected"; break; + case 11: s = "\";\" expected"; break; + case 12: s = "\"print\" expected"; break; + case 13: s = "\"return\" expected"; break; + case 14: s = "\"<\" expected"; break; + case 15: s = "\">\" expected"; break; + case 16: s = "\"<=\" expected"; break; + case 17: s = "\">=\" expected"; break; + case 18: s = "\"==\" expected"; break; + case 19: s = "\"!=\" expected"; break; + case 20: s = "\"+\" expected"; break; + case 21: s = "\"-\" expected"; break; + case 22: s = "\"*\" expected"; break; + case 23: s = "\"/\" expected"; break; + case 24: s = "\"#\" expected"; break; + case 25: s = "\"?\" expected"; break; + case 26: s = "\":\" expected"; break; + case 27: s = "\"time\" expected"; break; + case 28: s = "??? expected"; break; + case 29: s = "invalid Statement"; break; case 30: s = "invalid Factor"; break; default: s = "error " + n; diff -r 2bd626188d31 -r e9fc19eb3efb graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Scanner.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Scanner.java Thu Sep 05 16:36:40 2013 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Scanner.java Fri Sep 13 23:12:10 2013 +0200 @@ -21,7 +21,7 @@ * questions. */ -// The content of this file is automatically generated. DO NOT EDIT. + // The content of this file is automatically generated. DO NOT EDIT. package com.oracle.truffle.sl.parser; @@ -518,66 +518,66 @@ } // NextCh already done case 1: recEnd = pos; recKind = 1; - if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z') {AddCh(); state = 1; break;} + if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z') {AddCh(); state = 1; break;} else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;} case 2: - if (ch <= 9 || ch >= 11 && ch <= 12 || ch >= 14 && ch <= '!' || ch >= '#' && ch <= '[' || ch >= ']' && ch <= 65535) {AddCh(); state = 2; break;} - else if (ch == '"') {AddCh(); state = 3; break;} + if (ch <= 9 || ch >= 11 && ch <= 12 || ch >= 14 && ch <= '!' || ch >= '#' && ch <= '[' || ch >= ']' && ch <= 65535) {AddCh(); state = 2; break;} + else if (ch == '"') {AddCh(); state = 3; break;} else {state = 0; break;} - case 3: + case 3: {t.kind = 2; break loop;} case 4: recEnd = pos; recKind = 3; - if (ch >= '0' && ch <= '9') {AddCh(); state = 4; break;} + if (ch >= '0' && ch <= '9') {AddCh(); state = 4; break;} else {t.kind = 3; break loop;} - case 5: + case 5: {t.kind = 3; break loop;} - case 6: + case 6: {t.kind = 5; break loop;} - case 7: + case 7: {t.kind = 6; break loop;} - case 8: + case 8: {t.kind = 8; break loop;} - case 9: + case 9: {t.kind = 9; break loop;} - case 10: + case 10: {t.kind = 11; break loop;} - case 11: + case 11: {t.kind = 16; break loop;} - case 12: + case 12: {t.kind = 17; break loop;} - case 13: + case 13: {t.kind = 18; break loop;} case 14: - if (ch == '=') {AddCh(); state = 15; break;} + if (ch == '=') {AddCh(); state = 15; break;} else {state = 0; break;} - case 15: + case 15: {t.kind = 19; break loop;} - case 16: + case 16: {t.kind = 20; break loop;} - case 17: + case 17: {t.kind = 21; break loop;} - case 18: + case 18: {t.kind = 22; break loop;} - case 19: + case 19: {t.kind = 23; break loop;} - case 20: + case 20: {t.kind = 24; break loop;} - case 21: + case 21: {t.kind = 25; break loop;} - case 22: + case 22: {t.kind = 26; break loop;} case 23: recEnd = pos; recKind = 10; - if (ch == '=') {AddCh(); state = 13; break;} + if (ch == '=') {AddCh(); state = 13; break;} else {t.kind = 10; break loop;} case 24: recEnd = pos; recKind = 14; - if (ch == '=') {AddCh(); state = 11; break;} + if (ch == '=') {AddCh(); state = 11; break;} else {t.kind = 14; break loop;} case 25: recEnd = pos; recKind = 15; - if (ch == '=') {AddCh(); state = 12; break;} + if (ch == '=') {AddCh(); state = 12; break;} else {t.kind = 15; break loop;} } diff -r 2bd626188d31 -r e9fc19eb3efb mx/commands.py --- a/mx/commands.py Thu Sep 05 16:36:40 2013 +0200 +++ b/mx/commands.py Fri Sep 13 23:12:10 2013 +0200 @@ -467,18 +467,21 @@ env = os.environ.copy() env['PYTHONPATH'] = dirname(mx.__file__) - for root, _, filenames in os.walk(_graal_home): - for f in filenames: - if f.endswith('.py'): - pyfile = join(_graal_home, root, f) - mx.log('Running pylint on ' + pyfile + '...') - mx.run(['pylint', '--reports=n', '--rcfile=' + rcfile, pyfile], env=env) + versioned = subprocess.check_output(['hg', 'locate', '-f'], stderr=subprocess.STDOUT).split(os.linesep) + for f in versioned: + if f.endswith('.py'): + pyfile = f + mx.log('Running pylint on ' + pyfile + '...') + mx.run(['pylint', '--reports=n', '--rcfile=' + rcfile, pyfile], env=env) -def jdkhome(args, vm=None): - """print the JDK directory selected for the 'vm' command""" +def jdkhome(vm=None): + """return the JDK directory selected for the 'vm' command""" + build = _vmbuild if _vmSourcesAvailable else 'product' + return _jdk(build, installGraalJar=False) - build = _vmbuild if _vmSourcesAvailable else 'product' - print _jdk(build, installGraalJar=False) +def print_jdkhome(args, vm=None): + """print the JDK directory selected for the 'vm' command""" + print jdkhome(vm) def buildvars(args): """describe the variables that can be set by the -D option to the 'mx build' commmand""" @@ -1358,7 +1361,7 @@ '--title', 'Graal OpenJDK Project Documentation', '--dot-output-base', 'projects'] + args) -def mx_init(): +def mx_init(suite): commands = { 'build': [build, ''], 'buildvars': [buildvars, ''], @@ -1367,7 +1370,7 @@ 'hsdis': [hsdis, '[att]'], 'hcfdis': [hcfdis, ''], 'igv' : [igv, ''], - 'jdkhome': [jdkhome, ''], + 'jdkhome': [print_jdkhome, ''], 'pylint': [pylint, ''], 'dacapo': [dacapo, '[VM options] benchmarks...|"all" [DaCapo options]'], 'scaladacapo': [scaladacapo, '[VM options] benchmarks...|"all" [Scala DaCapo options]'], @@ -1406,7 +1409,7 @@ 'export': [export, '[-options] [zipfile]'], }) - mx._commands.update(commands) + mx.update_commands(suite, commands) def mx_post_parse_cmd_line(opts): # # TODO _minVersion check could probably be part of a Suite in mx? diff -r 2bd626188d31 -r e9fc19eb3efb mx/projects --- a/mx/projects Thu Sep 05 16:36:40 2013 +0200 +++ b/mx/projects Fri Sep 13 23:12:10 2013 +0200 @@ -28,7 +28,7 @@ library@OKRA@urls=http://cr.openjdk.java.net/~tdeneau/okra-1.2.jar distribution@GRAAL@path=graal.jar -distribution@GRAAL@dependencies=com.oracle.graal.hotspot.amd64,com.oracle.graal.truffle,com.oracle.graal.truffle.printer,com.oracle.graal.hotspot.sparc,com.oracle.graal.hotspot,com.oracle.graal.compiler.hsail +distribution@GRAAL@dependencies=com.oracle.graal.hotspot.amd64,com.oracle.graal.hotspot.ptx,com.oracle.graal.truffle,com.oracle.graal.truffle.printer,com.oracle.graal.hotspot.sparc,com.oracle.graal.hotspot,com.oracle.graal.compiler.hsail # graal.api.runtime project@com.oracle.graal.api.runtime@subDir=graal @@ -134,6 +134,15 @@ project@com.oracle.graal.hotspot.sparc@javaCompliance=1.7 project@com.oracle.graal.hotspot.sparc@workingSets=Graal,HotSpot,SPARC +# graal.hotspot.ptx +project@com.oracle.graal.hotspot.ptx@subDir=graal +project@com.oracle.graal.hotspot.ptx@sourceDirs=src +project@com.oracle.graal.hotspot.ptx@dependencies=com.oracle.graal.hotspot,com.oracle.graal.ptx +project@com.oracle.graal.hotspot.ptx@checkstyle=com.oracle.graal.graph +project@com.oracle.graal.hotspot.ptx@annotationProcessors=com.oracle.graal.service.processor +project@com.oracle.graal.hotspot.ptx@javaCompliance=1.7 +project@com.oracle.graal.hotspot.ptx@workingSets=Graal,HotSpot,PTX + # graal.hotspot.server project@com.oracle.graal.hotspot.server@subDir=graal project@com.oracle.graal.hotspot.server@sourceDirs=src diff -r 2bd626188d31 -r e9fc19eb3efb mx/sanitycheck.py --- a/mx/sanitycheck.py Thu Sep 05 16:36:40 2013 +0200 +++ b/mx/sanitycheck.py Fri Sep 13 23:12:10 2013 +0200 @@ -77,7 +77,8 @@ 'sunflow': [ 'fastdebug', 'debug'], 'tomcat': ['product', 'fastdebug', 'debug'], 'tradebeans': ['product', 'fastdebug', 'debug'], - 'tradesoap': ['product'], + # tradesoap is too unreliable for the gate, often crashing with "java.net.BindException: Address already in use" + 'tradesoap': [ ], 'xalan': ['product', 'fastdebug', 'debug'], } diff -r 2bd626188d31 -r e9fc19eb3efb mxtool/mx.py --- a/mxtool/mx.py Thu Sep 05 16:36:40 2013 +0200 +++ b/mxtool/mx.py Fri Sep 13 23:12:10 2013 +0200 @@ -37,7 +37,11 @@ containing one or more projects. It's not coincidental that this closely matches the layout of one or more projects in a Mercurial repository. The configuration information for a suite lives in an 'mx' sub-directory -at the top level of the suite. +at the top level of the suite. A suite is given a name by a 'suite=name' +property in the 'mx/projects' file (if omitted the name is suite directory). +An 'mx' subdirectory can be named as plain 'mx' or 'mxbasename', where +'basename' is the os.path.basename of the suite directory. +The latter is useful to avoid clashes in IDE project names. When launched, mx treats the current working directory as a suite. This is the primary suite. All other suites are called included suites. @@ -137,7 +141,7 @@ Property values can use environment variables with Bash syntax (e.g. ${HOME}). """ -import sys, os, errno, time, subprocess, shlex, types, urllib2, contextlib, StringIO, zipfile, signal, xml.sax.saxutils, tempfile +import sys, os, errno, time, subprocess, shlex, types, urllib2, contextlib, StringIO, zipfile, signal, xml.sax.saxutils, tempfile, fnmatch import textwrap import xml.parsers.expat import shutil, re, xml.dom.minidom @@ -435,6 +439,23 @@ if url.endswith('/') != self.path.endswith(os.sep): abort('Path for dependency directory must have a URL ending with "/": path=' + self.path + ' url=' + url) + def __eq__(self, other): + if isinstance(other, Library): + if len(self.urls) == 0: + return self.path == other.path + else: + return self.urls == other.urls + else: + return NotImplemented + + + def __ne__(self, other): + result = self.__eq__(other) + if result is NotImplemented: + return result + return not result + + def get_path(self, resolve): path = self.path if not isabs(path): @@ -468,15 +489,15 @@ return deps class Suite: - def __init__(self, d, primary): + def __init__(self, d, mxDir, primary): self.dir = d + self.mxDir = mxDir self.projects = [] self.libs = [] self.dists = [] self.includes = [] self.commands = None self.primary = primary - mxDir = join(d, 'mx') self._load_env(mxDir) self._load_commands(mxDir) self._load_includes(mxDir) @@ -590,7 +611,7 @@ if hasattr(mod, 'mx_post_parse_cmd_line'): self.mx_post_parse_cmd_line = mod.mx_post_parse_cmd_line - mod.mx_init() + mod.mx_init(self) self.commands = mod def _load_includes(self, mxDir): @@ -600,7 +621,7 @@ for line in f: include = expandvars_in_property(line.strip()) self.includes.append(include) - _loadSuite(include, False) + _loadSuite(os.path.abspath(include), False) def _load_env(self, mxDir): e = join(mxDir, 'env') @@ -616,8 +637,7 @@ key, value = line.split('=', 1) os.environ[key.strip()] = expandvars_in_property(value.strip()) def _post_init(self, opts): - mxDir = join(self.dir, 'mx') - self._load_projects(mxDir) + self._load_projects(self.mxDir) for p in self.projects: existing = _projects.get(p.name) if existing is not None: @@ -626,8 +646,9 @@ _projects[p.name] = p for l in self.libs: existing = _libs.get(l.name) - if existing is not None: - abort('cannot redefine library ' + l.name) + # Check that suites that define same library are consistent + if existing is not None and existing != l: + abort('inconsistent library redefinition of ' + l.name + ' in ' + existing.suite.dir + ' and ' + l.suite.dir) _libs[l.name] = l for d in self.dists: existing = _dists.get(d.name) @@ -729,12 +750,25 @@ abort('Unknown operating system ' + sys.platform) def _loadSuite(d, primary=False): - mxDir = join(d, 'mx') - if not exists(mxDir) or not isdir(mxDir): + """ + Load a suite from the 'mx' or 'mxbbb' subdirectory of d, where 'bbb' is basename of d + """ + mxDefaultDir = join(d, 'mx') + name = os.path.basename(d) + mxTaggedDir = mxDefaultDir + name + mxDir = None + if exists(mxTaggedDir) and isdir(mxTaggedDir): + mxDir = mxTaggedDir + else: + if exists(mxDefaultDir) and isdir(mxDefaultDir): + mxDir = mxDefaultDir + + + if mxDir is None: return None if len([s for s in _suites.itervalues() if s.dir == d]) == 0: - s = Suite(d, primary) - _suites[s.name] = s + s = Suite(d, mxDir, primary) + _suites[name] = s return s def suites(): @@ -879,7 +913,7 @@ """ deps = [] if projectNames is None: - projects = _projects.values() + projects = opt_limit_to_suite(_projects.values()) else: projects = [project(name) for name in projectNames] @@ -887,6 +921,17 @@ p.all_deps(deps, includeLibs=includeLibs, includeAnnotationProcessors=includeAnnotationProcessors) return deps +def opt_limit_to_suite(projects): + if _opts.specific_suite is None: + return projects + else: + result = [] + for p in projects: + s = p.suite + if s.name == _opts.specific_suite: + result.append(p) + return result + def _handle_missing_java_home(): if not sys.stdout.isatty(): abort('Could not find bootstrap JDK. Use --java-home option or ensure JAVA_HOME environment variable is set.') @@ -936,7 +981,8 @@ def __init__(self): self.java_initialized = False - ArgumentParser.__init__(self, prog='mx') + # this doesn't resolve the right way, but can't figure out how to override _handle_conflict_resolve in _ActionsContainer + ArgumentParser.__init__(self, prog='mx', conflict_handler='resolve') self.add_argument('-v', action='store_true', dest='verbose', help='enable verbose output') self.add_argument('-V', action='store_true', dest='very_verbose', help='enable very verbose output') @@ -950,6 +996,7 @@ self.add_argument('--user-home', help='users home directory', metavar='', default=os.path.expanduser('~')) self.add_argument('--java-home', help='bootstrap JDK installation directory (must be JDK 6 or later)', metavar='') self.add_argument('--ignore-project', action='append', dest='ignored_projects', help='name of project to ignore', metavar='', default=[]) + self.add_argument('--suite', dest='specific_suite', help='limit command to given suite', default=None) if get_os() != 'windows': # Time outs are (currently) implemented with Unix specific functionality self.add_argument('--timeout', help='timeout (in seconds) for command', type=int, default=0, metavar='') @@ -987,6 +1034,9 @@ commandAndArgs = opts.__dict__.pop('commandAndArgs') return opts, commandAndArgs + def _handle_conflict_resolve(self, action, conflicting_actions): + self._handle_conflict_error(action, conflicting_actions) + def _format_commands(): msg = '\navailable commands:\n\n' for cmd in sorted(_commands.iterkeys()): @@ -1997,7 +2047,7 @@ logv('[no Java sources in {0} - skipping]'.format(sourceDir)) continue - timestampFile = join(p.suite.dir, 'mx', 'checkstyle-timestamps', sourceDir[len(p.suite.dir) + 1:].replace(os.sep, '_') + '.timestamp') + timestampFile = join(p.suite.mxDir, 'checkstyle-timestamps', sourceDir[len(p.suite.dir) + 1:].replace(os.sep, '_') + '.timestamp') if not exists(dirname(timestampFile)): os.makedirs(dirname(timestampFile)) mustCheck = False @@ -2083,10 +2133,10 @@ elif name == 'error': errors.append('{}:{}: {}'.format(source[0], attrs['line'], attrs['message'])) - p = xml.parsers.expat.ParserCreate() - p.StartElementHandler = start_element + xp = xml.parsers.expat.ParserCreate() + xp.StartElementHandler = start_element with open(auditfileName) as fp: - p.ParseFile(fp) + xp.ParseFile(fp) if len(errors) != 0: map(log, errors) totalErrors = totalErrors + len(errors) @@ -2356,20 +2406,22 @@ out.element('classpathentry', {'combineaccessrules' : 'false', 'exported' : 'true', 'kind' : 'src', 'path' : '/' + getattr(dep, 'eclipse.project')}) else: path = dep.path - if dep.mustExist: - dep.get_path(resolve=True) - if not isabs(path): - # Relative paths for "lib" class path entries have various semantics depending on the Eclipse - # version being used (e.g. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737) so it's - # safest to simply use absolute paths. - path = join(suite.dir, path) - - attributes = {'exported' : 'true', 'kind' : 'lib', 'path' : path} - - sourcePath = dep.get_source_path(resolve=True) - if sourcePath is not None: - attributes['sourcepath'] = sourcePath - out.element('classpathentry', attributes) + dep.get_path(resolve=True) + if not exists(path) and not dep.mustExist: + continue + + if not isabs(path): + # Relative paths for "lib" class path entries have various semantics depending on the Eclipse + # version being used (e.g. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737) so it's + # safest to simply use absolute paths. + path = join(p.suite.dir, path) + + attributes = {'exported' : 'true', 'kind' : 'lib', 'path' : path} + + sourcePath = dep.get_source_path(resolve=True) + if sourcePath is not None: + attributes['sourcepath'] = sourcePath + out.element('classpathentry', attributes) else: out.element('classpathentry', {'combineaccessrules' : 'false', 'exported' : 'true', 'kind' : 'src', 'path' : '/' + dep.name}) @@ -2454,7 +2506,7 @@ if not exists(settingsDir): os.mkdir(settingsDir) - eclipseSettingsDir = join(suite.dir, 'mx', 'eclipse-settings') + eclipseSettingsDir = join(p.suite.mxDir, 'eclipse-settings') if exists(eclipseSettingsDir): for name in os.listdir(eclipseSettingsDir): if name == "org.eclipse.jdt.apt.core.prefs" and not len(p.annotation_processors()) > 0: @@ -2482,7 +2534,7 @@ # Relative paths for "lib" class path entries have various semantics depending on the Eclipse # version being used (e.g. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737) so it's # safest to simply use absolute paths. - path = join(suite.dir, path) + path = join(p.suite.dir, path) out.element('factorypathentry', {'kind' : 'EXTJAR', 'id' : path, 'enabled' : 'true', 'runInBatchMode' : 'false'}) else: out.element('factorypathentry', {'kind' : 'WKSPJAR', 'id' : '/' + dep.name + '/' + dep.name + '.jar', 'enabled' : 'true', 'runInBatchMode' : 'false'}) @@ -2558,12 +2610,14 @@ # identify the location where to look for workingsets.xml wsfilename = 'workingsets.xml' + wsloc = '.metadata/.plugins/org.eclipse.ui.workbench' wsroot = suite.dir if os.environ.has_key('WORKSPACE'): wsroot = os.environ['WORKSPACE'] - wsdir = join(wsroot, '.metadata/.plugins/org.eclipse.ui.workbench') + wsdir = join(wsroot, wsloc) if not exists(wsdir): wsdir = wsroot + log('Could not find Eclipse metadata directory. Please place ' + wsfilename + ' in ' + wsloc + ' manually.') wspath = join(wsdir, wsfilename) # gather working set info from project data @@ -2933,7 +2987,7 @@ shutil.rmtree(currentDir) log('Deleted ' + currentDir) -def javadoc(args, parser=None, docDir='javadoc', includeDeps=True): +def javadoc(args, parser=None, docDir='javadoc', includeDeps=True, stdDoclet=True): """generate javadoc for some/all Java projects""" parser = ArgumentParser(prog='mx javadoc') if parser is None else parser @@ -3035,10 +3089,14 @@ nowarnAPI = [] if not args.warnAPI: nowarnAPI.append('-XDignore.symbol.file') + + # windowTitle onloy applies to the standard doclet processor + windowTitle = [] + if stdDoclet: + windowTitle = ['-windowtitle', p.name + ' javadoc'] try: log('Generating {2} for {0} in {1}'.format(p.name, out, docDir)) run([java().javadoc, memory, - '-windowtitle', p.name + ' javadoc', '-XDignore.symbol.file', '-classpath', cp, '-quiet', @@ -3048,6 +3106,7 @@ links + extraArgs + nowarnAPI + + windowTitle + list(pkgs)) log('Generated {2} for {0} in {1}'.format(p.name, out, docDir)) finally: @@ -3436,6 +3495,14 @@ assert _argParser is not None _argParser.add_argument(*args, **kwargs) +def update_commands(suite, new_commands): + for key, value in new_commands.iteritems(): + if _commands.has_key(key) and not suite.primary: + pass + # print("WARNING: attempt to redefine command '" + key + "' in suite " + suite.dir) + else: + _commands[key] = value + # Table of commands in alphabetical order. # Keys are command names, value are lists: [, , ...] # If any of the format args are instances of Callable, then they are called with an 'env' are before being @@ -3467,9 +3534,12 @@ def _findPrimarySuite(): def is_suite_dir(d): - mxDir = join(d, 'mx') - if exists(mxDir) and isdir(mxDir) and exists(join(mxDir, 'projects')): - return dirname(mxDir) + for f in os.listdir(d): + if fnmatch.fnmatch(f, 'mx*'): + mxDir = join(d, f) + if exists(mxDir) and isdir(mxDir) and exists(join(mxDir, 'projects')): + return dirname(mxDir) + # try current working directory first if is_suite_dir(os.getcwd()): diff -r 2bd626188d31 -r e9fc19eb3efb src/gpu/ptx/vm/gpu_ptx.cpp --- a/src/gpu/ptx/vm/gpu_ptx.cpp Thu Sep 05 16:36:40 2013 +0200 +++ b/src/gpu/ptx/vm/gpu_ptx.cpp Fri Sep 13 23:12:10 2013 +0200 @@ -29,7 +29,7 @@ #include "utilities/ostream.hpp" #include "memory/allocation.hpp" #include "memory/allocation.inline.hpp" -#include "kernelArguments.hpp" +#include "ptxKernelArguments.hpp" void * gpu::Ptx::_device_context; int gpu::Ptx::_cu_device = 0; @@ -50,36 +50,6 @@ gpu::Ptx::cuda_cu_memcpy_dtoh_func_t gpu::Ptx::_cuda_cu_memcpy_dtoh; gpu::Ptx::cuda_cu_memfree_func_t gpu::Ptx::_cuda_cu_memfree; -void gpu::probe_linkage() { -#if defined(__APPLE__) || defined(LINUX) - set_gpu_linkage(gpu::Ptx::probe_linkage()); -#else - set_gpu_linkage(false); -#endif -} - -void gpu::initialize_gpu() { - if (gpu::has_gpu_linkage()) { - set_initialized(gpu::Ptx::initialize_gpu()); - } -} - -void * gpu::generate_kernel(unsigned char *code, int code_len, const char *name) { - if (gpu::has_gpu_linkage()) { - return (gpu::Ptx::generate_kernel(code, code_len, name)); - } else { - return NULL; - } -} - -bool gpu::execute_kernel(address kernel, PTXKernelArguments & ptxka, JavaValue& ret) { - if (gpu::has_gpu_linkage()) { - return (gpu::Ptx::execute_kernel(kernel, ptxka, ret)); - } else { - return false; - } -} - bool gpu::Ptx::initialize_gpu() { /* Initialize CUDA driver API */ diff -r 2bd626188d31 -r e9fc19eb3efb src/gpu/ptx/vm/kernelArguments.cpp --- a/src/gpu/ptx/vm/kernelArguments.cpp Thu Sep 05 16:36:40 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,130 +0,0 @@ -/* - * 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. - * - */ - -#include "precompiled.hpp" -#include "kernelArguments.hpp" -#include "runtime/javaCalls.hpp" - -gpu::Ptx::cuda_cu_memalloc_func_t gpu::Ptx::_cuda_cu_memalloc; -gpu::Ptx::cuda_cu_memcpy_htod_func_t gpu::Ptx::_cuda_cu_memcpy_htod; - -// Get next java argument -oop PTXKernelArguments::next_arg(BasicType expectedType) { - assert(_index < _args->length(), "out of bounds"); - oop arg=((objArrayOop) (_args))->obj_at(_index++); - assert(expectedType == T_OBJECT || java_lang_boxing_object::is_instance(arg, expectedType), "arg type mismatch"); - return arg; -} - -void PTXKernelArguments::do_int() { - // If the parameter is a return value, - if (is_return_type()) { - // Allocate device memory for T_INT return value pointer on device. Size in bytes - int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_INT_BYTE_SIZE); - if (status != GRAAL_CUDA_SUCCESS) { - tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); - _success = false; - return; - } - // Push _return_value_ptr to _kernelBuffer - *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr; - _bufferOffset += sizeof(_return_value_ptr); - } - else { - // Get the next java argument and its value which should be a T_INT - oop arg = next_arg(T_INT); - // Copy the java argument value to kernelArgBuffer - jvalue intval; - if (java_lang_boxing_object::get_value(arg, &intval) != T_INT) { - tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_INT"); - _success = false; - return; - } - *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = intval.i; - _bufferOffset += sizeof(intval.i); - } - return; -} - -void PTXKernelArguments::do_long() { - // If the parameter is a return value, - if (is_return_type()) { - // Allocate device memory for T_LONG return value pointer on device. Size in bytes - int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_LONG_BYTE_SIZE); - if (status != GRAAL_CUDA_SUCCESS) { - tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); - _success = false; - return; - } - // Push _return_value_ptr to _kernelBuffer - *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr; - _bufferOffset += sizeof(_return_value_ptr); - } - else { - // Get the next java argument and its value which should be a T_LONG - oop arg = next_arg(T_LONG); - // Copy the java argument value to kernelArgBuffer - jvalue val; - if (java_lang_boxing_object::get_value(arg, &val) != T_LONG) { - tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_LONG"); - _success = false; - return; - } - *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = val.j; - _bufferOffset += sizeof(val.j); - } - return; -} - -void PTXKernelArguments::do_byte() { - // If the parameter is a return value, - if (is_return_type()) { - // Allocate device memory for T_BYTE return value pointer on device. Size in bytes - int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_BYTE_SIZE); - if (status != GRAAL_CUDA_SUCCESS) { - tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); - _success = false; - return; - } - // Push _return_value_ptr to _kernelBuffer - *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr; - _bufferOffset += sizeof(_return_value_ptr); - } - else { - // Get the next java argument and its value which should be a T_BYTE - oop arg = next_arg(T_BYTE); - // Copy the java argument value to kernelArgBuffer - jvalue val; - if (java_lang_boxing_object::get_value(arg, &val) != T_BYTE) { - tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_BYTE"); - _success = false; - return; - } - *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = val.b; - _bufferOffset += sizeof(val.b); - } - return; -} - -// TODO implement other do_* diff -r 2bd626188d31 -r e9fc19eb3efb src/gpu/ptx/vm/kernelArguments.hpp --- a/src/gpu/ptx/vm/kernelArguments.hpp Thu Sep 05 16:36:40 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,129 +0,0 @@ -/* - * 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. - * - */ - -#ifndef KERNEL_ARGUMENTS_PTX_HPP -#define KERNEL_ARGUMENTS_PTX_HPP - -#include "runtime/gpu.hpp" -#include "runtime/signature.hpp" - -#define T_BYTE_SIZE 1 -#define T_INT_BYTE_SIZE 4 -#define T_LONG_BYTE_SIZE 8 - -class PTXKernelArguments : public SignatureIterator { -public: - // Buffer holding CUdeviceptr values that represent the kernel arguments - char _kernelArgBuffer[1024]; - // Current offset into _kernelArgBuffer - size_t _bufferOffset; - gpu::Ptx::CUdeviceptr _return_value_ptr; -private: - // Array of java argument oops - arrayOop _args; - // Current index into _args - int _index; - // Flag to indicate successful creation of kernel argument buffer - bool _success; - // Get next java argument - oop next_arg(BasicType expectedType); - - public: - PTXKernelArguments(Symbol* signature, arrayOop args, bool is_static) : SignatureIterator(signature) { - this->_return_type = T_ILLEGAL; - _index = 0; - _args = args; - _success = true; - _bufferOffset = 0; - _return_value_ptr = 0; - if (!is_static) { - // TODO : Create a device argument for receiver object and add it to _kernelBuffer - tty->print_cr("{CUDA] ****** TODO: Support for execution of non-static java methods not implemented yet."); - } - // Iterate over the entire signature - iterate(); - assert((_success && (_index == args->length())), "arg count mismatch with signature"); - } - - inline char* device_argument_buffer() { - return _kernelArgBuffer; - } - - inline size_t device_argument_buffer_size() { - return _bufferOffset; - } - - // Get the return oop value - oop get_return_oop(); - - // get device return value ptr - gpu::Ptx::CUdeviceptr get_return_value_ptr() { - return _return_value_ptr; - } - - - void do_byte(); - void do_int(); - void do_long(); - - inline void do_bool() { - /* TODO : To be implemented */ - guarantee(false, "NYI"); - } - inline void do_char() { - /* TODO : To be implemented */ - guarantee(false, "NYI"); - } - inline void do_short() { - /* TODO : To be implemented */ - guarantee(false, "NYI"); - } - inline void do_float() { - /* TODO : To be implemented */ - guarantee(false, "NYI"); - } - inline void do_double() { - /* TODO : To be implemented */ - guarantee(false, "NYI"); - } - - inline void do_object() { - /* TODO : To be implemented */ - guarantee(false, "NYI"); - } - inline void do_object(int begin, int end) { - /* TODO : To be implemented */ - guarantee(false, "NYI"); - } - inline void do_array(int begin, int end) { - /* TODO : To be implemented */ - guarantee(false, "NYI"); - } - inline void do_void() { - /* TODO : To be implemented */ - guarantee(false, "NYI"); - } -}; - -#endif // KERNEL_ARGUMENTS_HPP diff -r 2bd626188d31 -r e9fc19eb3efb src/gpu/ptx/vm/ptxKernelArguments.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gpu/ptx/vm/ptxKernelArguments.cpp Fri Sep 13 23:12:10 2013 +0200 @@ -0,0 +1,130 @@ +/* + * 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. + * + */ + +#include "precompiled.hpp" +#include "ptxKernelArguments.hpp" +#include "runtime/javaCalls.hpp" + +gpu::Ptx::cuda_cu_memalloc_func_t gpu::Ptx::_cuda_cu_memalloc; +gpu::Ptx::cuda_cu_memcpy_htod_func_t gpu::Ptx::_cuda_cu_memcpy_htod; + +// Get next java argument +oop PTXKernelArguments::next_arg(BasicType expectedType) { + assert(_index < _args->length(), "out of bounds"); + oop arg=((objArrayOop) (_args))->obj_at(_index++); + assert(expectedType == T_OBJECT || java_lang_boxing_object::is_instance(arg, expectedType), "arg type mismatch"); + return arg; +} + +void PTXKernelArguments::do_int() { + // If the parameter is a return value, + if (is_return_type()) { + // Allocate device memory for T_INT return value pointer on device. Size in bytes + int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_INT_BYTE_SIZE); + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); + _success = false; + return; + } + // Push _return_value_ptr to _kernelBuffer + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr; + _bufferOffset += sizeof(_return_value_ptr); + } + else { + // Get the next java argument and its value which should be a T_INT + oop arg = next_arg(T_INT); + // Copy the java argument value to kernelArgBuffer + jvalue intval; + if (java_lang_boxing_object::get_value(arg, &intval) != T_INT) { + tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_INT"); + _success = false; + return; + } + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = intval.i; + _bufferOffset += sizeof(intval.i); + } + return; +} + +void PTXKernelArguments::do_long() { + // If the parameter is a return value, + if (is_return_type()) { + // Allocate device memory for T_LONG return value pointer on device. Size in bytes + int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_LONG_BYTE_SIZE); + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); + _success = false; + return; + } + // Push _return_value_ptr to _kernelBuffer + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr; + _bufferOffset += sizeof(_return_value_ptr); + } + else { + // Get the next java argument and its value which should be a T_LONG + oop arg = next_arg(T_LONG); + // Copy the java argument value to kernelArgBuffer + jvalue val; + if (java_lang_boxing_object::get_value(arg, &val) != T_LONG) { + tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_LONG"); + _success = false; + return; + } + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = val.j; + _bufferOffset += sizeof(val.j); + } + return; +} + +void PTXKernelArguments::do_byte() { + // If the parameter is a return value, + if (is_return_type()) { + // Allocate device memory for T_BYTE return value pointer on device. Size in bytes + int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_BYTE_SIZE); + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); + _success = false; + return; + } + // Push _return_value_ptr to _kernelBuffer + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr; + _bufferOffset += sizeof(_return_value_ptr); + } + else { + // Get the next java argument and its value which should be a T_BYTE + oop arg = next_arg(T_BYTE); + // Copy the java argument value to kernelArgBuffer + jvalue val; + if (java_lang_boxing_object::get_value(arg, &val) != T_BYTE) { + tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_BYTE"); + _success = false; + return; + } + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = val.b; + _bufferOffset += sizeof(val.b); + } + return; +} + +// TODO implement other do_* diff -r 2bd626188d31 -r e9fc19eb3efb src/gpu/ptx/vm/ptxKernelArguments.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gpu/ptx/vm/ptxKernelArguments.hpp Fri Sep 13 23:12:10 2013 +0200 @@ -0,0 +1,129 @@ +/* + * 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. + * + */ + +#ifndef KERNEL_ARGUMENTS_PTX_HPP +#define KERNEL_ARGUMENTS_PTX_HPP + +#include "runtime/gpu.hpp" +#include "runtime/signature.hpp" + +#define T_BYTE_SIZE 1 +#define T_INT_BYTE_SIZE 4 +#define T_LONG_BYTE_SIZE 8 + +class PTXKernelArguments : public SignatureIterator { +public: + // Buffer holding CUdeviceptr values that represent the kernel arguments + char _kernelArgBuffer[1024]; + // Current offset into _kernelArgBuffer + size_t _bufferOffset; + gpu::Ptx::CUdeviceptr _return_value_ptr; +private: + // Array of java argument oops + arrayOop _args; + // Current index into _args + int _index; + // Flag to indicate successful creation of kernel argument buffer + bool _success; + // Get next java argument + oop next_arg(BasicType expectedType); + + public: + PTXKernelArguments(Symbol* signature, arrayOop args, bool is_static) : SignatureIterator(signature) { + this->_return_type = T_ILLEGAL; + _index = 0; + _args = args; + _success = true; + _bufferOffset = 0; + _return_value_ptr = 0; + if (!is_static) { + // TODO : Create a device argument for receiver object and add it to _kernelBuffer + tty->print_cr("{CUDA] ****** TODO: Support for execution of non-static java methods not implemented yet."); + } + // Iterate over the entire signature + iterate(); + assert((_success && (_index == args->length())), "arg count mismatch with signature"); + } + + inline char* device_argument_buffer() { + return _kernelArgBuffer; + } + + inline size_t device_argument_buffer_size() { + return _bufferOffset; + } + + // Get the return oop value + oop get_return_oop(); + + // get device return value ptr + gpu::Ptx::CUdeviceptr get_return_value_ptr() { + return _return_value_ptr; + } + + + void do_byte(); + void do_int(); + void do_long(); + + inline void do_bool() { + /* TODO : To be implemented */ + guarantee(false, "NYI"); + } + inline void do_char() { + /* TODO : To be implemented */ + guarantee(false, "NYI"); + } + inline void do_short() { + /* TODO : To be implemented */ + guarantee(false, "NYI"); + } + inline void do_float() { + /* TODO : To be implemented */ + guarantee(false, "NYI"); + } + inline void do_double() { + /* TODO : To be implemented */ + guarantee(false, "NYI"); + } + + inline void do_object() { + /* TODO : To be implemented */ + guarantee(false, "NYI"); + } + inline void do_object(int begin, int end) { + /* TODO : To be implemented */ + guarantee(false, "NYI"); + } + inline void do_array(int begin, int end) { + /* TODO : To be implemented */ + guarantee(false, "NYI"); + } + inline void do_void() { + /* TODO : To be implemented */ + guarantee(false, "NYI"); + } +}; + +#endif // KERNEL_ARGUMENTS_HPP diff -r 2bd626188d31 -r e9fc19eb3efb src/os_gpu/bsd_ptx/vm/gpu_bsd.cpp --- a/src/os_gpu/bsd_ptx/vm/gpu_bsd.cpp Thu Sep 05 16:36:40 2013 +0200 +++ b/src/os_gpu/bsd_ptx/vm/gpu_bsd.cpp Fri Sep 13 23:12:10 2013 +0200 @@ -33,6 +33,7 @@ * a better detection solution for NVIDA PTX and AMD HSAIL. */ set_available(true); + set_target_il_type(gpu::PTX); if (TraceGPUInteraction) { tty->print_cr("gpu_bsd::probe_gpu(APPLE): %d", gpu::is_available()); } diff -r 2bd626188d31 -r e9fc19eb3efb src/os_gpu/linux_ptx/vm/gpu_linux.cpp --- a/src/os_gpu/linux_ptx/vm/gpu_linux.cpp Thu Sep 05 16:36:40 2013 +0200 +++ b/src/os_gpu/linux_ptx/vm/gpu_linux.cpp Fri Sep 13 23:12:10 2013 +0200 @@ -39,32 +39,40 @@ */ static unsigned int nvidia_vendor_id = 0x10de; +static unsigned int amd_vendor_id = 0x1002; bool gpu::Linux::probe_gpu() { /* - * Open /proc/bus/pci/devices to look for the first CUDA enabled - * device. For now, finding the first CUDA device. Will need to - * revisit this to support execution on multiple CUDA devices if - * they exist. + * Open /proc/bus/pci/devices to look for the first GPU device. For + * now, we will just find the first GPU device. Will need to revisit + * this to support execution on multiple GPU devices, if they exist. */ FILE *pci_devices = fopen("/proc/bus/pci/devices", "r"); char contents[4096]; unsigned int bus_num_devfn_ign; unsigned int vendor; unsigned int device; - bool cuda_device_exists = false; + bool gpu_device_exists = false; if (pci_devices == NULL) { tty->print_cr("*** Failed to open /proc/bus/pci/devices"); - return cuda_device_exists; + return gpu_device_exists; } while (fgets(contents, sizeof(contents)-1, pci_devices)) { sscanf(contents, "%04x%04x%04x", &bus_num_devfn_ign, &vendor, &device); - /* Break after finding the first CUDA device. */ + /* Break after finding the first GPU device. */ if (vendor == nvidia_vendor_id) { - cuda_device_exists = true; + gpu_device_exists = true; + set_target_il_type(gpu::PTX); if (TraceGPUInteraction) { - tty->print_cr("Found supported nVidia CUDA device vendor : 0x%04x device 0x%04x", vendor, device); + tty->print_cr("Found supported nVidia GPU device vendor : 0x%04x device 0x%04x", vendor, device); + } + break; + } else if (vendor == amd_vendor_id) { + gpu_device_exists = true; + set_target_il_type(gpu::HSAIL); + if (TraceGPUInteraction) { + tty->print_cr("Found supported AMD GPU device vendor : 0x%04x device 0x%04x", vendor, device); } break; } @@ -73,5 +81,5 @@ // Close file pointer. fclose(pci_devices); - return cuda_device_exists; + return gpu_device_exists; } diff -r 2bd626188d31 -r e9fc19eb3efb src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Thu Sep 05 16:36:40 2013 +0200 +++ b/src/share/vm/classfile/vmSymbols.hpp Fri Sep 13 23:12:10 2013 +0200 @@ -311,6 +311,7 @@ template(com_oracle_graal_hotspot_meta_HotSpotResolvedObjectType, "com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType") \ template(com_oracle_graal_hotspot_meta_HotSpotMonitorValue, "com/oracle/graal/hotspot/meta/HotSpotMonitorValue") \ template(com_oracle_graal_hotspot_debug_LocalImpl, "com/oracle/graal/hotspot/debug/LocalImpl") \ + template(com_oracle_graal_hotspot_ptx_PTXHotSpotGraalRuntime, "com/oracle/graal/hotspot/ptx/PTXHotSpotGraalRuntime")\ AMD64_ONLY(template(com_oracle_graal_hotspot_amd64_AMD64HotSpotGraalRuntime,"com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime"))\ SPARC_ONLY(template(com_oracle_graal_hotspot_sparc_SPARCHotSpotGraalRuntime,"com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime"))\ /* graal.api.meta */ \ @@ -356,6 +357,7 @@ template(compileMethod_signature, "(JLcom/oracle/graal/hotspot/meta/HotSpotResolvedObjectType;IZ)V") \ template(setOption_name, "setOption") \ template(setOption_signature, "(Ljava/lang/String;)Z") \ + template(finalizeOptions_name, "finalizeOptions") \ template(createUnresolvedJavaMethod_name, "createUnresolvedJavaMethod") \ template(createUnresolvedJavaMethod_signature, "(Ljava/lang/String;Ljava/lang/String;Lcom/oracle/graal/api/meta/JavaType;)Lcom/oracle/graal/api/meta/JavaMethod;") \ template(createSignature_name, "createSignature") \ diff -r 2bd626188d31 -r e9fc19eb3efb src/share/vm/graal/graalCompiler.cpp --- a/src/share/vm/graal/graalCompiler.cpp Thu Sep 05 16:36:40 2013 +0200 +++ b/src/share/vm/graal/graalCompiler.cpp Fri Sep 13 23:12:10 2013 +0200 @@ -95,6 +95,8 @@ vm_abort(false); } } + VMToCompiler::finalizeOptions(CITime); + if (UseCompiler) { VMToCompiler::startCompiler(BootstrapGraal); _initialized = true; diff -r 2bd626188d31 -r e9fc19eb3efb src/share/vm/graal/graalCompilerToGPU.cpp --- a/src/share/vm/graal/graalCompilerToGPU.cpp Thu Sep 05 16:36:40 2013 +0200 +++ b/src/share/vm/graal/graalCompilerToGPU.cpp Fri Sep 13 23:12:10 2013 +0200 @@ -28,7 +28,7 @@ #include "graal/graalJavaAccess.hpp" #include "runtime/gpu.hpp" #include "runtime/javaCalls.hpp" -# include "ptx/vm/kernelArguments.hpp" +# include "ptx/vm/ptxKernelArguments.hpp" // Entry to native method implementation that transitions current thread to '_thread_in_vm'. #define C2V_VMENTRY(result_type, name, signature) \ diff -r 2bd626188d31 -r e9fc19eb3efb src/share/vm/graal/graalVMToCompiler.cpp --- a/src/share/vm/graal/graalVMToCompiler.cpp Thu Sep 05 16:36:40 2013 +0200 +++ b/src/share/vm/graal/graalVMToCompiler.cpp Fri Sep 13 23:12:10 2013 +0200 @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "classfile/systemDictionary.hpp" #include "graal/graalVMToCompiler.hpp" +#include "runtime/gpu.hpp" // this is a *global* handle jobject VMToCompiler::_graalRuntimePermObject = NULL; @@ -60,7 +61,18 @@ Handle VMToCompiler::graalRuntime() { if (JNIHandles::resolve(_graalRuntimePermObject) == NULL) { #ifdef AMD64 - Symbol* name = vmSymbols::com_oracle_graal_hotspot_amd64_AMD64HotSpotGraalRuntime(); + Symbol* name = NULL; + if (UseGPU) { + // Set name to PTXHotSpotRuntime if nVidia GPU was detected. + if ((gpu::get_target_il_type() == gpu::PTX) && + gpu::is_available() && gpu::has_gpu_linkage()) { + name = vmSymbols::com_oracle_graal_hotspot_ptx_PTXHotSpotGraalRuntime(); + } + // Set name to corresponding runtime classname for other + // supported GPU runtimes, here. + } else { + name = vmSymbols::com_oracle_graal_hotspot_amd64_AMD64HotSpotGraalRuntime(); + } #endif #ifdef SPARC Symbol* name = vmSymbols::com_oracle_graal_hotspot_sparc_SPARCHotSpotGraalRuntime(); @@ -90,23 +102,33 @@ } void VMToCompiler::initOptions() { - KlassHandle compilerKlass = loadClass(vmSymbols::com_oracle_graal_hotspot_HotSpotOptions()); + KlassHandle optionsKlass = loadClass(vmSymbols::com_oracle_graal_hotspot_HotSpotOptions()); Thread* THREAD = Thread::current(); - compilerKlass->initialize(THREAD); + optionsKlass->initialize(THREAD); check_pending_exception("Error while calling initOptions"); } jboolean VMToCompiler::setOption(Handle option) { assert(!option.is_null(), ""); - KlassHandle compilerKlass = loadClass(vmSymbols::com_oracle_graal_hotspot_HotSpotOptions()); + KlassHandle optionsKlass = loadClass(vmSymbols::com_oracle_graal_hotspot_HotSpotOptions()); Thread* THREAD = Thread::current(); JavaValue result(T_BOOLEAN); - JavaCalls::call_static(&result, compilerKlass, vmSymbols::setOption_name(), vmSymbols::setOption_signature(), option, THREAD); + JavaCalls::call_static(&result, optionsKlass, vmSymbols::setOption_name(), vmSymbols::setOption_signature(), option, THREAD); check_pending_exception("Error while calling setOption"); return result.get_jboolean(); } +void VMToCompiler::finalizeOptions(jboolean ciTime) { + KlassHandle optionsKlass = loadClass(vmSymbols::com_oracle_graal_hotspot_HotSpotOptions()); + Thread* THREAD = Thread::current(); + JavaValue result(T_VOID); + JavaCallArguments args; + args.push_int(ciTime); + JavaCalls::call_static(&result, optionsKlass, vmSymbols::finalizeOptions_name(), vmSymbols::bool_void_signature(), &args, THREAD); + check_pending_exception("Error while calling finalizeOptions"); +} + void VMToCompiler::compileMethod(Method* method, Handle holder, int entry_bci, jboolean blocking) { assert(method != NULL, "just checking"); assert(!holder.is_null(), "just checking"); diff -r 2bd626188d31 -r e9fc19eb3efb src/share/vm/graal/graalVMToCompiler.hpp --- a/src/share/vm/graal/graalVMToCompiler.hpp Thu Sep 05 16:36:40 2013 +0200 +++ b/src/share/vm/graal/graalVMToCompiler.hpp Fri Sep 13 23:12:10 2013 +0200 @@ -57,6 +57,9 @@ // public static boolean HotSpotOptions.setOption(String option); static jboolean setOption(Handle option); + // public static void HotSpotOptions.finalizeOptions(boolean ciTime); + static void finalizeOptions(jboolean ciTime); + // public abstract boolean compileMethod(long vmId, String name, int entry_bci, boolean blocking); static void compileMethod(Method* method, Handle holder, int entry_bci, jboolean blocking); diff -r 2bd626188d31 -r e9fc19eb3efb src/share/vm/runtime/globals.hpp --- a/src/share/vm/runtime/globals.hpp Thu Sep 05 16:36:40 2013 +0200 +++ b/src/share/vm/runtime/globals.hpp Fri Sep 13 23:12:10 2013 +0200 @@ -3717,8 +3717,11 @@ product(bool , AllowNonVirtualCalls, false, \ "Obey the ACC_SUPER flag and allow invokenonvirtual calls") \ \ - product(bool, TraceGPUInteraction, false, \ - "Trace external GPU warp loading") \ + product(bool, TraceGPUInteraction, false, \ + "Trace external GPU Interaction") \ + \ + product(bool, UseGPU, false, \ + "Run code on GPU") \ \ diagnostic(ccstr, SharedArchiveFile, NULL, \ "Override the default location of the CDS archive file") \ diff -r 2bd626188d31 -r e9fc19eb3efb src/share/vm/runtime/gpu.cpp --- a/src/share/vm/runtime/gpu.cpp Thu Sep 05 16:36:40 2013 +0200 +++ b/src/share/vm/runtime/gpu.cpp Fri Sep 13 23:12:10 2013 +0200 @@ -25,14 +25,48 @@ #include "precompiled.hpp" #include "runtime/gpu.hpp" -bool gpu::_available = false; // does the hardware exist? -bool gpu::_gpu_linkage = false; // is the driver library to access the GPU installed -bool gpu::_initialized = false; // is the GPU device initialized +bool gpu::_available = false; // does the hardware exist? +bool gpu::_gpu_linkage = false; // is the driver library to access the GPU installed +bool gpu::_initialized = false; // is the GPU device initialized +gpu::TargetGPUIL gpu::_targetIL = gpu::NONE; // No GPU detected yet. void gpu::init() { #if defined(TARGET_OS_FAMILY_bsd) || defined(TARGET_OS_FAMILY_linux) gpu::probe_gpu(); + if (gpu::get_target_il_type() == gpu::PTX) { + set_gpu_linkage(gpu::Ptx::probe_linkage()); + } else { + set_gpu_linkage(false); + } #endif - // need multi-gpu TARGET ifdef - gpu::probe_linkage(); +} + +void gpu::initialize_gpu() { + if (gpu::has_gpu_linkage()) { + if (gpu::get_target_il_type() == gpu::PTX) { + set_initialized(gpu::Ptx::initialize_gpu()); + } + // Add initialization of other GPUs here + } } + +void * gpu::generate_kernel(unsigned char *code, int code_len, const char *name) { + if (gpu::has_gpu_linkage()) { + if (gpu::get_target_il_type() == gpu::PTX) { + return (gpu::Ptx::generate_kernel(code, code_len, name)); + } + // Add kernel generation functionality of other GPUs here + } + return NULL; +} + +bool gpu::execute_kernel(address kernel, PTXKernelArguments & ptxka, JavaValue& ret) { + if (gpu::has_gpu_linkage()) { + if (gpu::get_target_il_type() == gpu::PTX) { + return (gpu::Ptx::execute_kernel(kernel, ptxka, ret)); + } + // Add kernel execution functionality of other GPUs here + } + return false; +} + diff -r 2bd626188d31 -r e9fc19eb3efb src/share/vm/runtime/gpu.hpp --- a/src/share/vm/runtime/gpu.hpp Thu Sep 05 16:36:40 2013 +0200 +++ b/src/share/vm/runtime/gpu.hpp Fri Sep 13 23:12:10 2013 +0200 @@ -36,12 +36,12 @@ class gpu: AllStatic { public: + + enum TargetGPUIL { NONE = 0, PTX = 1, HSAIL = 2}; static void init(void); static void probe_gpu(); - static void probe_linkage(); - static void initialize_gpu(); static void * generate_kernel(unsigned char *code, int code_len, const char *name); @@ -66,10 +66,19 @@ static bool has_gpu_linkage() { return _gpu_linkage; } + static void set_target_il_type(TargetGPUIL value) { + _targetIL = value; + } + + static enum gpu::TargetGPUIL get_target_il_type() { + return _targetIL; + } + protected: static bool _available; static bool _gpu_linkage; static bool _initialized; + static TargetGPUIL _targetIL; // Platform dependent stuff #ifdef TARGET_OS_FAMILY_linux