# HG changeset patch # User Thomas Wuerthinger # Date 1425909848 -3600 # Node ID 7241e6dfcafd3c389c3d3b39b80f5605acee0fb0 # Parent d30a0545ddc21fb63695a08f5d53491f9942395a# Parent dc7189b2bb5fe9569cce923beb261334435ae267 Merge. diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaTypeProfile.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaTypeProfile.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaTypeProfile.java Mon Mar 09 15:04:08 2015 +0100 @@ -25,7 +25,6 @@ import java.util.*; import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; /** * This profile object represents the type profile at a specific BCI. The precision of the supplied diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java Mon Mar 09 15:04:08 2015 +0100 @@ -31,34 +31,6 @@ public interface ProfilingInfo { /** - * Represents the three possibilities that an exception was seen at a specific BCI. - */ - public enum TriState { - TRUE, - FALSE, - UNKNOWN; - - public static TriState get(boolean value) { - return value ? TRUE : FALSE; - } - - /** - * This is optimistic about {@link #UNKNOWN} (it prefers known values over {@link #UNKNOWN}) - * and pesimistic about known (it perfers {@link #TRUE} over {@link #FALSE}). - */ - public static TriState merge(TriState a, TriState b) { - if (a == TRUE || b == TRUE) { - return TRUE; - } - if (a == FALSE || b == FALSE) { - return FALSE; - } - assert a == UNKNOWN && b == UNKNOWN; - return UNKNOWN; - } - } - - /** * Returns the length of the bytecodes associated with this profile. */ int getCodeSize(); diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/TriState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/TriState.java Mon Mar 09 15:04:08 2015 +0100 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.api.meta; + +/** + * Represents the three possibilities that an exception was seen at a specific BCI. + */ +public enum TriState { + TRUE, + FALSE, + UNKNOWN; + + public static TriState get(boolean value) { + return value ? TRUE : FALSE; + } + + /** + * This is optimistic about {@link #UNKNOWN} (it prefers known values over {@link #UNKNOWN}) and + * pesimistic about known (it perfers {@link #TRUE} over {@link #FALSE}). + */ + public static TriState merge(TriState a, TriState b) { + if (a == TRUE || b == TRUE) { + return TRUE; + } + if (a == FALSE || b == FALSE) { + return FALSE; + } + assert a == UNKNOWN && b == UNKNOWN; + return UNKNOWN; + } + + public boolean isTrue() { + return this == TRUE; + } + + public boolean isFalse() { + return this == FALSE; + } + + public boolean isUnknown() { + return this == UNKNOWN; + } + + public boolean isKnown() { + return this != UNKNOWN; + } + + public boolean toBoolean() { + if (isTrue()) { + return true; + } else if (isFalse()) { + return false; + } else { + throw new IllegalStateException("Cannot convert to boolean, TriState is in an unknown state"); + } + } +} diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java Mon Mar 09 15:04:08 2015 +0100 @@ -135,4 +135,13 @@ } return newStamp; } + + public boolean neverDistinct(Stamp other) { + Constant constant = this.asConstant(); + if (constant != null) { + Constant otherConstant = other.asConstant(); + return otherConstant != null && constant.equals(otherConstant); + } + return false; + } } diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java Mon Mar 09 15:04:08 2015 +0100 @@ -37,6 +37,8 @@ private static final Stamp objectAlwaysNullStamp = new ObjectStamp(null, false, false, true); private static final Stamp nodeIntrinsicStamp = new ObjectStamp(null, false, false, false); private static final Stamp positiveInt = forInteger(Kind.Int, 0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE); + private static final Stamp booleanTrue = forInteger(Kind.Boolean, -1, -1, 1, 1); + private static final Stamp booleanFalse = forInteger(Kind.Boolean, 0, 0, 0, 0); private static void setCache(Kind kind, Stamp stamp) { stampCache[kind.ordinal()] = stamp; @@ -80,6 +82,14 @@ } } + public static Stamp tautology() { + return booleanTrue; + } + + public static Stamp contradiction() { + return booleanFalse; + } + /** * Return a stamp for a Java kind, as it would be represented on the bytecode stack. */ diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -307,8 +307,8 @@ private void processMethod(final String snippet) { graph = parseEager(snippet, AllowAssumptions.NO); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); - new PartialEscapePhase(false, new CanonicalizerPhase(true)).apply(graph, context); + new InliningPhase(new CanonicalizerPhase()).apply(graph, context); + new PartialEscapePhase(false, new CanonicalizerPhase()).apply(graph, context); } private void compareGraphs(final String snippet, final String referenceSnippet) { @@ -318,9 +318,9 @@ private void compareGraphs(final String snippet, final String referenceSnippet, final boolean loopPeeling, final boolean excludeVirtual) { graph = parseEager(snippet, AllowAssumptions.NO); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); canonicalizer.apply(graph, context); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); + new InliningPhase(new CanonicalizerPhase()).apply(graph, context); if (loopPeeling) { new LoopPeelingPhase().apply(graph); } @@ -332,9 +332,9 @@ canonicalizer.apply(graph, context); StructuredGraph referenceGraph = parseEager(referenceSnippet, AllowAssumptions.YES); - new InliningPhase(new CanonicalizerPhase(true)).apply(referenceGraph, context); + new InliningPhase(new CanonicalizerPhase()).apply(referenceGraph, context); new DeadCodeEliminationPhase().apply(referenceGraph); - new CanonicalizerPhase(true).apply(referenceGraph, context); + new CanonicalizerPhase().apply(referenceGraph, context); assertEquals(referenceGraph, graph, excludeVirtual, true); } diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -36,7 +36,7 @@ private StructuredGraph getCanonicalizedGraph(String name) { StructuredGraph graph = parseEager(name, AllowAssumptions.YES); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); return graph; } @@ -53,7 +53,7 @@ StructuredGraph graph = parseEager("canonicalCompare" + i, AllowAssumptions.NO); assertEquals(referenceGraph, graph); } - new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(referenceGraph, new PhaseContext(getProviders())); for (int i = 1; i < 4; i++) { StructuredGraph graph = getCanonicalizedGraph("canonicalCompare" + i); assertEquals(referenceGraph, graph); diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,130 +0,0 @@ -/* - * Copyright (c) 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.compiler.test; - -import org.junit.*; - -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.phases.common.*; -import com.oracle.graal.phases.tiers.*; - -/** - * Collection of tests for {@link com.oracle.graal.phases.common.ConditionalEliminationPhase} - * including those that triggered bugs in this phase. - */ -public class ConditionalEliminationTest extends GraalCompilerTest { - - public static Object field; - - static class Entry { - - final String name; - - public Entry(String name) { - this.name = name; - } - } - - static class EntryWithNext extends Entry { - - public EntryWithNext(String name, Entry next) { - super(name); - this.next = next; - } - - final Entry next; - } - - public static Entry search(Entry start, String name, Entry alternative) { - Entry current = start; - do { - while (current instanceof EntryWithNext) { - if (name != null && current.name == name) { - current = null; - } else { - Entry next = ((EntryWithNext) current).next; - current = next; - } - } - - if (current != null) { - if (current.name.equals(name)) { - return current; - } - } - if (current == alternative) { - return null; - } - current = alternative; - - } while (true); - } - - public static int testRedundantComparesSnippet(int[] array) { - if (array == null) { - return 0; - } - return array[0] + array[1] + array[2] + array[3]; - } - - @Test - public void testRedundantCompares() { - StructuredGraph graph = parseEager("testRedundantComparesSnippet", AllowAssumptions.YES); - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); - PhaseContext context = new PhaseContext(getProviders()); - - new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); - canonicalizer.apply(graph, context); - new FloatingReadPhase().apply(graph); - new ConditionalEliminationPhase().apply(graph, context); - canonicalizer.apply(graph, context); - - assertDeepEquals(1, graph.getNodes().filter(GuardNode.class).count()); - } - - public static String testInstanceOfCheckCastSnippet(Object e) { - if (e instanceof Entry) { - return ((Entry) e).name; - } - return null; - } - - @Test - @Ignore - public void testInstanceOfCheckCastLowered() { - StructuredGraph graph = parseEager("testInstanceOfCheckCastSnippet", AllowAssumptions.YES); - - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); - PhaseContext context = new PhaseContext(getProviders()); - - new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); - canonicalizer.apply(graph, context); - new ConditionalEliminationPhase().apply(graph, context); - canonicalizer.apply(graph, context); - - assertDeepEquals(0, graph.getNodes().filter(GuardNode.class).count()); - } - -} diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest1.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest1.java Mon Mar 09 15:04:08 2015 +0100 @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.test; + +import org.junit.*; + +import com.oracle.graal.api.directives.*; + +/** + * Collection of tests for + * {@link com.oracle.graal.phases.common.DominatorConditionalEliminationPhase} including those that + * triggered bugs in this phase. + */ +public class ConditionalEliminationTest1 extends ConditionalEliminationTestBase { + + private static final String REFERENCE_SNIPPET = "referenceSnippet"; + + @SuppressWarnings("all") + public static int referenceSnippet(int a) { + if (a == 0) { + return 1; + } + return 0; + } + + @Test + public void test1() { + test("test1Snippet", REFERENCE_SNIPPET); + } + + @SuppressWarnings("all") + public static int test1Snippet(int a) { + if (a == 0) { + if (a == 5) { + return 100; + } + if (a > 100) { + if (a == 0) { + return 200; + } + } + if (a != 2) { + return 1; + } + } + return 0; + } + + @Test + public void test2() { + test("test2Snippet", REFERENCE_SNIPPET); + } + + @SuppressWarnings("all") + public static int test2Snippet(int a) { + if (a == 0) { + if (a > 100) { + if (a == 0) { + return 200; + } + } + if (a != 2) { + return 1; + } + } + return 0; + } + + @Test + public void test3() { + test("test3Snippet", REFERENCE_SNIPPET); + } + + @SuppressWarnings("all") + public static int test3Snippet(int a) { + if (a == 0) { + if (a < 1) { + if (a < 2) { + if (a < 3) { + if (a > -1) { + if (a > -2) { + if (a > -3) { + if (a == 1) { + return 42; + } else { + return 1; + } + } + } + } + } + } + } + } + return 0; + } + + @SuppressWarnings("all") + public static int test4Snippet(int a, int b) { + if (b < 1) { + GraalDirectives.controlFlowAnchor(); + if (b < 0) { + return 1; + } + } + return 0; + } + + @Test + public void test4() { + test("test4Snippet", "test4Snippet"); + } +} diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest2.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest2.java Mon Mar 09 15:04:08 2015 +0100 @@ -0,0 +1,130 @@ +/* + * Copyright (c) 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.compiler.test; + +import org.junit.*; + +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.tiers.*; + +/** + * Collection of tests for + * {@link com.oracle.graal.phases.common.DominatorConditionalEliminationPhase} including those that + * triggered bugs in this phase. + */ +public class ConditionalEliminationTest2 extends ConditionalEliminationTestBase { + + public static Object field; + + static class Entry { + + final String name; + + public Entry(String name) { + this.name = name; + } + } + + static class EntryWithNext extends Entry { + + public EntryWithNext(String name, Entry next) { + super(name); + this.next = next; + } + + final Entry next; + } + + public static Entry search(Entry start, String name, Entry alternative) { + Entry current = start; + do { + while (current instanceof EntryWithNext) { + if (name != null && current.name == name) { + current = null; + } else { + Entry next = ((EntryWithNext) current).next; + current = next; + } + } + + if (current != null) { + if (current.name.equals(name)) { + return current; + } + } + if (current == alternative) { + return null; + } + current = alternative; + + } while (true); + } + + public static int testRedundantComparesSnippet(int[] array) { + if (array == null) { + return 0; + } + return array[0] + array[1] + array[2] + array[3]; + } + + @Test + public void testRedundantCompares() { + StructuredGraph graph = parseEager("testRedundantComparesSnippet", AllowAssumptions.YES); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); + PhaseContext context = new PhaseContext(getProviders()); + + new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); + canonicalizer.apply(graph, context); + new FloatingReadPhase().apply(graph); + new DominatorConditionalEliminationPhase(true).apply(graph, context); + canonicalizer.apply(graph, context); + + assertDeepEquals(1, graph.getNodes().filter(GuardNode.class).count()); + } + + public static String testInstanceOfCheckCastSnippet(Object e) { + if (e instanceof Entry) { + return ((Entry) e).name; + } + return null; + } + + @Test + public void testInstanceOfCheckCastLowered() { + StructuredGraph graph = parseEager("testInstanceOfCheckCastSnippet", AllowAssumptions.YES); + + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); + PhaseContext context = new PhaseContext(getProviders()); + + new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); + canonicalizer.apply(graph, context); + new DominatorConditionalEliminationPhase(true).apply(graph, context); + canonicalizer.apply(graph, context); + + assertDeepEquals(0, graph.getNodes().filter(GuardNode.class).count()); + } + +} diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest3.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest3.java Mon Mar 09 15:04:08 2015 +0100 @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.test; + +import org.junit.*; + +/** + * Collection of tests for + * {@link com.oracle.graal.phases.common.DominatorConditionalEliminationPhase} including those that + * triggered bugs in this phase. + */ +public class ConditionalEliminationTest3 extends ConditionalEliminationTestBase { + + private static final String REFERENCE_SNIPPET = "referenceSnippet"; + + @SuppressWarnings("all") + public static int referenceSnippet(int a, int b) { + int sum = 0; + outer: for (int i = 0;; ++i) { + if (b > 100) { + inner: for (int j = 0;; ++j) { + ++sum; + if (sum == 100) { + break inner; + } + if (sum == 1000 && b < 1000) { + break outer; + } + } + } + } + return sum; + } + + @Test + public void test1() { + test("test1Snippet", REFERENCE_SNIPPET); + } + + @SuppressWarnings("all") + public static int test1Snippet(int a, int b) { + int sum = 0; + outer: for (int i = 0;; ++i) { + if (b > 100) { + inner: for (int j = 0;; ++j) { + ++sum; + if (sum == 100) { + break inner; + } + if (sum == 1000 && b < 1000) { + break outer; + } + } + } + } + if (b >= 1000) { + return 5; + } + return sum; + } + + @Test + public void test2() { + test("test2Snippet", REFERENCE_SNIPPET); + } + + @SuppressWarnings("all") + public static int test2Snippet(int a, int b) { + int sum = 0; + outer: for (int i = 0;; ++i) { + if (b > 100) { + inner: for (int j = 0;; ++j) { + ++sum; + if (sum == 100) { + break inner; + } + if (sum == 1000 && b < 1000) { + break outer; + } + } + if (sum != 100) { + return 42; + } + } + } + return sum; + } +} diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest4.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest4.java Mon Mar 09 15:04:08 2015 +0100 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.test; + +import org.junit.*; + +/** + * Collection of tests for + * {@link com.oracle.graal.phases.common.DominatorConditionalEliminationPhase} including those that + * triggered bugs in this phase. + */ +public class ConditionalEliminationTest4 extends ConditionalEliminationTestBase { + + @SuppressWarnings("all") + public static int reference1Snippet(int a, int b) { + if (a > b) { + return 1; + } + return 2; + } + + @SuppressWarnings("all") + public static int test1Snippet(int a, int b) { + if (a > b) { + if (a > b) { + return 1; + } + } + return 2; + } + + @Test + public void test1() { + test("test1Snippet", "reference1Snippet"); + } + + @SuppressWarnings("all") + public static int reference2Snippet(int a, int b) { + if (a < b) { + return 1; + } + return 2; + } + + @SuppressWarnings("all") + public static int test2Snippet(int a, int b) { + if (a < b) { + if (a < b) { + return 1; + } + } + return 2; + } + + @Test + public void test2() { + test("test2Snippet", "reference2Snippet"); + } +} diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest5.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest5.java Mon Mar 09 15:04:08 2015 +0100 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.test; + +import org.junit.*; + +/** + * Collection of tests for + * {@link com.oracle.graal.phases.common.DominatorConditionalEliminationPhase} including those that + * triggered bugs in this phase. + */ +public class ConditionalEliminationTest5 extends ConditionalEliminationTestBase { + + interface A { + } + + interface B extends A { + } + + @SuppressWarnings("all") + public static int reference1Snippet(A a, B b) { + if (a instanceof B) { + return 1; + } + return 2; + } + + @SuppressWarnings("all") + public static int test1Snippet(A a, B b) { + if (a instanceof B) { + if (a instanceof A) { + return 1; + } + } + return 2; + } + + @Test + public void test1() { + test("test1Snippet", "reference1Snippet"); + } + + @SuppressWarnings("all") + public static int reference2Snippet(A a, B b) { + if (a instanceof B) { + return 1; + } + return 2; + } + + @SuppressWarnings("all") + public static int test2Snippet(A a, B b) { + if (a instanceof B) { + B newVal = (B) a; + if (newVal != null) { + return 1; + } + } + return 2; + } + + @Test + public void test2() { + test("test2Snippet", "reference2Snippet"); + } +} diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest6.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest6.java Mon Mar 09 15:04:08 2015 +0100 @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.test; + +import org.junit.*; + +/** + * Collection of tests for + * {@link com.oracle.graal.phases.common.DominatorConditionalEliminationPhase} including those that + * triggered bugs in this phase. + */ +public class ConditionalEliminationTest6 extends ConditionalEliminationTestBase { + + public static final A constA = new A(); + public static final B constB = new B(); + + static class A { + } + + static class B { + } + + @SuppressWarnings("all") + public static B reference1Snippet(Object a, B b) { + if (a == constA) { + return b; + } + return null; + } + + @SuppressWarnings("all") + public static B test1Snippet(Object a, B b) { + if (a == constA) { + if (a == null) { + return null; + } else { + return b; + } + } + return null; + } + + @Test + public void test1() { + test("test1Snippet", "reference1Snippet"); + } + + @SuppressWarnings("all") + public static B test2Snippet(Object a, B b) { + if (a == constA) { + if (a == constB) { + return null; + } else { + return b; + } + } + return null; + } + + @Test + public void test2() { + test("test2Snippet", "reference1Snippet"); + } + + @SuppressWarnings("all") + public static B test3Snippet(Object a, B b) { + if (a == constA) { + if (a == b) { + return null; + } else { + return b; + } + } + return null; + } + + @Test + public void test3() { + test("test3Snippet", "reference1Snippet"); + } +} diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest7.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest7.java Mon Mar 09 15:04:08 2015 +0100 @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.test; + +import org.junit.*; + +/** + * Collection of tests for + * {@link com.oracle.graal.phases.common.DominatorConditionalEliminationPhase} including those that + * triggered bugs in this phase. + */ +public class ConditionalEliminationTest7 extends ConditionalEliminationTestBase { + + @SuppressWarnings("all") + public static int test1Snippet(int a, Object b) { + int sum = 0; + for (int j = 0;; ++j) { + ++sum; + if (b instanceof String) { + if (sum == 100) { + break; + } + } + } + String s = (String) b; + return s.length() + sum; + } + + @Test + public void test1() { + // One loop exit is skipped. + testProxies("test1Snippet", 1); + } + + @SuppressWarnings("all") + public static int test2Snippet(int a, Object b) { + int sum = 0; + for (int j = 0;; ++j) { + ++sum; + if (b instanceof String) { + break; + } + } + String s = (String) b; + return s.length() + sum; + } + + @Test + public void test2() { + // The loop exit is the anchor => no proxy necessary. + testProxies("test2Snippet", 0); + } + + @SuppressWarnings("all") + public static int test3Snippet(int a, Object b) { + int sum = a; + outer: while (true) { + sum++; + while (sum++ != 20) { + while (sum++ != 30) { + while (sum++ != 40) { + while (sum++ != 50) { + if (b instanceof String) { + break outer; + } + } + } + } + } + } + String s = (String) b; + return s.length() + sum; + } + + @Test + public void test3() { + // The break skips over 4 other loops. + testProxies("test3Snippet", 4); + } +} diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest8.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest8.java Mon Mar 09 15:04:08 2015 +0100 @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.test; + +import org.junit.*; + +/** + * Collection of tests for + * {@link com.oracle.graal.phases.common.DominatorConditionalEliminationPhase} including those that + * triggered bugs in this phase. + */ +public class ConditionalEliminationTest8 extends ConditionalEliminationTestBase { + + private static double value; + + @SuppressWarnings("all") + public static int test1Snippet(int a, Object b) { + double sum = 0; + if (!(b instanceof String)) { + return 42; + } + for (int j = 0; j < a; ++j) { + sum += value; + } + return ((String) b).length(); + } + + @Test + public void test1() { + // One loop exit is skipped, because the condition dominates also the loop begin. + testProxies("test1Snippet", 0); + } +} diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest9.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest9.java Mon Mar 09 15:04:08 2015 +0100 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.test; + +import org.junit.*; + +import com.oracle.graal.api.directives.*; + +/** + * Collection of tests for + * {@link com.oracle.graal.phases.common.DominatorConditionalEliminationPhase} including those that + * triggered bugs in this phase. + */ +public class ConditionalEliminationTest9 extends ConditionalEliminationTestBase { + + private static final String REFERENCE_SNIPPET = "referenceSnippet"; + + @SuppressWarnings("all") + public static int referenceSnippet(int a) { + if (a == 0) { + GraalDirectives.deoptimize(); + } + return 0; + } + + @Test + public void test1() { + test("test1Snippet", REFERENCE_SNIPPET); + } + + @SuppressWarnings("all") + public static int test1Snippet(int a) { + if (a == 0) { + if (a == 0) { + GraalDirectives.deoptimize(); + } + if (a == 0) { + GraalDirectives.deoptimize(); + } + } + return 0; + } +} diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTestBase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTestBase.java Mon Mar 09 15:04:08 2015 +0100 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.test; + +import org.junit.*; + +import com.oracle.graal.debug.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.schedule.*; +import com.oracle.graal.phases.tiers.*; + +/** + * Collection of tests for + * {@link com.oracle.graal.phases.common.DominatorConditionalEliminationPhase} including those that + * triggered bugs in this phase. + */ +public class ConditionalEliminationTestBase extends GraalCompilerTest { + + protected void test(String snippet, String referenceSnippet) { + StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); + Debug.dump(graph, "Graph"); + PhaseContext context = new PhaseContext(getProviders()); + CanonicalizerPhase canonicalizer1 = new CanonicalizerPhase(); + canonicalizer1.disableSimplification(); + canonicalizer1.apply(graph, context); + new ConvertDeoptimizeToGuardPhase().apply(graph, context); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); + new DominatorConditionalEliminationPhase(true).apply(graph, context); + canonicalizer.apply(graph, context); + canonicalizer.apply(graph, context); + StructuredGraph referenceGraph = parseEager(referenceSnippet, AllowAssumptions.YES); + canonicalizer.apply(referenceGraph, context); + assertEquals(referenceGraph, graph); + } + + public void testProxies(String snippet, int expectedProxiesCreated) { + StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); + PhaseContext context = new PhaseContext(getProviders()); + CanonicalizerPhase canonicalizer1 = new CanonicalizerPhase(); + canonicalizer1.disableSimplification(); + canonicalizer1.apply(graph, context); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); + new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); + canonicalizer.apply(graph, context); + + int baseProxyCount = graph.getNodes().filter(ProxyNode.class).count(); + new DominatorConditionalEliminationPhase(true).apply(graph, context); + canonicalizer.apply(graph, context); + new SchedulePhase().apply(graph, context); + int actualProxiesCreated = graph.getNodes().filter(ProxyNode.class).count() - baseProxyCount; + Assert.assertEquals(expectedProxiesCreated, actualProxiesCreated); + } +} diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -83,8 +83,8 @@ try (Scope s = Debug.scope("DegeneratedLoopsTest", new DebugDumpScope(snippet))) { StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); - new CanonicalizerPhase(true).apply(graph, context); + new InliningPhase(new CanonicalizerPhase()).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); Debug.dump(graph, "Graph"); StructuredGraph referenceGraph = parseEager(REFERENCE_SNIPPET, AllowAssumptions.YES); Debug.dump(referenceGraph, "ReferenceGraph"); diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -110,7 +110,7 @@ try (Scope s = Debug.scope("NestedCheckCastsTest", graph)) { Debug.dump(graph, "After parsing: " + snippet); Assert.assertEquals(checkcasts, graph.getNodes().filter(CheckCastNode.class).count()); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); Assert.assertEquals(afterCanon, graph.getNodes().filter(CheckCastNode.class).count()); return graph; } catch (Throwable e) { diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -70,8 +70,8 @@ GraphBuilderConfiguration conf = GraphBuilderConfiguration.getSnippetDefault(); new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), getProviders().getConstantReflection(), conf, OptimisticOptimizations.ALL).apply(graph); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); - new CanonicalizerPhase(true).apply(graph, context); + new InliningPhase(new CanonicalizerPhase()).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); return graph; } diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -60,7 +60,7 @@ StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); PhaseContext context = new PhaseContext(getProviders()); - new LoweringPhase(new CanonicalizerPhase(true), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); + new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); new FloatingReadPhase().apply(graph); ReturnNode returnNode = null; diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GuardEliminationCornerCasesTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GuardEliminationCornerCasesTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.test; + +import org.junit.*; + +import com.oracle.graal.api.directives.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.phases.*; +import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.schedule.*; +import com.oracle.graal.phases.tiers.*; + +public class GuardEliminationCornerCasesTest extends GraalCompilerTest { + + static class A { + + } + + static class B extends A { + + } + + static class C extends B { + + } + + static class D extends C { + + } + + @SuppressWarnings({"static-method", "unused"}) + private int testMethod(Object a) { + if (a instanceof A) { + if (a instanceof C) { + if (a instanceof B) { + B b = (B) a; + if (b instanceof C) { + return 1; + } else { + GraalDirectives.deoptimize(); + } + } + } else { + GraalDirectives.deoptimize(); + } + } + return 0; + } + + @Test + public void testFloatingGuards() { + HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); + StructuredGraph graph = parseEager("testMethod", AllowAssumptions.YES); + new ConvertDeoptimizeToGuardPhase().apply(graph, context); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); + new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); + Debug.dump(graph, "after parsing"); + + GuardNode myGuardNode = null; + for (Node n : graph.getNodes()) { + if (n instanceof GuardNode) { + GuardNode guardNode = (GuardNode) n; + LogicNode condition = guardNode.condition(); + if (condition instanceof InstanceOfNode) { + InstanceOfNode instanceOfNode = (InstanceOfNode) condition; + if (instanceOfNode.getValue() instanceof ValueProxy) { + myGuardNode = guardNode; + break; + } + } + } + } + + AbstractBeginNode myBegin = (AbstractBeginNode) myGuardNode.getAnchor(); + AbstractBeginNode prevBegin = BeginNode.prevBegin((FixedNode) myBegin.predecessor()); + myGuardNode.setAnchor(prevBegin); + + Debug.dump(graph, "after manual modification"); + graph.reverseUsageOrder(); + new ConditionalEliminationPhase().apply(graph); + new SchedulePhase(SchedulePhase.SchedulingStrategy.EARLIEST).apply(graph); + } +} diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfCanonicalizerTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -182,13 +182,13 @@ private void testCombinedIf(String snippet, int count) { StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); PhaseContext context = new PhaseContext(getProviders()); - new LoweringPhase(new CanonicalizerPhase(true), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); + new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); new FloatingReadPhase().apply(graph); MidTierContext midContext = new MidTierContext(getProviders(), getCodeCache().getTarget(), OptimisticOptimizations.ALL, graph.method().getProfilingInfo(), null); new GuardLoweringPhase().apply(graph, midContext); - new LoweringPhase(new CanonicalizerPhase(true), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, midContext); + new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, midContext); new ValueAnchorCleanupPhase().apply(graph); - new CanonicalizerPhase(true).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); assertDeepEquals(count, graph.getNodes().filter(IfNode.class).count()); } @@ -200,7 +200,7 @@ n.replaceFirstInput(param, constant); } Debug.dump(graph, "Graph"); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); for (FrameState fs : param.usages().filter(FrameState.class).snapshot()) { fs.replaceFirstInput(param, null); param.safeDelete(); diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IntegerEqualsCanonicalizerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IntegerEqualsCanonicalizerTest.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IntegerEqualsCanonicalizerTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -114,7 +114,7 @@ private StructuredGraph getCanonicalizedGraph(String snippet) { StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); - new CanonicalizerPhase(false).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); for (FrameState state : graph.getNodes(FrameState.TYPE).snapshot()) { state.replaceAtUsages(null); state.safeDelete(); diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeExceptionTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -67,8 +67,8 @@ hints.put(invoke, 1000d); } HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(hints, new CanonicalizerPhase(true)).apply(graph, context); - new CanonicalizerPhase(true).apply(graph, context); + new InliningPhase(hints, new CanonicalizerPhase()).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); new DeadCodeEliminationPhase().apply(graph); } } diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeHintsTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -78,8 +78,8 @@ } HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(hints, new CanonicalizerPhase(true)).apply(graph, context); - new CanonicalizerPhase(true).apply(graph, context); + new InliningPhase(hints, new CanonicalizerPhase()).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); new DeadCodeEliminationPhase().apply(graph); StructuredGraph referenceGraph = parseEager(REFERENCE_SNIPPET, AllowAssumptions.NO); assertEquals(referenceGraph, graph); diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LockEliminationTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -62,7 +62,7 @@ test("testSynchronizedSnippet", new A(), new A()); StructuredGraph graph = getGraph("testSynchronizedSnippet"); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); new LockEliminationPhase().apply(graph); assertDeepEquals(1, graph.getNodes().filter(MonitorEnterNode.class).count()); assertDeepEquals(1, graph.getNodes().filter(MonitorExitNode.class).count()); @@ -80,7 +80,7 @@ test("testSynchronizedMethodSnippet", new A()); StructuredGraph graph = getGraph("testSynchronizedMethodSnippet"); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); new LockEliminationPhase().apply(graph); assertDeepEquals(1, graph.getNodes().filter(MonitorEnterNode.class).count()); assertDeepEquals(1, graph.getNodes().filter(MonitorExitNode.class).count()); @@ -90,11 +90,11 @@ ResolvedJavaMethod method = getResolvedJavaMethod(snippet); StructuredGraph graph = parseEager(method, AllowAssumptions.YES); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new CanonicalizerPhase(true).apply(graph, context); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); - new CanonicalizerPhase(true).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); + new InliningPhase(new CanonicalizerPhase()).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); new DeadCodeEliminationPhase().apply(graph); - new LoweringPhase(new CanonicalizerPhase(true), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); + new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); new ValueAnchorCleanupPhase().apply(graph); new LockEliminationPhase().apply(graph); return graph; diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LongNodeChainTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LongNodeChainTest.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LongNodeChainTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -77,7 +77,7 @@ new SchedulePhase(s).apply(graph); } - new CanonicalizerPhase(false).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); JavaConstant asConstant = (JavaConstant) returnNode.result().asConstant(); Assert.assertEquals(N + 1, asConstant.asInt()); } diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LoopUnswitchTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -134,8 +134,8 @@ ((StateSplit) stateSplit).setStateAfter(null); } - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); - new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(referenceGraph, new PhaseContext(getProviders())); try (Scope s = Debug.scope("Test", new DebugDumpScope("Test:" + snippet))) { assertEquals(referenceGraph, graph); } catch (Throwable e) { diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -600,7 +600,7 @@ try (Scope d = Debug.scope("FloatingReadTest", graph)) { try (OverrideScope s = OptionValue.override(OptScheduleOutOfLoops, schedulingStrategy == SchedulingStrategy.LATEST_OUT_OF_LOOPS, OptImplicitNullChecks, false)) { HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); canonicalizer.apply(graph, context); if (mode == TestMode.INLINED_WITHOUT_FRAMESTATES) { new InliningPhase(canonicalizer).apply(graph, context); diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MergeCanonicalizerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MergeCanonicalizerTest.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MergeCanonicalizerTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -58,8 +58,8 @@ private void testReturnCount(String snippet, int returnCount) { StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); Debug.dump(graph, "Graph"); assertDeepEquals(returnCount, graph.getNodes(ReturnNode.TYPE).count()); } diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -97,8 +97,8 @@ hints.put(invoke, 1000d); } HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(hints, new CanonicalizerPhase(true)).apply(graph, context); - new CanonicalizerPhase(true).apply(graph, context); + new InliningPhase(hints, new CanonicalizerPhase()).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); new DeadCodeEliminationPhase().apply(graph); return graph; } diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ProfilingInfoTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ProfilingInfoTest.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ProfilingInfoTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -27,7 +27,6 @@ import org.junit.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; /** * Tests profiling information provided by the runtime. diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -93,7 +93,7 @@ private StructuredGraph compileTestSnippet(final String snippet) { StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); PhaseContext context = new PhaseContext(getProviders()); - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); canonicalizer.apply(graph, context); new PushThroughPiPhase().apply(graph); diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushThroughIfTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushThroughIfTest.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushThroughIfTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -63,15 +63,15 @@ fs.replaceAtUsages(null); GraphUtil.killWithUnusedFloatingInputs(fs); } - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); StructuredGraph referenceGraph = parseEager(reference, AllowAssumptions.YES); for (FrameState fs : referenceGraph.getNodes(FrameState.TYPE).snapshot()) { fs.replaceAtUsages(null); GraphUtil.killWithUnusedFloatingInputs(fs); } - new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(referenceGraph, new PhaseContext(getProviders())); assertEquals(referenceGraph, graph); } } diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -83,7 +83,7 @@ // structure changes significantly StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); PhaseContext context = new PhaseContext(getProviders()); - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); new FloatingReadPhase().apply(graph); new OptimizeGuardAnchorsPhase().apply(graph); diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReassociateAndCanonicalTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -244,9 +244,9 @@ private void test(String test, String ref) { StructuredGraph testGraph = parseEager(test, AllowAssumptions.NO); - new CanonicalizerPhase(true).apply(testGraph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(testGraph, new PhaseContext(getProviders())); StructuredGraph refGraph = parseEager(ref, AllowAssumptions.NO); - new CanonicalizerPhase(true).apply(refGraph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(refGraph, new PhaseContext(getProviders())); assertEquals(testGraph, refGraph); } } diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ScalarTypeSystemTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -133,7 +133,7 @@ StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO); Debug.dump(graph, "Graph"); PhaseContext context = new PhaseContext(getProviders()); - new CanonicalizerPhase(true).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); StructuredGraph referenceGraph = parseEager(referenceSnippet, AllowAssumptions.NO); assertEquals(referenceGraph, graph); } diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StampCanonicalizerTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -110,7 +110,7 @@ private void testZeroReturn(String methodName) { StructuredGraph graph = parseEager(methodName, AllowAssumptions.YES); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); new DeadCodeEliminationPhase().apply(graph); assertConstantReturn(graph, 0); } diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StraighteningTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -89,7 +89,7 @@ // No debug scope to reduce console noise for @Test(expected = ...) tests StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); Debug.dump(graph, "Graph"); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); StructuredGraph referenceGraph = parseEager(REFERENCE_SNIPPET, AllowAssumptions.YES); assertEquals(referenceGraph, graph); } diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/TypeSystemTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -178,11 +178,11 @@ * reference graph. */ new ConditionalEliminationPhase().apply(graph, new PhaseContext(getProviders())); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); // a second canonicalizer is needed to process nested MaterializeNodes - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); StructuredGraph referenceGraph = parseEager(referenceSnippet, AllowAssumptions.NO); - new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(referenceGraph, new PhaseContext(getProviders())); assertEquals(referenceGraph, graph); } @@ -230,8 +230,8 @@ private void testHelper(String snippet, Class clazz) { StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); Debug.dump(graph, "Graph " + snippet); Assert.assertFalse("shouldn't have nodes of type " + clazz, graph.getNodes().filter(clazz).iterator().hasNext()); } diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -53,7 +53,7 @@ public void test1() { final ResolvedJavaMethod javaMethod = getResolvedJavaMethod("testMethod"); final StructuredGraph graph = parseEager(javaMethod, AllowAssumptions.NO); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); new DeadCodeEliminationPhase().apply(graph); for (ConstantNode node : ConstantNode.getConstantNodes(graph)) { diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java Mon Mar 09 15:04:08 2015 +0100 @@ -154,10 +154,10 @@ new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), getProviders().getConstantReflection(), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); + new InliningPhase(new CanonicalizerPhase()).apply(graph, context); new DeadCodeEliminationPhase().apply(graph); - new CanonicalizerPhase(true).apply(graph, context); - new PartialEscapePhase(iterativeEscapeAnalysis, false, new CanonicalizerPhase(true), null).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); + new PartialEscapePhase(iterativeEscapeAnalysis, false, new CanonicalizerPhase(), null).apply(graph, context); returnNodes = graph.getNodes(ReturnNode.TYPE).snapshot(); } catch (Throwable e) { throw Debug.handle(e); diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EarlyReadEliminationTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -42,7 +42,7 @@ protected void processMethod(final String snippet) { graph = parseEager(getResolvedJavaMethod(snippet), AllowAssumptions.NO); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); - new EarlyReadEliminationPhase(new CanonicalizerPhase(true)).apply(graph, context); + new InliningPhase(new CanonicalizerPhase()).apply(graph, context); + new EarlyReadEliminationPhase(new CanonicalizerPhase()).apply(graph, context); } } diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -308,8 +308,8 @@ @Test public void testFullyUnrolledLoop() { prepareGraph("testFullyUnrolledLoopSnippet", false); - new LoopFullUnrollPhase(new CanonicalizerPhase(true)).apply(graph, context); - new PartialEscapePhase(false, new CanonicalizerPhase(true)).apply(graph, context); + new LoopFullUnrollPhase(new CanonicalizerPhase()).apply(graph, context); + new PartialEscapePhase(false, new CanonicalizerPhase()).apply(graph, context); Assert.assertEquals(1, returnNodes.size()); Assert.assertTrue(returnNodes.get(0).result() instanceof AllocatedObjectNode); CommitAllocationNode commit = ((AllocatedObjectNode) returnNodes.get(0).result()).getCommit(); diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -86,6 +86,6 @@ private void processMethod(final String snippet) { graph = parseEager(snippet, AllowAssumptions.YES); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new IterativeInliningPhase(new CanonicalizerPhase(true)).apply(graph, context); + new IterativeInliningPhase(new CanonicalizerPhase()).apply(graph, context); } } diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -246,7 +246,7 @@ protected void processMethod(final String snippet) { graph = parseEager(snippet, AllowAssumptions.NO); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); - new PartialEscapePhase(false, true, new CanonicalizerPhase(true), null).apply(graph, context); + new InliningPhase(new CanonicalizerPhase()).apply(graph, context); + new PartialEscapePhase(false, true, new CanonicalizerPhase(), null).apply(graph, context); } } diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -181,7 +181,7 @@ merge.setStateAfter(null); } new DeadCodeEliminationPhase().apply(graph); - new CanonicalizerPhase(true).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); try { Assert.assertTrue("partial escape analysis should have removed all NewInstanceNode allocations", graph.getNodes().filter(NewInstanceNode.class).isEmpty()); Assert.assertTrue("partial escape analysis should have removed all NewArrayNode allocations", graph.getNodes().filter(NewArrayNode.class).isEmpty()); diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PoorMansEATest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PoorMansEATest.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PoorMansEATest.java Mon Mar 09 15:04:08 2015 +0100 @@ -61,9 +61,9 @@ try (Scope s = Debug.scope("PoorMansEATest", new DebugDumpScope(snippet))) { StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO); HighTierContext highTierContext = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext); + new InliningPhase(new CanonicalizerPhase()).apply(graph, highTierContext); PhaseContext context = new PhaseContext(getProviders()); - new LoweringPhase(new CanonicalizerPhase(true), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); + new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); // remove framestates in order to trigger the simplification. cleanup: for (FrameState fs : graph.getNodes(FrameState.TYPE).snapshot()) { @@ -75,7 +75,7 @@ } } } - new CanonicalizerPhase(true).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); } catch (Throwable e) { throw Debug.handle(e); } diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -236,10 +236,10 @@ PhaseSuite graphBuilderSuite = eagerInfopointMode ? getCustomGraphBuilderSuite(GraphBuilderConfiguration.getFullDebugDefault()) : getDefaultGraphBuilderSuite(); HighTierContext context = new HighTierContext(getProviders(), null, graphBuilderSuite, OptimisticOptimizations.ALL); Debug.dump(graph, "Graph"); - new CanonicalizerPhase(true).apply(graph, context); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); + new InliningPhase(new CanonicalizerPhase()).apply(graph, context); Debug.dump(graph, "Graph"); - new CanonicalizerPhase(true).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); new DeadCodeEliminationPhase().apply(graph); return graph; } catch (Throwable e) { diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Mon Mar 09 15:04:08 2015 +0100 @@ -32,7 +32,6 @@ import com.oracle.graal.api.code.CompilationResult.ConstantReference; import com.oracle.graal.api.code.CompilationResult.DataPatch; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.compiler.LIRGenerationPhase.LIRGenerationContext; import com.oracle.graal.compiler.common.alloc.*; import com.oracle.graal.compiler.common.cfg.*; diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Mon Mar 09 15:04:08 2015 +0100 @@ -62,7 +62,7 @@ "Thread - aggregate by qualified name and thread", type = OptionType.Debug) public static final OptionValue DebugValueSummary = new OptionValue<>("Name"); @Option(help = "Omit reporting 0-value metrics", type = OptionType.Debug) - public static final OptionValue SuppressZeroDebugValues = new OptionValue<>(false); + public static final OptionValue SuppressZeroDebugValues = new OptionValue<>(true); @Option(help = "Send Graal IR to dump handlers on error", type = OptionType.Debug) public static final OptionValue DumpOnError = new OptionValue<>(false); @Option(help = "Intercept also bailout exceptions", type = OptionType.Debug) diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Mon Mar 09 15:04:08 2015 +0100 @@ -46,7 +46,10 @@ } public HighTier() { - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue()); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); + if (ImmutableCode.getValue()) { + canonicalizer.disableReadCanonicalization(); + } if (OptCanonicalizer.getValue()) { appendPhase(canonicalizer); @@ -61,7 +64,7 @@ if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) { appendPhase(canonicalizer); - appendPhase(new IterativeConditionalEliminationPhase(canonicalizer)); + appendPhase(new IterativeConditionalEliminationPhase(canonicalizer, false)); } } } diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java Mon Mar 09 15:04:08 2015 +0100 @@ -43,7 +43,10 @@ } public LowTier() { - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue()); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); + if (ImmutableCode.getValue()) { + canonicalizer.disableReadCanonicalization(); + } if (Options.ProfileCompiledMethods.getValue()) { appendPhase(new ProfileCompiledMethodsPhase()); @@ -57,7 +60,7 @@ /* Cleanup IsNull checks resulting from MID_TIER/LOW_TIER lowering and ExpandLogic phase. */ if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) { - appendPhase(new IterativeConditionalEliminationPhase(canonicalizer)); + appendPhase(new IterativeConditionalEliminationPhase(canonicalizer, false)); /* Canonicalizer may create some new ShortCircuitOrNodes so clean them up. */ appendPhase(new ExpandLogicPhase()); } diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java Mon Mar 09 15:04:08 2015 +0100 @@ -34,7 +34,10 @@ public class MidTier extends PhaseSuite { public MidTier() { - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue()); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); + if (ImmutableCode.getValue()) { + canonicalizer.disableReadCanonicalization(); + } if (OptPushThroughPi.getValue()) { appendPhase(new PushThroughPiPhase()); @@ -64,7 +67,7 @@ } if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) { - appendPhase(new IterativeConditionalEliminationPhase(canonicalizer)); + appendPhase(new IterativeConditionalEliminationPhase(canonicalizer, false)); } if (OptEliminatePartiallyRedundantGuards.getValue()) { diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Mon Mar 09 15:04:08 2015 +0100 @@ -891,6 +891,16 @@ } } + /** + * Reverses the usage orders of all nodes. This is used for debugging to make sure an unorthodox + * usage order does not trigger bugs in the compiler. + */ + public void reverseUsageOrder() { + for (Node n : getNodes()) { + n.reverseUsageOrder(); + } + } + public boolean isFrozen() { return isFrozen; } diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Mon Mar 09 15:04:08 2015 +0100 @@ -346,6 +346,24 @@ } /** + * Checks whether this node has usages. + */ + public final boolean hasUsages() { + return this.usage0 != null; + } + + void reverseUsageOrder() { + List snapshot = this.usages().snapshot(); + for (Node n : snapshot) { + this.removeUsage(n); + } + Collections.reverse(snapshot); + for (Node n : snapshot) { + this.addUsage(n); + } + } + + /** * Adds a given node to this node's {@linkplain #usages() usages}. * * @param node the node to add @@ -424,15 +442,6 @@ return false; } - private void clearUsages() { - incUsageModCount(); - maybeNotifyZeroUsages(this); - usage0 = null; - usage1 = null; - extraUsages = NO_NODES; - extraUsagesCount = 0; - } - public final Node predecessor() { return predecessor; } @@ -551,17 +560,27 @@ return true; } - public void replaceAtUsages(Node other) { + public final void replaceAtUsages(Node other) { + replaceAtUsages(other, null); + } + + public final void replaceAtUsages(Node other, Predicate filter) { assert checkReplaceWith(other); - for (Node usage : usages()) { - boolean result = usage.getNodeClass().getInputEdges().replaceFirst(usage, this, other); - assert assertTrue(result, "not found in inputs, usage: %s", usage); - if (other != null) { - maybeNotifyInputChanged(usage); - other.addUsage(usage); + int i = 0; + while (i < this.getUsageCount()) { + Node usage = this.getUsageAt(i); + if (filter == null || filter.test(usage)) { + boolean result = usage.getNodeClass().getInputEdges().replaceFirst(usage, this, other); + assert assertTrue(result, "not found in inputs, usage: %s", usage); + if (other != null) { + maybeNotifyInputChanged(usage); + other.addUsage(usage); + } + this.movUsageFromEndTo(i); + } else { + ++i; } } - clearUsages(); } public Node getUsageAt(int index) { diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -248,10 +248,11 @@ HighTierContext highContext = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); MidTierContext midContext = new MidTierContext(getProviders(), getCodeCache().getTarget(), OptimisticOptimizations.ALL, graph.method().getProfilingInfo(), null); new NodeIntrinsificationPhase(getProviders(), getSnippetReflection()).apply(graph); - new InliningPhase(new InlineEverythingPolicy(), new CanonicalizerPhase(true)).apply(graph, highContext); - new LoweringPhase(new CanonicalizerPhase(true), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highContext); + new InliningPhase(new InlineEverythingPolicy(), new CanonicalizerPhase()).apply(graph, highContext); + new CanonicalizerPhase().apply(graph, highContext); + new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highContext); new GuardLoweringPhase().apply(graph, midContext); - new LoweringPhase(new CanonicalizerPhase(true), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, midContext); + new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, midContext); new WriteBarrierAdditionPhase(config).apply(graph); Debug.dump(graph, "After Write Barrier Addition"); diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -628,14 +628,14 @@ try (Scope d = Debug.scope("WriteBarrierVerificationTest", new DebugDumpScope(snippet))) { final StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); HighTierContext highTierContext = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext); + new InliningPhase(new CanonicalizerPhase()).apply(graph, highTierContext); MidTierContext midTierContext = new MidTierContext(getProviders(), getCodeCache().getTarget(), OptimisticOptimizations.ALL, graph.method().getProfilingInfo(), null); - new LoweringPhase(new CanonicalizerPhase(true), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highTierContext); + new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highTierContext); new GuardLoweringPhase().apply(graph, midTierContext); new LoopSafepointInsertionPhase().apply(graph); - new LoweringPhase(new CanonicalizerPhase(true), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, highTierContext); + new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, highTierContext); new WriteBarrierAdditionPhase(config).apply(graph); diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java Mon Mar 09 15:04:08 2015 +0100 @@ -34,7 +34,6 @@ import java.util.jar.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.bytecode.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java Mon Mar 09 15:04:08 2015 +0100 @@ -33,7 +33,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.JavaMethodProfile.ProfiledMethod; import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.HotSpotMethodDataAccessor.Tag; diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodDataAccessor.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodDataAccessor.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodDataAccessor.java Mon Mar 09 15:04:08 2015 +0100 @@ -25,7 +25,6 @@ import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.hotspot.*; /** diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethodImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethodImpl.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethodImpl.java Mon Mar 09 15:04:08 2015 +0100 @@ -33,7 +33,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.debug.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.debug.*; diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionInterface.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionInterface.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionInterface.java Mon Mar 09 15:04:08 2015 +0100 @@ -29,7 +29,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Mon Mar 09 15:04:08 2015 +0100 @@ -31,7 +31,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.hotspot.meta.*; diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/ArrayCopyNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/ArrayCopyNode.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/ArrayCopyNode.java Mon Mar 09 15:04:08 2015 +0100 @@ -77,9 +77,9 @@ // the canonicalization before loop unrolling is needed to propagate the length into // additions, etc. PhaseContext context = new PhaseContext(tool.getMetaAccess(), tool.getConstantReflection(), tool.getLowerer(), tool.getReplacements(), tool.getStampProvider()); - new CanonicalizerPhase(true).apply(snippetGraph, context); - new LoopFullUnrollPhase(new CanonicalizerPhase(true)).apply(snippetGraph, context); - new CanonicalizerPhase(true).apply(snippetGraph, context); + new CanonicalizerPhase().apply(snippetGraph, context); + new LoopFullUnrollPhase(new CanonicalizerPhase()).apply(snippetGraph, context); + new CanonicalizerPhase().apply(snippetGraph, context); } @Override diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Mon Mar 09 15:04:08 2015 +0100 @@ -31,7 +31,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.bytecode.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.calc.*; diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Mon Mar 09 15:04:08 2015 +0100 @@ -34,7 +34,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.api.replacements.*; import com.oracle.graal.bytecode.*; import com.oracle.graal.compiler.common.*; diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/NestedLoop_EA.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/NestedLoop_EA.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/NestedLoop_EA.java Mon Mar 09 15:04:08 2015 +0100 @@ -26,7 +26,6 @@ import org.junit.*; -import com.oracle.graal.compiler.common.*; import com.oracle.graal.jtt.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.virtual.*; @@ -41,7 +40,7 @@ protected Suites createSuites() { Suites suites = super.createSuites(); ListIterator> position = suites.getHighTier().findPhase(PartialEscapePhase.class); - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!GraalOptions.ImmutableCode.getValue()); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); // incremental canonicalizer of PEA is missing some important canonicalization (TODO?) position.add(canonicalizer); position.add(new PartialEscapePhase(true, canonicalizer)); diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/LoopPhiCanonicalizerTest.java --- a/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/LoopPhiCanonicalizerTest.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/LoopPhiCanonicalizerTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -62,7 +62,7 @@ PhaseContext context = new PhaseContext(getProviders()); Assert.assertEquals(5, graph.getNodes().filter(loopPhis).count()); - new CanonicalizerPhase(false).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); Assert.assertEquals(2, graph.getNodes().filter(loopPhis).count()); test("loopSnippet"); diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractBeginNode.java Mon Mar 09 15:04:08 2015 +0100 @@ -94,10 +94,19 @@ } public void removeProxies() { - for (ProxyNode vpn : proxies().snapshot()) { - // can not use graph.replaceFloating because vpn.value may be null during killCFG - vpn.replaceAtUsages(vpn.value()); - vpn.safeDelete(); + if (this.hasUsages()) { + outer: while (true) { + for (ProxyNode vpn : proxies().snapshot()) { + ValueNode value = vpn.value(); + vpn.replaceAtUsages(value); + vpn.safeDelete(); + if (value == this) { + // Guard proxy could have this input as value. + continue outer; + } + } + break; + } } } diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BinaryOpLogicNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BinaryOpLogicNode.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BinaryOpLogicNode.java Mon Mar 09 15:04:08 2015 +0100 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodeinfo.*; @@ -83,4 +85,10 @@ } return this; } + + public abstract Stamp getSucceedingStampForX(boolean negated); + + public abstract Stamp getSucceedingStampForY(boolean negated); + + public abstract TriState tryFold(Stamp xStamp, Stamp yStamp); } diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConditionAnchorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConditionAnchorNode.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConditionAnchorNode.java Mon Mar 09 15:04:08 2015 +0100 @@ -76,6 +76,9 @@ return new ValueAnchorNode(null); } } + if (this.hasNoUsages()) { + return null; + } return this; } diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardPhiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardPhiNode.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardPhiNode.java Mon Mar 09 15:04:08 2015 +0100 @@ -41,11 +41,6 @@ this.values = new NodeInputList<>(this); } - public GuardPhiNode(AbstractMergeNode merge, ValueNode[] values) { - super(TYPE, StampFactory.forVoid(), merge); - this.values = new NodeInputList<>(this, values); - } - @Override public NodeInputList values() { return values; diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardProxyNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardProxyNode.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardProxyNode.java Mon Mar 09 15:04:08 2015 +0100 @@ -43,6 +43,11 @@ public void generate(NodeLIRBuilderTool generator) { } + public void setValue(GuardingNode newValue) { + this.updateUsages(value.asNode(), newValue.asNode()); + this.value = newValue; + } + @Override public ValueNode value() { return value.asNode(); diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Mon Mar 09 15:04:08 2015 +0100 @@ -26,7 +26,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; @@ -1133,4 +1132,8 @@ public AbstractBeginNode getPrimarySuccessor() { return this.trueSuccessor(); } + + public AbstractBeginNode getSuccessor(boolean result) { + return result ? this.trueSuccessor() : this.falseSuccessor(); + } } diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Mon Mar 09 15:04:08 2015 +0100 @@ -324,7 +324,7 @@ if (node instanceof AbstractBeginNode) { ((AbstractBeginNode) node).prepareDelete(); } - assert node.hasNoUsages() : node + " " + node.usages(); + assert node.hasNoUsages() : node + " " + node.usages().count() + ", " + node.usages().first(); GraphUtil.unlinkFixedNode(node); node.safeDelete(); } diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnaryOpLogicNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnaryOpLogicNode.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnaryOpLogicNode.java Mon Mar 09 15:04:08 2015 +0100 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodeinfo.*; @@ -46,4 +48,8 @@ @Override public void generate(NodeLIRBuilderTool gen) { } + + public abstract Stamp getSucceedingStampForValue(boolean negated); + + public abstract TriState tryFold(Stamp valueStamp); } diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java Mon Mar 09 15:04:08 2015 +0100 @@ -58,9 +58,11 @@ if (result != this) { return result; } - if (forX.stamp() instanceof FloatStamp && forY.stamp() instanceof FloatStamp) { - FloatStamp xStamp = (FloatStamp) forX.stamp(); - FloatStamp yStamp = (FloatStamp) forY.stamp(); + Stamp xStampGeneric = forX.stamp(); + Stamp yStampGeneric = forY.stamp(); + if (xStampGeneric instanceof FloatStamp && yStampGeneric instanceof FloatStamp) { + FloatStamp xStamp = (FloatStamp) xStampGeneric; + FloatStamp yStamp = (FloatStamp) yStampGeneric; if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY) && xStamp.isNonNaN() && yStamp.isNonNaN()) { return LogicConstantNode.tautology(); } else if (xStamp.alwaysDistinct(yStamp)) { @@ -79,4 +81,34 @@ } throw GraalInternalError.shouldNotReachHere(); } + + @Override + public Stamp getSucceedingStampForX(boolean negated) { + if (!negated) { + return getX().stamp().join(getY().stamp()); + } + return null; + } + + @Override + public Stamp getSucceedingStampForY(boolean negated) { + if (!negated) { + return getX().stamp().join(getY().stamp()); + } + return null; + } + + @Override + public TriState tryFold(Stamp xStampGeneric, Stamp yStampGeneric) { + if (xStampGeneric instanceof FloatStamp && yStampGeneric instanceof FloatStamp) { + FloatStamp xStamp = (FloatStamp) xStampGeneric; + FloatStamp yStamp = (FloatStamp) yStampGeneric; + if (xStamp.alwaysDistinct(yStamp)) { + return TriState.FALSE; + } else if (xStamp.neverDistinct(yStamp)) { + return TriState.TRUE; + } + } + return TriState.UNKNOWN; + } } diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java Mon Mar 09 15:04:08 2015 +0100 @@ -72,4 +72,19 @@ } throw GraalInternalError.shouldNotReachHere(); } + + @Override + public Stamp getSucceedingStampForX(boolean negated) { + return null; + } + + @Override + public Stamp getSucceedingStampForY(boolean negated) { + return null; + } + + @Override + public TriState tryFold(Stamp xStampGeneric, Stamp yStampGeneric) { + return TriState.UNKNOWN; + } } diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowNode.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowNode.java Mon Mar 09 15:04:08 2015 +0100 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes.calc; +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; @@ -92,4 +93,97 @@ protected CompareNode duplicateModified(ValueNode newX, ValueNode newY) { return new IntegerBelowNode(newX, newY); } + + @Override + public Stamp getSucceedingStampForX(boolean negated) { + Stamp xStampGeneric = getX().stamp(); + Stamp yStampGeneric = getY().stamp(); + if (xStampGeneric instanceof IntegerStamp) { + IntegerStamp xStamp = (IntegerStamp) xStampGeneric; + int bits = xStamp.getBits(); + if (yStampGeneric instanceof IntegerStamp) { + IntegerStamp yStamp = (IntegerStamp) yStampGeneric; + assert yStamp.getBits() == bits; + if (negated) { + // x >= y + if (xStamp.isPositive() && yStamp.isPositive()) { + long xLowerBound = xStamp.lowerBound(); + long yLowerBound = yStamp.lowerBound(); + if (yLowerBound > xLowerBound) { + return new IntegerStamp(bits, yLowerBound, xStamp.upperBound(), xStamp.downMask(), xStamp.upMask()); + } + } + } else { + // x < y + if (yStamp.isPositive()) { + // x >= 0 && x < y + long xUpperBound = xStamp.upperBound(); + long yUpperBound = yStamp.upperBound(); + if (yUpperBound <= xUpperBound || !xStamp.isPositive()) { + if (yUpperBound != 0) { + yUpperBound--; + } + return new IntegerStamp(bits, Math.max(0, xStamp.lowerBound()), Math.min(xUpperBound, yUpperBound), xStamp.downMask(), xStamp.upMask()); + } + } + } + } + } + return null; + } + + @Override + public Stamp getSucceedingStampForY(boolean negated) { + Stamp xStampGeneric = getX().stamp(); + Stamp yStampGeneric = getY().stamp(); + if (xStampGeneric instanceof IntegerStamp) { + IntegerStamp xStamp = (IntegerStamp) xStampGeneric; + int bits = xStamp.getBits(); + if (yStampGeneric instanceof IntegerStamp) { + IntegerStamp yStamp = (IntegerStamp) yStampGeneric; + assert yStamp.getBits() == bits; + if (negated) { + // y <= x + if (xStamp.isPositive()) { + long xUpperBound = xStamp.upperBound(); + long yUpperBound = yStamp.upperBound(); + if (xUpperBound < yUpperBound || !yStamp.isPositive()) { + return new IntegerStamp(bits, Math.max(0, yStamp.lowerBound()), Math.min(xUpperBound, yUpperBound), yStamp.downMask(), yStamp.upMask()); + } + } + } else { + // y > x + if (xStamp.isPositive() && yStamp.isPositive()) { + long xLowerBound = xStamp.lowerBound(); + long yLowerBound = yStamp.lowerBound(); + if (xLowerBound >= yLowerBound) { + if (xLowerBound != CodeUtil.maxValue(bits)) { + xLowerBound++; + } + return new IntegerStamp(bits, xLowerBound, yStamp.upperBound(), yStamp.downMask(), yStamp.upMask()); + } + } + } + } + } + return null; + } + + @Override + public TriState tryFold(Stamp xStampGeneric, Stamp yStampGeneric) { + if (xStampGeneric instanceof IntegerStamp) { + IntegerStamp xStamp = (IntegerStamp) xStampGeneric; + if (yStampGeneric instanceof IntegerStamp) { + IntegerStamp yStamp = (IntegerStamp) yStampGeneric; + if (yStamp.isPositive()) { + if (xStamp.isPositive() && xStamp.upperBound() < yStamp.lowerBound()) { + return TriState.TRUE; + } else if (xStamp.isStrictlyNegative() || xStamp.lowerBound() >= yStamp.upperBound()) { + return TriState.FALSE; + } + } + } + } + return TriState.UNKNOWN; + } } diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java Mon Mar 09 15:04:08 2015 +0100 @@ -154,4 +154,34 @@ } return super.canonicalizeSymmetricConstant(tool, constant, nonConstant, mirrored); } + + @Override + public Stamp getSucceedingStampForX(boolean negated) { + if (!negated) { + return getX().stamp().join(getY().stamp()); + } + return null; + } + + @Override + public Stamp getSucceedingStampForY(boolean negated) { + if (!negated) { + return getX().stamp().join(getY().stamp()); + } + return null; + } + + @Override + public TriState tryFold(Stamp xStampGeneric, Stamp yStampGeneric) { + if (xStampGeneric instanceof IntegerStamp && yStampGeneric instanceof IntegerStamp) { + IntegerStamp xStamp = (IntegerStamp) xStampGeneric; + IntegerStamp yStamp = (IntegerStamp) yStampGeneric; + if (xStamp.alwaysDistinct(yStamp)) { + return TriState.FALSE; + } else if (xStamp.neverDistinct(yStamp)) { + return TriState.TRUE; + } + } + return TriState.UNKNOWN; + } } diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java Mon Mar 09 15:04:08 2015 +0100 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes.calc; +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.calc.*; @@ -114,4 +115,85 @@ } throw GraalInternalError.shouldNotReachHere(); } + + @Override + public Stamp getSucceedingStampForX(boolean negated) { + Stamp xStampGeneric = getX().stamp(); + Stamp yStampGeneric = getY().stamp(); + if (xStampGeneric instanceof IntegerStamp) { + IntegerStamp xStamp = (IntegerStamp) xStampGeneric; + int bits = xStamp.getBits(); + if (yStampGeneric instanceof IntegerStamp) { + IntegerStamp yStamp = (IntegerStamp) yStampGeneric; + assert yStamp.getBits() == bits; + if (negated) { + // x >= y + long xLowerBound = xStamp.lowerBound(); + long yLowerBound = yStamp.lowerBound(); + if (yLowerBound > xLowerBound) { + return new IntegerStamp(bits, yLowerBound, xStamp.upperBound(), xStamp.downMask(), xStamp.upMask()); + } + } else { + // x < y + long xUpperBound = xStamp.upperBound(); + long yUpperBound = yStamp.upperBound(); + if (yUpperBound <= xUpperBound) { + if (yUpperBound != CodeUtil.minValue(bits)) { + yUpperBound--; + } + return new IntegerStamp(bits, xStamp.lowerBound(), yUpperBound, xStamp.downMask(), xStamp.upMask()); + } + } + } + } + return null; + } + + @Override + public Stamp getSucceedingStampForY(boolean negated) { + Stamp xStampGeneric = getX().stamp(); + Stamp yStampGeneric = getY().stamp(); + if (xStampGeneric instanceof IntegerStamp) { + IntegerStamp xStamp = (IntegerStamp) xStampGeneric; + int bits = xStamp.getBits(); + if (yStampGeneric instanceof IntegerStamp) { + IntegerStamp yStamp = (IntegerStamp) yStampGeneric; + assert yStamp.getBits() == bits; + if (negated) { + // y <= x + long xUpperBound = xStamp.upperBound(); + long yUpperBound = yStamp.upperBound(); + if (xUpperBound < yUpperBound) { + return new IntegerStamp(bits, yStamp.lowerBound(), xUpperBound, yStamp.downMask(), yStamp.upMask()); + } + } else { + // y > x + long xLowerBound = xStamp.lowerBound(); + long yLowerBound = yStamp.lowerBound(); + if (xLowerBound >= yLowerBound) { + if (xLowerBound != CodeUtil.maxValue(bits)) { + xLowerBound++; + } + return new IntegerStamp(bits, xLowerBound, yStamp.upperBound(), yStamp.downMask(), yStamp.upMask()); + } + } + } + } + return null; + } + + @Override + public TriState tryFold(Stamp xStampGeneric, Stamp yStampGeneric) { + if (xStampGeneric instanceof IntegerStamp && yStampGeneric instanceof IntegerStamp) { + IntegerStamp xStamp = (IntegerStamp) xStampGeneric; + IntegerStamp yStamp = (IntegerStamp) yStampGeneric; + if (xStamp.upperBound() < yStamp.lowerBound()) { + return TriState.TRUE; + } + if (xStamp.lowerBound() >= yStamp.upperBound()) { + return TriState.FALSE; + } + } + return TriState.UNKNOWN; + } } diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java Mon Mar 09 15:04:08 2015 +0100 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes.calc; +import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.Canonicalizable.BinaryCommutative; @@ -58,4 +59,20 @@ } return this; } + + @Override + public Stamp getSucceedingStampForX(boolean negated) { + return null; + } + + @Override + public Stamp getSucceedingStampForY(boolean negated) { + return null; + } + + @Override + public TriState tryFold(Stamp xStampGeneric, Stamp yStampGeneric) { + System.out.println("try fold with " + xStampGeneric + " and " + yStampGeneric); + return TriState.UNKNOWN; + } } diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java Mon Mar 09 15:04:08 2015 +0100 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes.calc; +import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; @@ -86,4 +87,22 @@ @NodeIntrinsic public static native IsNullNode isNull(Object object); + + @Override + public Stamp getSucceedingStampForValue(boolean negated) { + return negated ? StampFactory.objectNonNull() : StampFactory.alwaysNull(); + } + + @Override + public TriState tryFold(Stamp valueStamp) { + if (valueStamp instanceof ObjectStamp) { + ObjectStamp objectStamp = (ObjectStamp) valueStamp; + if (objectStamp.alwaysNull()) { + return TriState.TRUE; + } else if (objectStamp.nonNull()) { + return TriState.FALSE; + } + } + return TriState.UNKNOWN; + } } diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/PointerEqualsNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/PointerEqualsNode.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/PointerEqualsNode.java Mon Mar 09 15:04:08 2015 +0100 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes.calc; +import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; @@ -73,4 +74,42 @@ protected CompareNode duplicateModified(ValueNode newX, ValueNode newY) { return new PointerEqualsNode(newX, newY); } + + @Override + public Stamp getSucceedingStampForX(boolean negated) { + if (!negated) { + Stamp xStamp = getX().stamp(); + Stamp newStamp = xStamp.join(getY().stamp()); + if (!newStamp.equals(xStamp)) { + return newStamp; + } + } + return null; + } + + @Override + public Stamp getSucceedingStampForY(boolean negated) { + if (!negated) { + Stamp yStamp = getY().stamp(); + Stamp newStamp = yStamp.join(getX().stamp()); + if (!newStamp.equals(yStamp)) { + return newStamp; + } + } + return null; + } + + @Override + public TriState tryFold(Stamp xStampGeneric, Stamp yStampGeneric) { + if (xStampGeneric instanceof ObjectStamp && yStampGeneric instanceof ObjectStamp) { + ObjectStamp xStamp = (ObjectStamp) xStampGeneric; + ObjectStamp yStamp = (ObjectStamp) yStampGeneric; + if (xStamp.alwaysDistinct(yStamp)) { + return TriState.FALSE; + } else if (xStamp.neverDistinct(yStamp)) { + return TriState.TRUE; + } + } + return TriState.UNKNOWN; + } } diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java Mon Mar 09 15:04:08 2015 +0100 @@ -124,10 +124,15 @@ @Override public FixedNode next() { FixedNode result = cur; - if (cur == getEndNode()) { + if (result instanceof FixedWithNextNode) { + FixedWithNextNode fixedWithNextNode = (FixedWithNextNode) result; + FixedNode next = fixedWithNextNode.next(); + if (next instanceof AbstractBeginNode) { + next = null; + } + cur = next; + } else { cur = null; - } else { - cur = ((FixedWithNextNode) cur).next(); } assert !(cur instanceof AbstractBeginNode); return result; diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java Mon Mar 09 15:04:08 2015 +0100 @@ -318,7 +318,7 @@ } } - private void computePostdominators() { + public void computePostdominators() { outer: for (Block block : postOrder()) { if (block.isLoopEnd()) { // We do not want the loop header registered as the postdominator of the loop end. diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Mon Mar 09 15:04:08 2015 +0100 @@ -28,7 +28,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; @@ -239,4 +238,17 @@ public ValueNode getOriginalNode() { return object; } + + public TriState tryFold(Stamp testStamp) { + if (testStamp instanceof ObjectStamp) { + ObjectStamp objectStamp = (ObjectStamp) testStamp; + ResolvedJavaType objectType = objectStamp.type(); + if (objectType != null && type.isAssignableFrom(objectType)) { + return TriState.TRUE; + } else if (objectStamp.alwaysNull()) { + return TriState.TRUE; + } + } + return TriState.UNKNOWN; + } } diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java Mon Mar 09 15:04:08 2015 +0100 @@ -160,4 +160,43 @@ tool.replaceWithValue(LogicConstantNode.forBoolean(type().isAssignableFrom(state.getVirtualObject().type()), graph())); } } + + @Override + public Stamp getSucceedingStampForValue(boolean negated) { + if (negated) { + return null; + } else { + return StampFactory.declaredTrustedNonNull(type); + } + } + + @Override + public TriState tryFold(Stamp valueStamp) { + if (valueStamp instanceof ObjectStamp) { + ObjectStamp objectStamp = (ObjectStamp) valueStamp; + if (objectStamp.alwaysNull()) { + return TriState.FALSE; + } + + ResolvedJavaType objectType = objectStamp.type(); + if (objectType != null) { + ResolvedJavaType instanceofType = type; + if (instanceofType.isAssignableFrom(objectType)) { + if (objectStamp.nonNull()) { + return TriState.TRUE; + } + } else { + if (objectStamp.isExactType()) { + return TriState.FALSE; + } else { + boolean superType = objectType.isAssignableFrom(instanceofType); + if (!superType && !objectType.isInterface() && !instanceofType.isInterface()) { + return TriState.FALSE; + } + } + } + } + } + return TriState.UNKNOWN; + } } diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Mon Mar 09 15:04:08 2015 +0100 @@ -49,36 +49,23 @@ private static final DebugMetric METRIC_SIMPLIFICATION_CONSIDERED_NODES = Debug.metric("SimplificationConsideredNodes"); private static final DebugMetric METRIC_GLOBAL_VALUE_NUMBERING_HITS = Debug.metric("GlobalValueNumberingHits"); - private final boolean canonicalizeReads; - private final CustomCanonicalizer customCanonicalizer; - - public abstract static class CustomCanonicalizer { + private boolean canonicalizeReads = true; + private boolean simplify = true; - public Node canonicalize(Node node) { - return node; - } - - @SuppressWarnings("unused") - public void simplify(Node node, SimplifierTool tool) { - } + public CanonicalizerPhase() { } - public CanonicalizerPhase(boolean canonicalizeReads) { - this(canonicalizeReads, null); + public void disableReadCanonicalization() { + canonicalizeReads = false; } - public CanonicalizerPhase(boolean canonicalizeReads, CustomCanonicalizer customCanonicalizer) { - this.canonicalizeReads = canonicalizeReads; - this.customCanonicalizer = customCanonicalizer; - } - - public boolean getCanonicalizeReads() { - return canonicalizeReads; + public void disableSimplification() { + simplify = false; } @Override protected void run(StructuredGraph graph, PhaseContext context) { - new Instance(context, canonicalizeReads, customCanonicalizer).run(graph); + new Instance(context).run(graph); } /** @@ -90,7 +77,7 @@ } public void applyIncremental(StructuredGraph graph, PhaseContext context, Mark newNodesMark, boolean dumpGraph) { - new Instance(context, canonicalizeReads, newNodesMark, customCanonicalizer).apply(graph, dumpGraph); + new Instance(context, newNodesMark).apply(graph, dumpGraph); } /** @@ -102,7 +89,7 @@ } public void applyIncremental(StructuredGraph graph, PhaseContext context, Iterable workingSet, boolean dumpGraph) { - new Instance(context, canonicalizeReads, workingSet, customCanonicalizer).apply(graph, dumpGraph); + new Instance(context, workingSet).apply(graph, dumpGraph); } public void applyIncremental(StructuredGraph graph, PhaseContext context, Iterable workingSet, Mark newNodesMark) { @@ -110,38 +97,34 @@ } public void applyIncremental(StructuredGraph graph, PhaseContext context, Iterable workingSet, Mark newNodesMark, boolean dumpGraph) { - new Instance(context, canonicalizeReads, workingSet, newNodesMark, customCanonicalizer).apply(graph, dumpGraph); + new Instance(context, workingSet, newNodesMark).apply(graph, dumpGraph); } - private static final class Instance extends Phase { + private final class Instance extends Phase { private final Mark newNodesMark; private final PhaseContext context; - private final CustomCanonicalizer customCanonicalizer; private final Iterable initWorkingSet; - private final boolean canonicalizeReads; private NodeWorkList workList; private Tool tool; - private Instance(PhaseContext context, boolean canonicalizeReads, CustomCanonicalizer customCanonicalizer) { - this(context, canonicalizeReads, null, null, customCanonicalizer); + private Instance(PhaseContext context) { + this(context, null, null); } - private Instance(PhaseContext context, boolean canonicalizeReads, Iterable workingSet, CustomCanonicalizer customCanonicalizer) { - this(context, canonicalizeReads, workingSet, null, customCanonicalizer); + private Instance(PhaseContext context, Iterable workingSet) { + this(context, workingSet, null); } - private Instance(PhaseContext context, boolean canonicalizeReads, Mark newNodesMark, CustomCanonicalizer customCanonicalizer) { - this(context, canonicalizeReads, null, newNodesMark, customCanonicalizer); + private Instance(PhaseContext context, Mark newNodesMark) { + this(context, null, newNodesMark); } - private Instance(PhaseContext context, boolean canonicalizeReads, Iterable workingSet, Mark newNodesMark, CustomCanonicalizer customCanonicalizer) { + private Instance(PhaseContext context, Iterable workingSet, Mark newNodesMark) { super("Canonicalizer"); this.newNodesMark = newNodesMark; this.context = context; - this.canonicalizeReads = canonicalizeReads; - this.customCanonicalizer = customCanonicalizer; this.initWorkingSet = workingSet; } @@ -214,7 +197,7 @@ } } - public static boolean tryGlobalValueNumbering(Node node, NodeClass nodeClass) { + public boolean tryGlobalValueNumbering(Node node, NodeClass nodeClass) { if (nodeClass.valueNumberable() && !nodeClass.isLeafNode()) { Node newNode = node.graph().findDuplicate(node); if (newNode != null) { @@ -229,19 +212,7 @@ return false; } - public boolean tryCanonicalize(final Node node, NodeClass nodeClass) { - if (customCanonicalizer != null) { - Node canonical = customCanonicalizer.canonicalize(node); - if (performReplacement(node, canonical)) { - return true; - } else { - customCanonicalizer.simplify(node, tool); - } - } - return baseTryCanonicalize(node, nodeClass); - } - - private static AutoCloseable getCanonicalizeableContractAssertion(Node node) { + private AutoCloseable getCanonicalizeableContractAssertion(Node node) { boolean needsAssertion = false; assert (needsAssertion = true) == true; if (needsAssertion) { @@ -255,7 +226,7 @@ } } - public boolean baseTryCanonicalize(final Node node, NodeClass nodeClass) { + public boolean tryCanonicalize(final Node node, NodeClass nodeClass) { if (nodeClass.isCanonicalizable()) { METRIC_CANONICALIZATION_CONSIDERED_NODES.increment(); try (Scope s = Debug.scope("CanonicalizeNode", node)) { @@ -274,7 +245,7 @@ } } - if (nodeClass.isSimplifiable()) { + if (nodeClass.isSimplifiable() && simplify) { Debug.log(3, "Canonicalizer: simplifying %s", node); METRIC_SIMPLIFICATION_CONSIDERED_NODES.increment(); try (Scope s = Debug.scope("SimplifyNode", node)) { diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Mon Mar 09 15:04:08 2015 +0100 @@ -778,6 +778,8 @@ ResolvedJavaType type = state.getNodeType(object); if (isNull || (type != null && checkCast.type().isAssignableFrom(type))) { boolean nonNull = state.isNonNull(object); + // if (true) + // throw new RuntimeException(checkCast.toString()); GuardingNode replacementAnchor = null; if (nonNull) { replacementAnchor = searchAnchor(GraphUtil.unproxify(object), type); diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DominatorConditionalEliminationPhase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DominatorConditionalEliminationPhase.java Mon Mar 09 15:04:08 2015 +0100 @@ -0,0 +1,472 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.phases.common; + +import static com.oracle.graal.api.meta.DeoptimizationAction.*; +import static com.oracle.graal.api.meta.DeoptimizationReason.*; + +import java.util.*; +import java.util.function.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.cfg.*; +import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodeinfo.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.cfg.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.util.*; +import com.oracle.graal.phases.*; +import com.oracle.graal.phases.schedule.*; + +public class DominatorConditionalEliminationPhase extends Phase { + + private static final DebugMetric metricStampsRegistered = Debug.metric("StampsRegistered"); + private static final DebugMetric metricStampsFound = Debug.metric("StampsFound"); + private final boolean fullSchedule; + + public DominatorConditionalEliminationPhase(boolean fullSchedule) { + this.fullSchedule = fullSchedule; + } + + private static final class InfoElement { + private Stamp stamp; + private ValueNode guard; + + public InfoElement(Stamp stamp, ValueNode guard) { + this.stamp = stamp; + this.guard = guard; + } + + public Stamp getStamp() { + return stamp; + } + + public ValueNode getGuard() { + return guard; + } + } + + private static final class Info { + private ArrayList infos; + + public Info() { + infos = new ArrayList<>(); + } + + public Iterable getElements() { + return infos; + } + + public void pushElement(InfoElement element) { + infos.add(element); + } + + public void popElement() { + infos.remove(infos.size() - 1); + } + } + + @Override + protected void run(StructuredGraph graph) { + + Function> blockToNodes; + Function nodeToBlock; + Block startBlock; + + if (fullSchedule) { + SchedulePhase schedule = new SchedulePhase(SchedulePhase.SchedulingStrategy.EARLIEST); + schedule.apply(graph); + ControlFlowGraph cfg = schedule.getCFG(); + cfg.computePostdominators(); + blockToNodes = b -> schedule.getBlockToNodesMap().get(b); + nodeToBlock = n -> schedule.getNodeToBlockMap().get(n); + startBlock = cfg.getStartBlock(); + } else { + ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, false, true, true); + cfg.computePostdominators(); + blockToNodes = b -> b.getNodes(); + nodeToBlock = n -> cfg.blockFor(n); + startBlock = cfg.getStartBlock(); + } + + Instance instance = new Instance(graph, blockToNodes, nodeToBlock); + instance.processBlock(startBlock); + } + + private static class Instance { + + private final NodeMap map; + private final Stack loopExits; + private final Function> blockToNodes; + private final Function nodeToBlock; + + public Instance(StructuredGraph graph, Function> blockToNodes, Function nodeToBlock) { + map = graph.createNodeMap(); + loopExits = new Stack<>(); + this.blockToNodes = blockToNodes; + this.nodeToBlock = nodeToBlock; + } + + private void processBlock(Block block) { + + List undoOperations = new ArrayList<>(); + + if (preprocess(block, undoOperations)) { + + // Process always reached block first. + Block postdominator = block.getPostdominator(); + if (postdominator != null && postdominator.getDominator() == block) { + processBlock(postdominator); + } + + // Now go for the other dominators. + for (Block dominated : block.getDominated()) { + if (dominated != postdominator) { + assert dominated.getDominator() == block; + processBlock(dominated); + } + } + + postprocess(undoOperations); + } + } + + private static void postprocess(List undoOperations) { + for (Runnable r : undoOperations) { + r.run(); + } + } + + private boolean preprocess(Block block, List undoOperations) { + AbstractBeginNode beginNode = block.getBeginNode(); + if (beginNode.isAlive() || (beginNode instanceof MergeNode && beginNode.next().isAlive())) { + if (beginNode instanceof LoopExitNode) { + LoopExitNode loopExitNode = (LoopExitNode) beginNode; + this.loopExits.push(loopExitNode); + undoOperations.add(() -> loopExits.pop()); + } + for (Node n : blockToNodes.apply(block)) { + if (n.isAlive()) { + processNode(n, undoOperations); + } + } + return true; + } else { + // Control flow has been deleted by previous eliminations. + return false; + } + } + + private void processNode(Node node, List undoOperations) { + if (node instanceof AbstractBeginNode) { + processAbstractBegin((AbstractBeginNode) node, undoOperations); + } else if (node instanceof FixedGuardNode) { + processFixedGuard((FixedGuardNode) node, undoOperations); + } else if (node instanceof GuardNode) { + processGuard((GuardNode) node, undoOperations); + } else if (node instanceof CheckCastNode) { + processCheckCast((CheckCastNode) node); + } else if (node instanceof ConditionAnchorNode) { + processConditionAnchor((ConditionAnchorNode) node); + } else if (node instanceof IfNode) { + processIf((IfNode) node); + } else { + return; + } + } + + private void processCheckCast(CheckCastNode node) { + tryProofCondition(node, (guard, result) -> { + if (result) { + PiNode piNode = node.graph().unique(new PiNode(node.object(), node.stamp(), guard)); + node.replaceAtUsages(piNode); + GraphUtil.unlinkFixedNode(node); + node.safeDelete(); + } else { + DeoptimizeNode deopt = node.graph().add(new DeoptimizeNode(InvalidateReprofile, UnreachedCode)); + node.replaceAtPredecessor(deopt); + GraphUtil.killCFG(node); + } + }); + } + + private void processIf(IfNode node) { + tryProofCondition(node.condition(), (guard, result) -> { + AbstractBeginNode survivingSuccessor = node.getSuccessor(result); + survivingSuccessor.replaceAtUsages(InputType.Guard, guard); + survivingSuccessor.replaceAtPredecessor(null); + node.replaceAtPredecessor(survivingSuccessor); + GraphUtil.killCFG(node); + }); + } + + private void registerNewCondition(LogicNode condition, boolean negated, ValueNode guard, List undoOperations) { + if (condition instanceof UnaryOpLogicNode) { + UnaryOpLogicNode unaryLogicNode = (UnaryOpLogicNode) condition; + Stamp newStamp = unaryLogicNode.getSucceedingStampForValue(negated); + registerNewStamp(unaryLogicNode.getValue(), newStamp, guard, undoOperations); + } else if (condition instanceof BinaryOpLogicNode) { + BinaryOpLogicNode binaryOpLogicNode = (BinaryOpLogicNode) condition; + ValueNode x = binaryOpLogicNode.getX(); + if (!x.isConstant()) { + Stamp newStampX = binaryOpLogicNode.getSucceedingStampForX(negated); + registerNewStamp(x, newStampX, guard, undoOperations); + } + + ValueNode y = binaryOpLogicNode.getY(); + if (!y.isConstant()) { + Stamp newStampY = binaryOpLogicNode.getSucceedingStampForY(negated); + registerNewStamp(y, newStampY, guard, undoOperations); + } + registerCondition(condition, negated, guard, undoOperations); + } + } + + private void registerCondition(LogicNode condition, boolean negated, ValueNode guard, List undoOperations) { + this.registerNewStamp(condition, negated ? StampFactory.contradiction() : StampFactory.tautology(), guard, undoOperations); + } + + private Iterable getInfoElements(ValueNode proxiedValue) { + ValueNode value = GraphUtil.unproxify(proxiedValue); + Info info = map.get(value); + if (info == null) { + return Collections.emptyList(); + } else { + return info.getElements(); + } + } + + private boolean rewireGuards(ValueNode guard, boolean result, BiConsumer rewireGuardFunction) { + assert guard instanceof GuardingNode; + metricStampsFound.increment(); + ValueNode proxiedGuard = proxyGuard(guard); + rewireGuardFunction.accept(proxiedGuard, result); + return true; + } + + private ValueNode proxyGuard(ValueNode guard) { + ValueNode proxiedGuard = guard; + if (!this.loopExits.isEmpty()) { + while (proxiedGuard instanceof GuardProxyNode) { + proxiedGuard = ((GuardProxyNode) proxiedGuard).value(); + } + Block guardBlock = nodeToBlock.apply(proxiedGuard); + assert guardBlock != null; + for (int i = 0; i < loopExits.size(); ++i) { + LoopExitNode loopExitNode = loopExits.get(i); + Block loopExitBlock = nodeToBlock.apply(loopExitNode); + if (guardBlock != loopExitBlock && AbstractControlFlowGraph.dominates(guardBlock, loopExitBlock)) { + Block loopBeginBlock = nodeToBlock.apply(loopExitNode.loopBegin()); + if (!AbstractControlFlowGraph.dominates(guardBlock, loopBeginBlock) || guardBlock == loopBeginBlock) { + proxiedGuard = proxiedGuard.graph().unique(new GuardProxyNode((GuardingNode) proxiedGuard, loopExitNode)); + } + } + } + } + return proxiedGuard; + } + + private boolean tryProofCondition(Node node, BiConsumer rewireGuardFunction) { + if (node instanceof UnaryOpLogicNode) { + UnaryOpLogicNode unaryLogicNode = (UnaryOpLogicNode) node; + ValueNode value = unaryLogicNode.getValue(); + for (InfoElement infoElement : getInfoElements(value)) { + Stamp stamp = infoElement.getStamp(); + TriState result = unaryLogicNode.tryFold(stamp); + if (result.isKnown()) { + return rewireGuards(infoElement.getGuard(), result.toBoolean(), rewireGuardFunction); + } + } + } else if (node instanceof BinaryOpLogicNode) { + BinaryOpLogicNode binaryOpLogicNode = (BinaryOpLogicNode) node; + for (InfoElement infoElement : getInfoElements(binaryOpLogicNode)) { + if (infoElement.getStamp().equals(StampFactory.contradiction())) { + return rewireGuards(infoElement.getGuard(), false, rewireGuardFunction); + } else if (infoElement.getStamp().equals(StampFactory.tautology())) { + return rewireGuards(infoElement.getGuard(), true, rewireGuardFunction); + } + } + + ValueNode x = binaryOpLogicNode.getX(); + ValueNode y = binaryOpLogicNode.getY(); + for (InfoElement infoElement : getInfoElements(x)) { + TriState result = binaryOpLogicNode.tryFold(infoElement.getStamp(), y.stamp()); + if (result.isKnown()) { + return rewireGuards(infoElement.getGuard(), result.toBoolean(), rewireGuardFunction); + } + } + + for (InfoElement infoElement : getInfoElements(y)) { + TriState result = binaryOpLogicNode.tryFold(x.stamp(), infoElement.getStamp()); + if (result.isKnown()) { + return rewireGuards(infoElement.getGuard(), result.toBoolean(), rewireGuardFunction); + } + } + } else if (node instanceof CheckCastNode) { + CheckCastNode checkCastNode = (CheckCastNode) node; + for (InfoElement infoElement : getInfoElements(checkCastNode.object())) { + TriState result = checkCastNode.tryFold(infoElement.getStamp()); + if (result.isKnown()) { + return rewireGuards(infoElement.getGuard(), result.toBoolean(), rewireGuardFunction); + } + } + } else if (node instanceof ShortCircuitOrNode) { + final ShortCircuitOrNode shortCircuitOrNode = (ShortCircuitOrNode) node; + if (this.loopExits.isEmpty()) { + tryProofCondition(shortCircuitOrNode.getX(), (guard, result) -> { + if (result == !shortCircuitOrNode.isXNegated()) { + rewireGuards(guard, result, rewireGuardFunction); + } else { + tryProofCondition(shortCircuitOrNode.getY(), (innerGuard, innerResult) -> { + if (innerGuard == guard) { + rewireGuards(guard, shortCircuitOrNode.isYNegated() ? !innerResult : innerResult, rewireGuardFunction); + } + }); + } + }); + } + } + + return false; + } + + private void registerNewStamp(ValueNode proxiedValue, Stamp newStamp, ValueNode guard, List undoOperations) { + if (newStamp != null) { + ValueNode value = GraphUtil.unproxify(proxiedValue); + Info info = map.get(value); + if (info == null) { + info = new Info(); + map.set(value, info); + } + metricStampsRegistered.increment(); + final Info finalInfo = info; + finalInfo.pushElement(new InfoElement(newStamp, guard)); + undoOperations.add(() -> finalInfo.popElement()); + } + } + + private void processConditionAnchor(ConditionAnchorNode node) { + tryProofCondition(node.condition(), (guard, result) -> { + if (result == node.isNegated()) { + node.replaceAtUsages(guard); + GraphUtil.unlinkFixedNode(node); + GraphUtil.killWithUnusedFloatingInputs(node); + } else { + ValueAnchorNode valueAnchor = node.graph().add(new ValueAnchorNode(null)); + node.replaceAtUsages(valueAnchor); + node.graph().replaceFixedWithFixed(node, valueAnchor); + } + }); + } + + private void processGuard(GuardNode node, List undoOperations) { + if (!tryProofCondition(node.condition(), (guard, result) -> { + if (result != node.isNegated()) { + node.replaceAndDelete(guard); + } else { + DeoptimizeNode deopt = node.graph().add(new DeoptimizeNode(node.action(), node.reason())); + Block block = nodeToBlock.apply(node); + FixedNode next = block.getBeginNode().next(); + block.getBeginNode().setNext(deopt); + GraphUtil.killCFG(next); + } + })) { + registerNewCondition(node.condition(), node.isNegated(), node, undoOperations); + } + } + + private void processFixedGuard(FixedGuardNode node, List undoOperations) { + if (!tryProofCondition(node.condition(), (guard, result) -> { + if (result != node.isNegated()) { + node.replaceAtUsages(guard); + GraphUtil.unlinkFixedNode(node); + GraphUtil.killWithUnusedFloatingInputs(node); + } else { + DeoptimizeNode deopt = node.graph().add(new DeoptimizeNode(node.getAction(), node.getReason())); + deopt.setStateBefore(node.stateBefore()); + node.replaceAtPredecessor(deopt); + GraphUtil.killCFG(node); + } + })) { + registerNewCondition(node.condition(), node.isNegated(), node, undoOperations); + } + } + + private void processAbstractBegin(AbstractBeginNode beginNode, List undoOperations) { + Node predecessor = beginNode.predecessor(); + if (predecessor instanceof IfNode) { + IfNode ifNode = (IfNode) predecessor; + boolean negated = (ifNode.falseSuccessor() == beginNode); + LogicNode condition = ifNode.condition(); + registerNewCondition(condition, negated, beginNode, undoOperations); + } else if (predecessor instanceof TypeSwitchNode) { + TypeSwitchNode typeSwitch = (TypeSwitchNode) predecessor; + processTypeSwitch(beginNode, undoOperations, predecessor, typeSwitch); + } else if (predecessor instanceof IntegerSwitchNode) { + IntegerSwitchNode integerSwitchNode = (IntegerSwitchNode) predecessor; + processIntegerSwitch(beginNode, undoOperations, predecessor, integerSwitchNode); + } + } + + private void processIntegerSwitch(AbstractBeginNode beginNode, List undoOperations, Node predecessor, IntegerSwitchNode integerSwitchNode) { + Stamp stamp = null; + for (int i = 0; i < integerSwitchNode.keyCount(); i++) { + if (integerSwitchNode.keySuccessor(i) == predecessor) { + if (stamp == null) { + stamp = StampFactory.forConstant(integerSwitchNode.keyAt(i)); + } else { + stamp = stamp.meet(StampFactory.forConstant(integerSwitchNode.keyAt(i))); + } + } + } + + if (stamp != null) { + registerNewStamp(integerSwitchNode.value(), stamp, beginNode, undoOperations); + } + } + + private void processTypeSwitch(AbstractBeginNode beginNode, List undoOperations, Node predecessor, TypeSwitchNode typeSwitch) { + ValueNode hub = typeSwitch.value(); + if (hub instanceof LoadHubNode) { + LoadHubNode loadHub = (LoadHubNode) hub; + Stamp stamp = null; + for (int i = 0; i < typeSwitch.keyCount(); i++) { + if (typeSwitch.keySuccessor(i) == predecessor) { + if (stamp == null) { + stamp = StampFactory.exactNonNull(typeSwitch.typeAt(i)); + } else { + stamp = stamp.meet(StampFactory.exactNonNull(typeSwitch.typeAt(i))); + } + } + } + if (stamp != null) { + registerNewStamp(loadHub.getValue(), stamp, beginNode, undoOperations); + } + } + } + } +} diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java Mon Mar 09 15:04:08 2015 +0100 @@ -38,19 +38,20 @@ private static final int MAX_ITERATIONS = 256; private final CanonicalizerPhase canonicalizer; + private final boolean fullSchedule; - public IterativeConditionalEliminationPhase(CanonicalizerPhase canonicalizer) { + public IterativeConditionalEliminationPhase(CanonicalizerPhase canonicalizer, boolean fullSchedule) { this.canonicalizer = canonicalizer; + this.fullSchedule = fullSchedule; } @Override protected void run(StructuredGraph graph, PhaseContext context) { - ConditionalEliminationPhase eliminate = new ConditionalEliminationPhase(); - HashSetNodeEventListener listener = new HashSetNodeEventListener().exclude(NODE_ADDED); + HashSetNodeEventListener listener = new HashSetNodeEventListener().exclude(NODE_ADDED).exclude(ZERO_USAGES); int count = 0; while (true) { try (NodeEventScope nes = graph.trackNodeEvents(listener)) { - eliminate.apply(graph); + new DominatorConditionalEliminationPhase(fullSchedule).apply(graph); } if (listener.getNodes().isEmpty()) { break; diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java Mon Mar 09 15:04:08 2015 +0100 @@ -278,7 +278,10 @@ metricInliningTailDuplication.increment(); Debug.log("MultiTypeGuardInlineInfo starting tail duplication (%d opportunities)", opportunities); PhaseContext phaseContext = new PhaseContext(providers); - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue()); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); + if (ImmutableCode.getValue()) { + canonicalizer.disableReadCanonicalization(); + } TailDuplicationPhase.tailDuplicate(returnMerge, TailDuplicationPhase.TRUE_DECISION, replacementNodes, phaseContext, canonicalizer); } } diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Mon Mar 09 15:04:08 2015 +0100 @@ -75,8 +75,6 @@ LATEST_OUT_OF_LOOPS } - static int created; - private class LocationSet { private LocationIdentity firstLocation; private List list; @@ -305,6 +303,7 @@ private BlockMap blockToKillSet; private final SchedulingStrategy selectedStrategy; private boolean scheduleConstants; + private NodeMap nodeToBlockMap; public SchedulePhase() { this(OptScheduleOutOfLoops.getValue() ? SchedulingStrategy.LATEST_OUT_OF_LOOPS : SchedulingStrategy.LATEST); @@ -358,6 +357,11 @@ for (PhiNode phi : mergeNode.phis()) { nodeToBlock.set(phi, b); } + } else if (beginNode instanceof LoopExitNode) { + LoopExitNode loopExitNode = (LoopExitNode) beginNode; + for (ProxyNode proxy : loopExitNode.proxies()) { + nodeToBlock.set(proxy, b); + } } } @@ -378,7 +382,7 @@ if (visited.isMarked(phi)) { for (int i = 0; i < loopBegin.getLoopEndCount(); ++i) { Node node = phi.valueAt(i + loopBegin.forwardEndCount()); - if (!visited.isMarked(node)) { + if (node != null && !visited.isMarked(node)) { stack.push(node); processStack(blockToNodes, nodeToBlock, visited, stack); } @@ -406,6 +410,7 @@ } this.blockToNodesMap = blockToNodes; + this.nodeToBlockMap = nodeToBlock; } private static void addNode(BlockMap> blockToNodes, Block b, ValueNode endNode) { @@ -430,7 +435,9 @@ AbstractMergeNode merge = phiNode.merge(); for (int i = 0; i < merge.forwardEndCount(); ++i) { Node input = phiNode.valueAt(i); - stack.push(input); + if (input != null) { + stack.push(input); + } } } else { for (Node input : current.inputs()) { @@ -561,6 +568,10 @@ return blockToNodesMap; } + public NodeMap getNodeToBlockMap() { + return this.nodeToBlockMap; + } + /** * Gets the nodes in a given block. */ diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ArraysSubstitutionsTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ArraysSubstitutionsTest.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ArraysSubstitutionsTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -332,8 +332,8 @@ public void testCanonicalLength() { StructuredGraph graph = parseEager("testCanonicalLengthSnippet", AllowAssumptions.NO); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new InliningPhase(new CanonicalizerPhase()).apply(graph, context); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); Assert.assertTrue(graph.getNodes(ReturnNode.TYPE).first().result().asJavaConstant().asLong() == 0); } @@ -348,8 +348,8 @@ public void testCanonicalEqual() { StructuredGraph graph = parseEager("testCanonicalEqualSnippet", AllowAssumptions.NO); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new InliningPhase(new CanonicalizerPhase()).apply(graph, context); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); Assert.assertTrue(graph.getNodes(ReturnNode.TYPE).first().result().asJavaConstant().asLong() == 1); } @@ -362,10 +362,10 @@ public void testVirtualEqual() { StructuredGraph graph = parseEager("testVirtualEqualSnippet", AllowAssumptions.NO); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); - new PartialEscapePhase(false, new CanonicalizerPhase(false)).apply(graph, context); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new InliningPhase(new CanonicalizerPhase()).apply(graph, context); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); + new PartialEscapePhase(false, new CanonicalizerPhase()).apply(graph, context); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); Assert.assertTrue(graph.getNodes(ReturnNode.TYPE).first().result().asJavaConstant().asLong() == 1); } @@ -380,10 +380,10 @@ public void testVirtualNotEqual() { StructuredGraph graph = parseEager("testVirtualNotEqualSnippet", AllowAssumptions.NO); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); - new PartialEscapePhase(false, new CanonicalizerPhase(false)).apply(graph, context); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new InliningPhase(new CanonicalizerPhase()).apply(graph, context); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); + new PartialEscapePhase(false, new CanonicalizerPhase()).apply(graph, context); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); Assert.assertTrue(graph.getNodes(ReturnNode.TYPE).first().result().asJavaConstant().asLong() == 0); } diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/BitOpNodesTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/BitOpNodesTest.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/BitOpNodesTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -249,7 +249,7 @@ private ValueNode parseAndInline(String name, Class expectedClass) { StructuredGraph graph = parseEager(name, AllowAssumptions.YES); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.NONE); - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); canonicalizer.apply(graph, context); new InliningPhase(canonicalizer).apply(graph, context); canonicalizer.apply(graph, context); diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/EdgesTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/EdgesTest.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/EdgesTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -116,8 +116,8 @@ ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(method); StructuredGraph g = parseProfiled(javaMethod, AllowAssumptions.NO); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(new InlineMethodSubstitutionsPolicy(), new CanonicalizerPhase(true)).apply(g, context); - new CanonicalizerPhase(false).apply(g, context); + new InliningPhase(new InlineMethodSubstitutionsPolicy(), new CanonicalizerPhase()).apply(g, context); + new CanonicalizerPhase().apply(g, context); Assert.assertTrue(g.getNodes().filter(CheckCastNode.class).isEmpty()); } diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -52,9 +52,9 @@ StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); Debug.dump(graph, "Graph"); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); + new InliningPhase(new CanonicalizerPhase()).apply(graph, context); Debug.dump(graph, "Graph"); - new CanonicalizerPhase(true).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); new DeadCodeEliminationPhase().apply(graph); assertNotInGraph(graph, Invoke.class); diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -403,7 +403,7 @@ HighTierContext context = new HighTierContext(getProviders(), null, null, OptimisticOptimizations.ALL); StructuredGraph graph = parseEager(snippetName, AllowAssumptions.YES); - new CanonicalizerPhase(false).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); Assert.assertEquals(expectedWordCasts, graph.getNodes().filter(WordCastNode.class).count()); } diff -r dc7189b2bb5f -r 7241e6dfcafd graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/TypeCheckTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/TypeCheckTest.java Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/TypeCheckTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -25,7 +25,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.compiler.test.*; import com.oracle.graal.nodes.*; diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Mon Mar 09 15:04:08 2015 +0100 @@ -287,7 +287,7 @@ // Do deferred intrinsification of node intrinsics nodeIntrinsificationPhase.apply(specializedSnippet); - new CanonicalizerPhase(true).apply(specializedSnippet, new PhaseContext(providers)); + new CanonicalizerPhase().apply(specializedSnippet, new PhaseContext(providers)); NodeIntrinsificationVerificationPhase.verify(specializedSnippet); } @@ -627,7 +627,7 @@ afterParsing(graph); if (OptCanonicalizer.getValue()) { - new CanonicalizerPhase(true).apply(graph, new PhaseContext(replacements.providers)); + new CanonicalizerPhase().apply(graph, new PhaseContext(replacements.providers)); } } catch (Throwable e) { throw Debug.handle(e); @@ -659,7 +659,7 @@ */ protected void afterInline(StructuredGraph caller, StructuredGraph callee, Object beforeInlineData) { if (OptCanonicalizer.getValue()) { - new CanonicalizerPhase(true).apply(caller, new PhaseContext(replacements.providers)); + new CanonicalizerPhase().apply(caller, new PhaseContext(replacements.providers)); } } @@ -670,7 +670,7 @@ replacements.nodeIntrinsificationPhase.apply(graph); new DeadCodeEliminationPhase(Optional).apply(graph); if (OptCanonicalizer.getValue()) { - new CanonicalizerPhase(true).apply(graph, new PhaseContext(replacements.providers)); + new CanonicalizerPhase().apply(graph, new PhaseContext(replacements.providers)); } } diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Mon Mar 09 15:04:08 2015 +0100 @@ -670,8 +670,8 @@ if (loopBegin != null) { LoopEx loop = new LoopsData(snippetCopy).loop(loopBegin); Mark mark = snippetCopy.getMark(); - LoopTransformations.fullUnroll(loop, phaseContext, new CanonicalizerPhase(true)); - new CanonicalizerPhase(true).applyIncremental(snippetCopy, phaseContext, mark); + LoopTransformations.fullUnroll(loop, phaseContext, new CanonicalizerPhase()); + new CanonicalizerPhase().applyIncremental(snippetCopy, phaseContext, mark); loop.deleteUnusedNodes(); } GraphUtil.removeFixedWithUnusedInputs(explodeLoop); @@ -686,7 +686,7 @@ } snippetCopy.setGuardsStage(guardsStage); try (Scope s = Debug.scope("LoweringSnippetTemplate", snippetCopy)) { - new LoweringPhase(new CanonicalizerPhase(true), args.cacheKey.loweringStage).apply(snippetCopy, phaseContext); + new LoweringPhase(new CanonicalizerPhase(), args.cacheKey.loweringStage).apply(snippetCopy, phaseContext); } catch (Throwable e) { throw Debug.handle(e); } diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java Mon Mar 09 15:04:08 2015 +0100 @@ -142,7 +142,7 @@ } } try (Scope s = Debug.scope("LoweringSnippetTemplate", replacementGraph)) { - new LoweringPhase(new CanonicalizerPhase(true), tool.getLoweringStage()).apply(replacementGraph, c); + new LoweringPhase(new CanonicalizerPhase(), tool.getLoweringStage()).apply(replacementGraph, c); } catch (Throwable e) { throw Debug.handle(e); } diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Mon Mar 09 15:04:08 2015 +0100 @@ -100,7 +100,7 @@ frameState.replaceAtUsages(null); frameState.safeDelete(); } - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); new DeadCodeEliminationPhase().apply(graph); } diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Mon Mar 09 15:04:08 2015 +0100 @@ -85,7 +85,7 @@ public PartialEvaluator(Providers providers, GraphBuilderConfiguration configForRoot, TruffleCache truffleCache, SnippetReflectionProvider snippetReflection) { this.providers = providers; - this.canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue()); + this.canonicalizer = new CanonicalizerPhase(); this.snippetReflection = snippetReflection; this.truffleCache = truffleCache; this.callDirectMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.getCallDirectMethod()); diff -r dc7189b2bb5f -r 7241e6dfcafd 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 Mon Mar 09 14:22:15 2015 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java Mon Mar 09 15:04:08 2015 +0100 @@ -65,7 +65,7 @@ Map hints = PEAInliningHints.getValue() ? PartialEscapePhase.getHints(graph) : null; - InliningPhase inlining = new InliningPhase(hints, new CanonicalizerPhase(true)); + InliningPhase inlining = new InliningPhase(hints, new CanonicalizerPhase()); inlining.setMaxMethodsPerInlining(simple ? 1 : Integer.MAX_VALUE); inlining.apply(graph, context); progress |= inlining.getInliningCount() > 0; @@ -74,7 +74,7 @@ if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) { canonicalizer.apply(graph, context); - new IterativeConditionalEliminationPhase(canonicalizer).apply(graph, context); + new IterativeConditionalEliminationPhase(canonicalizer, false).apply(graph, context); } if (!progress) { break;