changeset 19709:2fd45bb25118

Initial version of new dominator-based conditional elimination phase.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Sun, 08 Mar 2015 21:58:34 +0100
parents 8f21e30a29c2
children e5028947ea79
files graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest1.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest2.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest3.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest4.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest5.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest6.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest7.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest8.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest9.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTestBase.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GuardEliminationCornerCasesTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfCanonicalizerTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IntegerEqualsCanonicalizerTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeExceptionTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeHintsTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LockEliminationTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LongNodeChainTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LoopUnswitchTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MergeCanonicalizerTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushThroughIfTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReassociateAndCanonicalTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ScalarTypeSystemTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StampCanonicalizerTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StraighteningTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/TypeSystemTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EarlyReadEliminationTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PoorMansEATest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/ArrayCopyNode.java graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/NestedLoop_EA.java graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/LoopPhiCanonicalizerTest.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BinaryOpLogicNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConditionAnchorNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardPhiNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardProxyNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnaryOpLogicNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/PointerEqualsNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DominatorConditionalEliminationPhase.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ArraysSubstitutionsTest.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/BitOpNodesTest.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/EdgesTest.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java
diffstat 92 files changed, 1985 insertions(+), 330 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java	Sun Mar 08 21:58:34 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;
+    }
 }
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java	Sun Mar 08 21:58:34 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.
      */
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java	Sun Mar 08 21:58:34 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);
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java	Sun Mar 08 21:58:34 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);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java	Thu Mar 05 14:26:16 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());
-    }
-
-}
--- /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	Sun Mar 08 21:58:34 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");
+    }
+}
--- /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	Sun Mar 08 21:58:34 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().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().apply(graph, context);
+        canonicalizer.apply(graph, context);
+
+        assertDeepEquals(0, graph.getNodes().filter(GuardNode.class).count());
+    }
+
+}
--- /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	Sun Mar 08 21:58:34 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;
+    }
+}
--- /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	Sun Mar 08 21:58:34 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");
+    }
+}
--- /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	Sun Mar 08 21:58:34 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");
+    }
+}
--- /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	Sun Mar 08 21:58:34 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");
+    }
+}
--- /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	Sun Mar 08 21:58:34 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);
+    }
+}
--- /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	Sun Mar 08 21:58:34 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.
+        testProxies("test1Snippet", 1);
+    }
+}
--- /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	Sun Mar 08 21:58:34 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;
+    }
+}
--- /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	Sun Mar 08 21:58:34 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().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().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);
+    }
+}
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java	Sun Mar 08 21:58:34 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");
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java	Sun Mar 08 21:58:34 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) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java	Sun Mar 08 21:58:34 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;
     }
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java	Sun Mar 08 21:58:34 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;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GuardEliminationCornerCasesTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GuardEliminationCornerCasesTest.java	Sun Mar 08 21:58:34 2015 +0100
@@ -78,7 +78,7 @@
         HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
         StructuredGraph graph = parseEager("testMethod", AllowAssumptions.YES);
         new ConvertDeoptimizeToGuardPhase().apply(graph, context);
-        CanonicalizerPhase canonicalizer = new CanonicalizerPhase(false);
+        CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
         new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
         Debug.dump(graph, "after parsing");
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfCanonicalizerTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfCanonicalizerTest.java	Sun Mar 08 21:58:34 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();
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IntegerEqualsCanonicalizerTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IntegerEqualsCanonicalizerTest.java	Sun Mar 08 21:58:34 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();
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeExceptionTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeExceptionTest.java	Sun Mar 08 21:58:34 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);
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeHintsTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeHintsTest.java	Sun Mar 08 21:58:34 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);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LockEliminationTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LockEliminationTest.java	Sun Mar 08 21:58:34 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;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LongNodeChainTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LongNodeChainTest.java	Sun Mar 08 21:58:34 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());
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LoopUnswitchTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LoopUnswitchTest.java	Sun Mar 08 21:58:34 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) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java	Sun Mar 08 21:58:34 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);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MergeCanonicalizerTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MergeCanonicalizerTest.java	Sun Mar 08 21:58:34 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());
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java	Sun Mar 08 21:58:34 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;
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java	Sun Mar 08 21:58:34 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);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushThroughIfTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushThroughIfTest.java	Sun Mar 08 21:58:34 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);
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java	Sun Mar 08 21:58:34 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);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReassociateAndCanonicalTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReassociateAndCanonicalTest.java	Sun Mar 08 21:58:34 2015 +0100
@@ -244,9 +244,9 @@
 
     private <T extends Node & IterableNodeType> 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);
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ScalarTypeSystemTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ScalarTypeSystemTest.java	Sun Mar 08 21:58:34 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);
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StampCanonicalizerTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StampCanonicalizerTest.java	Sun Mar 08 21:58:34 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);
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StraighteningTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StraighteningTest.java	Sun Mar 08 21:58:34 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);
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/TypeSystemTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/TypeSystemTest.java	Sun Mar 08 21:58:34 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 <T extends Node> void testHelper(String snippet, Class<T> 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());
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java	Sun Mar 08 21:58:34 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)) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java	Sun Mar 08 21:58:34 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);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EarlyReadEliminationTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EarlyReadEliminationTest.java	Sun Mar 08 21:58:34 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);
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java	Sun Mar 08 21:58:34 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();
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java	Sun Mar 08 21:58:34 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);
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java	Sun Mar 08 21:58:34 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);
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java	Sun Mar 08 21:58:34 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());
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PoorMansEATest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PoorMansEATest.java	Sun Mar 08 21:58:34 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);
         }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java	Sun Mar 08 21:58:34 2015 +0100
@@ -236,10 +236,10 @@
             PhaseSuite<HighTierContext> 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) {
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java	Sun Mar 08 21:58:34 2015 +0100
@@ -62,7 +62,7 @@
                    "Thread - aggregate by qualified name and thread", type = OptionType.Debug)
     public static final OptionValue<String> DebugValueSummary = new OptionValue<>("Name");
     @Option(help = "Omit reporting 0-value metrics", type = OptionType.Debug)
-    public static final OptionValue<Boolean> SuppressZeroDebugValues = new OptionValue<>(false);
+    public static final OptionValue<Boolean> SuppressZeroDebugValues = new OptionValue<>(true);
     @Option(help = "Send Graal IR to dump handlers on error", type = OptionType.Debug)
     public static final OptionValue<Boolean> DumpOnError = new OptionValue<>(false);
     @Option(help = "Intercept also bailout exceptions", type = OptionType.Debug)
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java	Sun Mar 08 21:58:34 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);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java	Sun Mar 08 21:58:34 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());
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java	Sun Mar 08 21:58:34 2015 +0100
@@ -34,7 +34,10 @@
 public class MidTier extends PhaseSuite<MidTierContext> {
 
     public MidTier() {
-        CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue());
+        CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+        if (ImmutableCode.getValue()) {
+            canonicalizer.disableReadCanonicalization();
+        }
 
         if (OptPushThroughPi.getValue()) {
             appendPhase(new PushThroughPiPhase());
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java	Sun Mar 08 21:58:34 2015 +0100
@@ -435,15 +435,6 @@
         return false;
     }
 
-    private void clearUsages() {
-        incUsageModCount();
-        maybeNotifyZeroUsages(this);
-        usage0 = null;
-        usage1 = null;
-        extraUsages = NO_NODES;
-        extraUsagesCount = 0;
-    }
-
     public final Node predecessor() {
         return predecessor;
     }
@@ -562,17 +553,27 @@
         return true;
     }
 
-    public void replaceAtUsages(Node other) {
+    public final void replaceAtUsages(Node other) {
+        replaceAtUsages(other, null);
+    }
+
+    public final void replaceAtUsages(Node other, Predicate<Node> 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) {
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java	Sun Mar 08 21:58:34 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");
 
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java	Sun Mar 08 21:58:34 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);
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/ArrayCopyNode.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/ArrayCopyNode.java	Sun Mar 08 21:58:34 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
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/NestedLoop_EA.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/NestedLoop_EA.java	Sun Mar 08 21:58:34 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<BasePhase<? super HighTierContext>> 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));
--- a/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/LoopPhiCanonicalizerTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/LoopPhiCanonicalizerTest.java	Sun Mar 08 21:58:34 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");
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BinaryOpLogicNode.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BinaryOpLogicNode.java	Sun Mar 08 21:58:34 2015 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.nodes;
 
+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 +84,10 @@
         }
         return this;
     }
+
+    public abstract Stamp getSucceedingStampForX(boolean negated);
+
+    public abstract Stamp getSucceedingStampForY(boolean negated);
+
+    public abstract Boolean tryFold(Stamp xStamp, Stamp yStamp);
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConditionAnchorNode.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConditionAnchorNode.java	Sun Mar 08 21:58:34 2015 +0100
@@ -76,6 +76,9 @@
                 return new ValueAnchorNode(null);
             }
         }
+        if (this.hasNoUsages()) {
+            return null;
+        }
         return this;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardPhiNode.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardPhiNode.java	Sun Mar 08 21:58:34 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<ValueNode> values() {
         return values;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardProxyNode.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardProxyNode.java	Sun Mar 08 21:58:34 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();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Sun Mar 08 21:58:34 2015 +0100
@@ -1133,4 +1133,8 @@
     public AbstractBeginNode getPrimarySuccessor() {
         return this.trueSuccessor();
     }
+
+    public AbstractBeginNode getSuccessor(boolean result) {
+        return result ? this.trueSuccessor() : this.falseSuccessor();
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Sun Mar 08 21:58:34 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();
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnaryOpLogicNode.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnaryOpLogicNode.java	Sun Mar 08 21:58:34 2015 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.nodes;
 
+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 +47,8 @@
     @Override
     public void generate(NodeLIRBuilderTool gen) {
     }
+
+    public abstract Stamp getSucceedingStampForValue(boolean negated);
+
+    public abstract Boolean tryFold(Stamp valueStamp);
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java	Sun Mar 08 21:58:34 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 Boolean 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 false;
+            } else if (xStamp.neverDistinct(yStamp)) {
+                return true;
+            }
+        }
+        return null;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java	Sun Mar 08 21:58:34 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 Boolean tryFold(Stamp xStampGeneric, Stamp yStampGeneric) {
+        return null;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowNode.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowNode.java	Sun Mar 08 21:58:34 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 Boolean 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 true;
+                    } else if (xStamp.isStrictlyNegative() || xStamp.lowerBound() >= yStamp.upperBound()) {
+                        return false;
+                    }
+                }
+            }
+        }
+        return null;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java	Sun Mar 08 21:58:34 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 Boolean 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 false;
+            } else if (xStamp.neverDistinct(yStamp)) {
+                return true;
+            }
+        }
+        return null;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java	Sun Mar 08 21:58:34 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 Boolean 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 true;
+            }
+            if (xStamp.lowerBound() >= yStamp.upperBound()) {
+                return false;
+            }
+        }
+        return null;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java	Sun Mar 08 21:58:34 2015 +0100
@@ -58,4 +58,19 @@
         }
         return this;
     }
+
+    @Override
+    public Stamp getSucceedingStampForX(boolean negated) {
+        return null;
+    }
+
+    @Override
+    public Stamp getSucceedingStampForY(boolean negated) {
+        return null;
+    }
+
+    @Override
+    public Boolean tryFold(Stamp xStampGeneric, Stamp yStampGeneric) {
+        return null;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java	Sun Mar 08 21:58:34 2015 +0100
@@ -86,4 +86,22 @@
 
     @NodeIntrinsic
     public static native IsNullNode isNull(Object object);
+
+    @Override
+    public Stamp getSucceedingStampForValue(boolean negated) {
+        return negated ? StampFactory.objectNonNull() : StampFactory.alwaysNull();
+    }
+
+    @Override
+    public Boolean tryFold(Stamp valueStamp) {
+        if (valueStamp instanceof ObjectStamp) {
+            ObjectStamp objectStamp = (ObjectStamp) valueStamp;
+            if (objectStamp.alwaysNull()) {
+                return true;
+            } else if (objectStamp.nonNull()) {
+                return false;
+            }
+        }
+        return null;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/PointerEqualsNode.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/PointerEqualsNode.java	Sun Mar 08 21:58:34 2015 +0100
@@ -73,4 +73,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 Boolean 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 false;
+            } else if (xStamp.neverDistinct(yStamp)) {
+                return true;
+            }
+        }
+        return null;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java	Sun Mar 08 21:58:34 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.
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java	Sun Mar 08 21:58:34 2015 +0100
@@ -239,4 +239,17 @@
     public ValueNode getOriginalNode() {
         return object;
     }
+
+    public Boolean tryFold(Stamp testStamp) {
+        if (testStamp instanceof ObjectStamp) {
+            ObjectStamp objectStamp = (ObjectStamp) testStamp;
+            ResolvedJavaType objectType = objectStamp.type();
+            if (objectType != null && type.isAssignableFrom(objectType)) {
+                return true;
+            } else if (objectStamp.alwaysNull()) {
+                return true;
+            }
+        }
+        return null;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java	Sun Mar 08 21:58:34 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 StampFactory.object();
+        } else {
+            return StampFactory.declaredTrustedNonNull(type);
+        }
+    }
+
+    @Override
+    public Boolean tryFold(Stamp valueStamp) {
+        if (valueStamp instanceof ObjectStamp) {
+            ObjectStamp objectStamp = (ObjectStamp) valueStamp;
+            if (objectStamp.alwaysNull()) {
+                return false;
+            }
+
+            ResolvedJavaType objectType = objectStamp.type();
+            if (objectType != null) {
+                ResolvedJavaType instanceofType = type;
+                if (instanceofType.isAssignableFrom(objectType)) {
+                    if (objectStamp.nonNull()) {
+                        return true;
+                    }
+                } else {
+                    if (objectStamp.isExactType()) {
+                        return false;
+                    } else {
+                        boolean superType = objectType.isAssignableFrom(instanceofType);
+                        if (!superType && !objectType.isInterface() && !instanceofType.isInterface()) {
+                            return false;
+                        }
+                    }
+                }
+            }
+        }
+        return null;
+    }
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Sun Mar 08 21:58:34 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<? extends Node> 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<? extends Node> workingSet, Mark newNodesMark) {
@@ -110,38 +97,34 @@
     }
 
     public void applyIncremental(StructuredGraph graph, PhaseContext context, Iterable<? extends Node> 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<? extends Node> 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<? extends Node> workingSet, CustomCanonicalizer customCanonicalizer) {
-            this(context, canonicalizeReads, workingSet, null, customCanonicalizer);
+        private Instance(PhaseContext context, Iterable<? extends Node> 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<? extends Node> workingSet, Mark newNodesMark, CustomCanonicalizer customCanonicalizer) {
+        private Instance(PhaseContext context, Iterable<? extends Node> 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)) {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Sun Mar 08 21:58:34 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);
--- /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	Sun Mar 08 21:58:34 2015 +0100
@@ -0,0 +1,448 @@
+/*
+ * 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 java.util.*;
+import java.util.function.*;
+
+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");
+
+    public DominatorConditionalEliminationPhase() {
+    }
+
+    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<InfoElement> infos;
+
+        public Info() {
+            infos = new ArrayList<>();
+        }
+
+        public Iterable<InfoElement> 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) {
+        SchedulePhase schedule = new SchedulePhase(SchedulePhase.SchedulingStrategy.EARLIEST);
+        schedule.apply(graph);
+        ControlFlowGraph cfg = schedule.getCFG();
+        cfg.computePostdominators();
+        Instance instance = new Instance(graph, b -> schedule.getBlockToNodesMap().get(b), n -> schedule.getNodeToBlockMap().get(n));
+        instance.processBlock(cfg.getStartBlock());
+    }
+
+    private static class Instance {
+
+        private final NodeMap<Info> map;
+        private final Stack<LoopExitNode> loopExits;
+        private final Function<Block, Iterable<? extends Node>> blockToNodes;
+        private final Function<Node, Block> nodeToBlock;
+
+        public Instance(StructuredGraph graph, Function<Block, Iterable<? extends Node>> blockToNodes, Function<Node, Block> nodeToBlock) {
+            map = graph.createNodeMap();
+            loopExits = new Stack<>();
+            this.blockToNodes = blockToNodes;
+            this.nodeToBlock = nodeToBlock;
+        }
+
+        private void processBlock(Block block) {
+
+            List<Runnable> 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<Runnable> undoOperations) {
+            for (Runnable r : undoOperations) {
+                r.run();
+            }
+        }
+
+        private boolean preprocess(Block block, List<Runnable> 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, block, undoOperations);
+                    }
+                }
+                return true;
+            } else {
+                // Control flow has been deleted by previous eliminations.
+                return false;
+            }
+        }
+
+        private void processNode(Node node, Block block, List<Runnable> undoOperations) {
+            if (node instanceof AbstractBeginNode) {
+                processAbstractBegin((AbstractBeginNode) node, undoOperations);
+            } else if (node instanceof FixedGuardNode) {
+                processFixedGuard((FixedGuardNode) node, block, undoOperations);
+            } else if (node instanceof GuardNode) {
+                processGuard((GuardNode) node, block, undoOperations);
+            } else if (node instanceof CheckCastNode) {
+                processCheckCast((CheckCastNode) node, block);
+            } else if (node instanceof ConditionAnchorNode) {
+                processConditionAnchor((ConditionAnchorNode) node, block);
+            } else if (node instanceof IfNode) {
+                processIf((IfNode) node, block);
+            } else {
+                return;
+            }
+        }
+
+        private void processCheckCast(CheckCastNode node, Block block) {
+            tryProofCondition(node, block, (guard, result) -> {
+                if (result) {
+                    PiNode piNode = node.graph().unique(new PiNode(node.object(), node.stamp(), guard));
+                    node.replaceAtUsages(piNode);
+                    GraphUtil.unlinkFixedNode(node);
+                    node.safeDelete();
+                }
+            });
+        }
+
+        private void processIf(IfNode node, Block block) {
+            tryProofCondition(node.condition(), block, (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<Runnable> 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<Runnable> undoOperations) {
+            this.registerNewStamp(condition, negated ? StampFactory.contradiction() : StampFactory.tautology(), guard, undoOperations);
+        }
+
+        private Iterable<InfoElement> 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, Block block, BiConsumer<ValueNode, Boolean> rewireGuardFunction) {
+            assert guard instanceof GuardingNode;
+            metricStampsFound.increment();
+            ValueNode proxiedGuard = proxyGuard(guard, block);
+            rewireGuardFunction.accept(proxiedGuard, result);
+            return true;
+        }
+
+        private ValueNode proxyGuard(ValueNode guard, Block block) {
+            ValueNode proxiedGuard = guard;
+            if (!this.loopExits.isEmpty()) {
+                while (proxiedGuard instanceof GuardProxyNode) {
+                    proxiedGuard = ((GuardProxyNode) proxiedGuard).value();
+                }
+                ValueNode initialProxiedGuard = proxiedGuard;
+                Block guardBlock = nodeToBlock.apply(proxiedGuard);
+                assert guardBlock != null;
+                Block curBlock = block;
+                if (guardBlock != curBlock) {
+                    int loopExitIndex = loopExits.size() - 1;
+                    GuardProxyNode lastProxy = null;
+                    do {
+                        LoopExitNode loopExitNode = loopExits.get(loopExitIndex);
+                        Block loopExitBlock = nodeToBlock.apply(loopExitNode);
+                        assert loopExitBlock != null;
+                        if (loopExitBlock == curBlock) {
+                            assert curBlock != guardBlock;
+                            GuardProxyNode guardProxy = proxiedGuard.graph().unique(new GuardProxyNode((GuardingNode) initialProxiedGuard, loopExitNode));
+                            if (lastProxy == null) {
+                                proxiedGuard = guardProxy;
+                            } else {
+                                lastProxy.setValue(guardProxy);
+                            }
+                            lastProxy = guardProxy;
+                            loopExitIndex--;
+                            if (loopExitIndex < 0) {
+                                break;
+                            }
+                        }
+                        curBlock = curBlock.getDominator();
+                    } while (guardBlock != curBlock);
+                }
+            }
+            return proxiedGuard;
+        }
+
+        private boolean tryProofCondition(Node node, Block block, BiConsumer<ValueNode, Boolean> rewireGuardFunction) {
+            if (node instanceof UnaryOpLogicNode) {
+                UnaryOpLogicNode unaryLogicNode = (UnaryOpLogicNode) node;
+                ValueNode value = unaryLogicNode.getValue();
+                for (InfoElement infoElement : getInfoElements(value)) {
+                    Stamp stamp = infoElement.getStamp();
+                    Boolean result = unaryLogicNode.tryFold(stamp);
+                    if (result != null) {
+                        return rewireGuards(infoElement.getGuard(), result, block, 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, block, rewireGuardFunction);
+                    } else if (infoElement.getStamp().equals(StampFactory.tautology())) {
+                        return rewireGuards(infoElement.getGuard(), true, block, rewireGuardFunction);
+                    }
+                }
+
+                ValueNode x = binaryOpLogicNode.getX();
+                ValueNode y = binaryOpLogicNode.getY();
+                for (InfoElement infoElement : getInfoElements(x)) {
+                    Boolean result = binaryOpLogicNode.tryFold(infoElement.getStamp(), y.stamp());
+                    if (result != null) {
+                        return rewireGuards(infoElement.getGuard(), result, block, rewireGuardFunction);
+                    }
+                }
+
+                for (InfoElement infoElement : getInfoElements(y)) {
+                    Boolean result = binaryOpLogicNode.tryFold(x.stamp(), infoElement.getStamp());
+                    if (result != null) {
+                        return rewireGuards(infoElement.getGuard(), result, block, rewireGuardFunction);
+                    }
+                }
+            } else if (node instanceof CheckCastNode) {
+                CheckCastNode checkCastNode = (CheckCastNode) node;
+                for (InfoElement infoElement : getInfoElements(checkCastNode.object())) {
+                    Boolean result = checkCastNode.tryFold(infoElement.getStamp());
+                    if (result != null) {
+                        return rewireGuards(infoElement.getGuard(), result, block, rewireGuardFunction);
+                    }
+                }
+            } else if (node instanceof ShortCircuitOrNode) {
+                final ShortCircuitOrNode shortCircuitOrNode = (ShortCircuitOrNode) node;
+                tryProofCondition(shortCircuitOrNode.getX(), block, (guard, result) -> {
+                    if (result == !shortCircuitOrNode.isXNegated()) {
+                        rewireGuards(guard, result, block, rewireGuardFunction);
+                    } else {
+                        tryProofCondition(shortCircuitOrNode.getY(), block, (innerGuard, innerResult) -> {
+                            if (innerGuard == guard) {
+                                rewireGuards(guard, shortCircuitOrNode.isYNegated() ? !innerResult : innerResult, block, rewireGuardFunction);
+                            }
+                        });
+                    }
+                });
+            }
+
+            return false;
+        }
+
+        private void registerNewStamp(ValueNode proxiedValue, Stamp newStamp, ValueNode guard, List<Runnable> 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, Block block) {
+            tryProofCondition(node.condition(), block, (guard, result) -> {
+                if (result == node.isNegated()) {
+                    node.replaceAtUsages(guard);
+                    GraphUtil.unlinkFixedNode(node);
+                    GraphUtil.killWithUnusedFloatingInputs(node);
+                }
+            });
+        }
+
+        private void processGuard(GuardNode node, Block block, List<Runnable> undoOperations) {
+            if (!tryProofCondition(node.condition(), block, (guard, result) -> {
+                if (result != node.isNegated()) {
+                    node.replaceAndDelete(guard);
+                }
+            })) {
+                registerNewCondition(node.condition(), node.isNegated(), node, undoOperations);
+            }
+        }
+
+        private void processFixedGuard(FixedGuardNode node, Block block, List<Runnable> undoOperations) {
+            if (!tryProofCondition(node.condition(), block, (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<Runnable> 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<Runnable> 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<Runnable> 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);
+                }
+            }
+        }
+    }
+}
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java	Sun Mar 08 21:58:34 2015 +0100
@@ -45,10 +45,12 @@
 
     @Override
     protected void run(StructuredGraph graph, PhaseContext context) {
+
         ConditionalEliminationPhase eliminate = new ConditionalEliminationPhase();
         HashSetNodeEventListener listener = new HashSetNodeEventListener().exclude(NODE_ADDED);
         int count = 0;
         while (true) {
+            new DominatorConditionalEliminationPhase().apply(graph);
             try (NodeEventScope nes = graph.trackNodeEvents(listener)) {
                 eliminate.apply(graph);
             }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java	Sun Mar 08 21:58:34 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);
             }
         }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Sun Mar 08 21:58:34 2015 +0100
@@ -75,8 +75,6 @@
         LATEST_OUT_OF_LOOPS
     }
 
-    static int created;
-
     private class LocationSet {
         private LocationIdentity firstLocation;
         private List<LocationIdentity> list;
@@ -305,6 +303,7 @@
     private BlockMap<LocationSet> blockToKillSet;
     private final SchedulingStrategy selectedStrategy;
     private boolean scheduleConstants;
+    private NodeMap<Block> nodeToBlockMap;
 
     public SchedulePhase() {
         this(OptScheduleOutOfLoops.getValue() ? SchedulingStrategy.LATEST_OUT_OF_LOOPS : SchedulingStrategy.LATEST);
@@ -378,7 +377,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 +405,7 @@
         }
 
         this.blockToNodesMap = blockToNodes;
+        this.nodeToBlockMap = nodeToBlock;
     }
 
     private static void addNode(BlockMap<List<ValueNode>> blockToNodes, Block b, ValueNode endNode) {
@@ -430,7 +430,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 +563,10 @@
         return blockToNodesMap;
     }
 
+    public NodeMap<Block> getNodeToBlockMap() {
+        return this.nodeToBlockMap;
+    }
+
     /**
      * Gets the nodes in a given block.
      */
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ArraysSubstitutionsTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ArraysSubstitutionsTest.java	Sun Mar 08 21:58:34 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);
     }
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/BitOpNodesTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/BitOpNodesTest.java	Sun Mar 08 21:58:34 2015 +0100
@@ -249,7 +249,7 @@
     private ValueNode parseAndInline(String name, Class<? extends ValueNode> 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);
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/EdgesTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/EdgesTest.java	Sun Mar 08 21:58:34 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());
     }
 
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java	Sun Mar 08 21:58:34 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);
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java	Sun Mar 08 21:58:34 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());
     }
 
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Sun Mar 08 21:58:34 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));
             }
         }
 
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Sun Mar 08 21:58:34 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);
         }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Sun Mar 08 21:58:34 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);
         }
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Sun Mar 08 21:58:34 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);
     }
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Sun Mar 08 21:58:34 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());
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java	Thu Mar 05 14:26:16 2015 +0100
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java	Sun Mar 08 21:58:34 2015 +0100
@@ -65,7 +65,7 @@
 
                 Map<Invoke, Double> 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;