changeset 9274:90c3837d6a1c

Merge.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Tue, 23 Apr 2013 20:16:45 +0200
parents d27550f2f80f (current diff) 7409a84b6001 (diff)
children 76afb8f4c930
files
diffstat 29 files changed, 275 insertions(+), 166 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java	Tue Apr 23 20:16:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java	Tue Apr 23 20:16:45 2013 +0200
@@ -307,7 +307,7 @@
     private void processMethod(final String snippet) {
         graph = parse(snippet);
         Assumptions assumptions = new Assumptions(false);
-        HighTierContext context = new HighTierContext(runtime(), assumptions);
+        HighTierContext context = new HighTierContext(runtime(), assumptions, replacements);
         new InliningPhase(runtime(), null, replacements, assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph);
         new PartialEscapeAnalysisPhase(false, false).apply(graph, context);
         new CullFrameStatesPhase().apply(graph);
@@ -325,7 +325,7 @@
                 graph = parse(snippet);
 
                 Assumptions assumptions = new Assumptions(false);
-                HighTierContext context = new HighTierContext(runtime(), assumptions);
+                HighTierContext context = new HighTierContext(runtime(), assumptions, replacements);
                 new InliningPhase(runtime(), null, replacements, assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph);
                 if (loopPeeling) {
                     new LoopTransformHighPhase().apply(graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java	Tue Apr 23 20:16:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java	Tue Apr 23 20:16:45 2013 +0200
@@ -31,6 +31,7 @@
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.Lowerable.*;
 import com.oracle.graal.phases.common.*;
+import com.oracle.graal.phases.tiers.*;
 
 public class FloatingReadTest extends GraphScheduleTest {
 
@@ -58,7 +59,8 @@
 
             public void run() {
                 StructuredGraph graph = parse(snippet);
-                new LoweringPhase(null, runtime(), replacements, new Assumptions(false), LoweringType.BEFORE_GUARDS).apply(graph);
+                HighTierContext context = new HighTierContext(runtime(), new Assumptions(false), replacements);
+                new LoweringPhase(LoweringType.BEFORE_GUARDS).apply(graph, context);
                 new FloatingReadPhase().apply(graph);
 
                 ReturnNode returnNode = null;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java	Tue Apr 23 20:16:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java	Tue Apr 23 20:16:45 2013 +0200
@@ -38,6 +38,7 @@
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.schedule.*;
+import com.oracle.graal.phases.tiers.*;
 
 /**
  * In these test the FrameStates are explicitly cleared out, so that the scheduling of
@@ -222,7 +223,8 @@
                     Assumptions assumptions = new Assumptions(false);
                     new InliningPhase(runtime(), null, replacements, assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph);
                 }
-                new LoweringPhase(null, runtime(), replacements, new Assumptions(false), LoweringType.BEFORE_GUARDS).apply(graph);
+                HighTierContext context = new HighTierContext(runtime(), new Assumptions(false), replacements);
+                new LoweringPhase(LoweringType.BEFORE_GUARDS).apply(graph, context);
                 if (mode == TestMode.WITHOUT_FRAMESTATES || mode == TestMode.INLINED_WITHOUT_FRAMESTATES) {
                     for (Node node : graph.getNodes()) {
                         if (node instanceof StateSplit) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java	Tue Apr 23 20:16:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java	Tue Apr 23 20:16:45 2013 +0200
@@ -34,6 +34,7 @@
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.Lowerable.*;
 import com.oracle.graal.phases.common.*;
+import com.oracle.graal.phases.tiers.*;
 
 public class PushNodesThroughPiTest extends GraalCompilerTest {
 
@@ -83,10 +84,11 @@
 
     private StructuredGraph compileTestSnippet(final String snippet) {
         StructuredGraph graph = parse(snippet);
-        new LoweringPhase(null, runtime(), replacements, new Assumptions(false), LoweringType.BEFORE_GUARDS).apply(graph);
-        new CanonicalizerPhase.Instance(runtime(), null).apply(graph);
+        HighTierContext context = new HighTierContext(runtime(), new Assumptions(false), replacements);
+        new LoweringPhase(LoweringType.BEFORE_GUARDS).apply(graph, context);
+        new CanonicalizerPhase().apply(graph, context);
         new PushThroughPiPhase().apply(graph);
-        new CanonicalizerPhase.Instance(runtime(), null).apply(graph);
+        new CanonicalizerPhase().apply(graph, context);
 
         return graph;
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java	Tue Apr 23 20:16:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java	Tue Apr 23 20:16:45 2013 +0200
@@ -34,6 +34,7 @@
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.Lowerable.*;
 import com.oracle.graal.phases.common.*;
+import com.oracle.graal.phases.tiers.*;
 
 /* consider
  *     B b = (B) a;
@@ -86,11 +87,12 @@
             // structure changes significantly
             public void run() {
                 StructuredGraph graph = parse(snippet);
-                new LoweringPhase(null, runtime(), replacements, new Assumptions(false), LoweringType.BEFORE_GUARDS).apply(graph);
+                HighTierContext context = new HighTierContext(runtime(), new Assumptions(false), replacements);
+                new LoweringPhase(LoweringType.BEFORE_GUARDS).apply(graph, context);
                 new FloatingReadPhase().apply(graph);
                 new EliminatePartiallyRedundantGuardsPhase(true, false).apply(graph);
                 new ReadEliminationPhase().apply(graph);
-                new CanonicalizerPhase.Instance(runtime(), null).apply(graph);
+                new CanonicalizerPhase().apply(graph, context);
 
                 Debug.dump(graph, "After lowering");
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/WriteBarrierAdditionTest.java	Tue Apr 23 20:16:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/WriteBarrierAdditionTest.java	Tue Apr 23 20:16:45 2013 +0200
@@ -32,6 +32,7 @@
 import com.oracle.graal.nodes.extended.WriteNode.WriteBarrierType;
 import com.oracle.graal.nodes.spi.Lowerable.*;
 import com.oracle.graal.phases.common.*;
+import com.oracle.graal.phases.tiers.*;
 
 public class WriteBarrierAdditionTest extends GraalCompilerTest {
 
@@ -98,7 +99,8 @@
 
             public void run() {
                 StructuredGraph graph = parse(snippet);
-                new LoweringPhase(null, runtime(), replacements, new Assumptions(false), LoweringType.BEFORE_GUARDS).apply(graph);
+                HighTierContext context = new HighTierContext(runtime(), new Assumptions(false), replacements);
+                new LoweringPhase(LoweringType.BEFORE_GUARDS).apply(graph, context);
                 new WriteBarrierAdditionPhase().apply(graph);
                 Debug.dump(graph, "After Write Barrier Addition");
                 final int barriers = graph.getNodes(SerialWriteBarrier.class).count();
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java	Tue Apr 23 20:16:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java	Tue Apr 23 20:16:45 2013 +0200
@@ -220,7 +220,7 @@
                 new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
 
                 Assumptions assumptions = new Assumptions(false);
-                HighTierContext context = new HighTierContext(runtime(), assumptions);
+                HighTierContext context = new HighTierContext(runtime(), assumptions, replacements);
                 new InliningPhase(runtime(), null, replacements, assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph);
                 new DeadCodeEliminationPhase().apply(graph);
                 new PartialEscapeAnalysisPhase(iterativeEscapeAnalysis, false).apply(graph, context);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java	Tue Apr 23 20:16:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java	Tue Apr 23 20:16:45 2013 +0200
@@ -101,7 +101,7 @@
     private void processMethod(final String snippet) {
         graph = parse(snippet);
         GraalOptions.OptEarlyReadElimination = true;
-        HighTierContext context = new HighTierContext(runtime(), new Assumptions(false));
+        HighTierContext context = new HighTierContext(runtime(), new Assumptions(false), replacements);
         new IterativeInliningPhase(replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL, false).apply(graph, context);
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java	Tue Apr 23 20:16:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java	Tue Apr 23 20:16:45 2013 +0200
@@ -222,7 +222,7 @@
     private void processMethod(final String snippet) {
         graph = parse(snippet);
         Assumptions assumptions = new Assumptions(false);
-        HighTierContext context = new HighTierContext(runtime(), assumptions);
+        HighTierContext context = new HighTierContext(runtime(), assumptions, replacements);
         new InliningPhase(runtime(), null, replacements, assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph);
         new PartialEscapeAnalysisPhase(false, true).apply(graph, context);
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java	Tue Apr 23 20:16:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java	Tue Apr 23 20:16:45 2013 +0200
@@ -162,7 +162,7 @@
                 StructuredGraph graph = parse(snippet);
 
                 Assumptions assumptions = new Assumptions(false);
-                HighTierContext context = new HighTierContext(runtime(), assumptions);
+                HighTierContext context = new HighTierContext(runtime(), assumptions, replacements);
                 new InliningPhase(runtime(), null, replacements, assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph);
                 new DeadCodeEliminationPhase().apply(graph);
                 new CanonicalizerPhase().apply(graph, context);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Tue Apr 23 20:16:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Tue Apr 23 20:16:45 2013 +0200
@@ -38,7 +38,6 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.cfg.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.spi.Lowerable.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
@@ -120,7 +119,7 @@
             new CanonicalizerPhase.Instance(runtime, assumptions).apply(graph);
         }
 
-        HighTierContext highTierContext = new HighTierContext(runtime, assumptions);
+        HighTierContext highTierContext = new HighTierContext(runtime, assumptions, replacements);
 
         if (GraalOptions.Inline && !plan.isPhaseDisabled(InliningPhase.class)) {
             if (GraalOptions.IterativeInlining) {
@@ -140,25 +139,13 @@
 
         Suites.DEFAULT.getHighTier().apply(graph, highTierContext);
 
-        new LoweringPhase(target, runtime, replacements, assumptions, LoweringType.BEFORE_GUARDS).apply(graph);
-
-        MidTierContext midTierContext = new MidTierContext(runtime, assumptions, replacements);
+        MidTierContext midTierContext = new MidTierContext(runtime, assumptions, replacements, target);
         Suites.DEFAULT.getMidTier().apply(graph, midTierContext);
 
-        plan.runPhases(PhasePosition.MID_LEVEL, graph);
-
-        // Add safepoints to loops
-        new SafepointInsertionPhase().apply(graph);
-
-        new GuardLoweringPhase(target).apply(graph);
-
         plan.runPhases(PhasePosition.LOW_LEVEL, graph);
 
-        new LoweringPhase(target, runtime, replacements, assumptions, LoweringType.AFTER_GUARDS).apply(graph);
-
-        new FrameStateAssignmentPhase().apply(graph);
-
-        new DeadCodeEliminationPhase().apply(graph);
+        LowTierContext lowTierContext = new LowTierContext(runtime, assumptions, replacements, target);
+        Suites.DEFAULT.getLowTier().apply(graph, lowTierContext);
 
         final SchedulePhase schedule = new SchedulePhase();
         schedule.apply(graph);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/BasicCompilerConfiguration.java	Tue Apr 23 20:16:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/BasicCompilerConfiguration.java	Tue Apr 23 20:16:45 2013 +0200
@@ -36,4 +36,8 @@
     public PhaseSuite<MidTierContext> createMidTier() {
         return new MidTier();
     }
+
+    public PhaseSuite<LowTierContext> createLowTier() {
+        return new LowTier();
+    }
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java	Tue Apr 23 20:16:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java	Tue Apr 23 20:16:45 2013 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.compiler.phases;
 
 import com.oracle.graal.loop.phases.*;
+import com.oracle.graal.nodes.spi.Lowerable.LoweringType;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.tiers.*;
@@ -68,6 +69,8 @@
         if (GraalOptions.OptCanonicalizer) {
             addPhase(new CanonicalizerPhase());
         }
+
+        addPhase(new LoweringPhase(LoweringType.BEFORE_GUARDS));
     }
 
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java	Tue Apr 23 20:16:45 2013 +0200
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.compiler.phases;
+
+import com.oracle.graal.nodes.spi.Lowerable.LoweringType;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.common.*;
+import com.oracle.graal.phases.tiers.*;
+
+public class LowTier extends PhaseSuite<LowTierContext> {
+
+    public LowTier() {
+        addPhase(new LoweringPhase(LoweringType.AFTER_GUARDS));
+
+        addPhase(new FrameStateAssignmentPhase());
+
+        addPhase(new DeadCodeEliminationPhase());
+    }
+}
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java	Tue Apr 23 20:16:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java	Tue Apr 23 20:16:45 2013 +0200
@@ -65,5 +65,10 @@
         if (GraalOptions.OptCanonicalizer) {
             addPhase(new CanonicalizerPhase());
         }
+
+        // Add safepoints to loops
+        addPhase(new SafepointInsertionPhase());
+
+        addPhase(new GuardLoweringPhase());
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java	Tue Apr 23 20:16:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java	Tue Apr 23 20:16:45 2013 +0200
@@ -82,7 +82,7 @@
         }
         // the canonicalization before loop unrolling is needed to propagate the length into
         // additions, etc.
-        HighTierContext context = new HighTierContext(tool.getRuntime(), tool.assumptions());
+        HighTierContext context = new HighTierContext(tool.getRuntime(), tool.assumptions(), tool.getReplacements());
         new CanonicalizerPhase().apply(snippetGraph, context);
         new LoopFullUnrollPhase().apply(snippetGraph, context);
         new CanonicalizerPhase().apply(snippetGraph, context);
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java	Tue Apr 23 20:16:34 2013 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java	Tue Apr 23 20:16:45 2013 +0200
@@ -117,6 +117,6 @@
 
     @Override
     public String toString() {
-        return debugInfo != null ? debugInfo.toString() : topFrame.toString();
+        return debugInfo != null ? debugInfo.toString() : topFrame != null ? topFrame.toString() : "<empty>";
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java	Tue Apr 23 20:16:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java	Tue Apr 23 20:16:45 2013 +0200
@@ -30,8 +30,6 @@
 
 public interface LoweringTool {
 
-    TargetDescription getTarget();
-
     GraalCodeCacheProvider getRuntime();
 
     Replacements getReplacements();
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeadCodeEliminationPhase.java	Tue Apr 23 20:16:34 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeadCodeEliminationPhase.java	Tue Apr 23 20:16:45 2013 +0200
@@ -32,17 +32,15 @@
     // Metrics
     private static final DebugMetric metricNodesRemoved = Debug.metric("NodesRemoved");
 
-    private NodeFlood flood;
-
     @Override
     protected void run(StructuredGraph graph) {
-        this.flood = graph.createNodeFlood();
+        NodeFlood flood = graph.createNodeFlood();
 
         flood.add(graph.start());
-        iterateSuccessors();
-        disconnectCFGNodes(graph);
-        iterateInputs(graph);
-        deleteNodes(graph);
+        iterateSuccessors(flood);
+        disconnectCFGNodes(flood, graph);
+        iterateInputs(flood, graph);
+        deleteNodes(flood, graph);
 
         // remove chained Merges
         for (MergeNode merge : graph.getNodes(MergeNode.class)) {
@@ -52,7 +50,7 @@
         }
     }
 
-    private void iterateSuccessors() {
+    private static void iterateSuccessors(NodeFlood flood) {
         for (Node current : flood) {
             if (current instanceof EndNode) {
                 EndNode end = (EndNode) current;
@@ -65,7 +63,7 @@
         }
     }
 
-    private void disconnectCFGNodes(StructuredGraph graph) {
+    private static void disconnectCFGNodes(NodeFlood flood, StructuredGraph graph) {
         for (EndNode node : graph.getNodes(EndNode.class)) {
             if (!flood.isMarked(node)) {
                 MergeNode merge = node.merge();
@@ -95,7 +93,7 @@
         }
     }
 
-    private void deleteNodes(StructuredGraph graph) {
+    private static void deleteNodes(NodeFlood flood, StructuredGraph graph) {
         for (Node node : graph.getNodes()) {
             if (!flood.isMarked(node)) {
                 node.clearInputs();
@@ -110,7 +108,7 @@
         }
     }
 
-    private void iterateInputs(StructuredGraph graph) {
+    private static void iterateInputs(NodeFlood flood, StructuredGraph graph) {
         for (Node node : graph.getNodes()) {
             if (node instanceof LocalNode) {
                 flood.add(node);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java	Tue Apr 23 20:16:34 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java	Tue Apr 23 20:16:45 2013 +0200
@@ -25,7 +25,6 @@
 import java.util.*;
 import java.util.Map.Entry;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
@@ -34,8 +33,9 @@
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.schedule.*;
+import com.oracle.graal.phases.tiers.*;
 
-public class GuardLoweringPhase extends Phase {
+public class GuardLoweringPhase extends BasePhase<MidTierContext> {
 
     private abstract static class ScheduledNodeIterator {
 
@@ -81,9 +81,14 @@
         protected abstract void processNode(Node node);
     }
 
-    private class UseImplicitNullChecks extends ScheduledNodeIterator {
+    private static class UseImplicitNullChecks extends ScheduledNodeIterator {
 
         private final IdentityHashMap<ValueNode, GuardNode> nullGuarded = new IdentityHashMap<>();
+        private final int implicitNullCheckLimit;
+
+        UseImplicitNullChecks(int implicitNullCheckLimit) {
+            this.implicitNullCheckLimit = implicitNullCheckLimit;
+        }
 
         @Override
         protected void processNode(Node node) {
@@ -134,9 +139,17 @@
                 nullGuarded.put(obj, guard);
             }
         }
+
+        private boolean isImplicitNullCheck(LocationNode location) {
+            if (location instanceof ConstantLocationNode) {
+                return ((ConstantLocationNode) location).displacement() < implicitNullCheckLimit;
+            } else {
+                return false;
+            }
+        }
     }
 
-    private class LowerGuards extends ScheduledNodeIterator {
+    private static class LowerGuards extends ScheduledNodeIterator {
 
         private final Block block;
 
@@ -193,35 +206,21 @@
         }
     }
 
-    private TargetDescription target;
-
-    public GuardLoweringPhase(TargetDescription target) {
-        this.target = target;
-    }
-
     @Override
-    protected void run(StructuredGraph graph) {
+    protected void run(StructuredGraph graph, MidTierContext context) {
         SchedulePhase schedule = new SchedulePhase();
         schedule.apply(graph);
 
         for (Block block : schedule.getCFG().getBlocks()) {
-            processBlock(block, schedule);
+            processBlock(block, schedule, context.getTarget().implicitNullCheckLimit);
         }
     }
 
-    private void processBlock(Block block, SchedulePhase schedule) {
+    private static void processBlock(Block block, SchedulePhase schedule, int implicitNullCheckLimit) {
         List<ScheduledNode> nodes = schedule.nodesFor(block);
-        if (GraalOptions.OptImplicitNullChecks && target.implicitNullCheckLimit > 0) {
-            new UseImplicitNullChecks().processNodes(nodes, block.getBeginNode());
+        if (GraalOptions.OptImplicitNullChecks && implicitNullCheckLimit > 0) {
+            new UseImplicitNullChecks(implicitNullCheckLimit).processNodes(nodes, block.getBeginNode());
         }
         new LowerGuards(block).processNodes(nodes, block.getBeginNode());
     }
-
-    private boolean isImplicitNullCheck(LocationNode location) {
-        if (location instanceof ConstantLocationNode) {
-            return ((ConstantLocationNode) location).displacement() < target.implicitNullCheckLimit;
-        } else {
-            return false;
-        }
-    }
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Tue Apr 23 20:16:34 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Tue Apr 23 20:16:45 2013 +0200
@@ -26,7 +26,6 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.nodes.*;
@@ -36,38 +35,36 @@
 import com.oracle.graal.nodes.spi.Lowerable.LoweringType;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.schedule.*;
+import com.oracle.graal.phases.tiers.*;
 
 /**
  * Processes all {@link Lowerable} nodes to do their lowering.
  */
-public class LoweringPhase extends Phase {
+public class LoweringPhase extends BasePhase<PhaseContext> {
 
     final class LoweringToolImpl implements LoweringTool {
 
+        private final PhaseContext context;
         private final FixedNode guardAnchor;
         private final NodeBitMap activeGuards;
         private FixedWithNextNode lastFixedNode;
         private ControlFlowGraph cfg;
 
-        public LoweringToolImpl(FixedNode guardAnchor, NodeBitMap activeGuards, ControlFlowGraph cfg) {
+        public LoweringToolImpl(PhaseContext context, FixedNode guardAnchor, NodeBitMap activeGuards, ControlFlowGraph cfg) {
+            this.context = context;
             this.guardAnchor = guardAnchor;
             this.activeGuards = activeGuards;
             this.cfg = cfg;
         }
 
         @Override
-        public TargetDescription getTarget() {
-            return target;
-        }
-
-        @Override
         public GraalCodeCacheProvider getRuntime() {
-            return runtime;
+            return (GraalCodeCacheProvider) context.getRuntime();
         }
 
         @Override
         public Replacements getReplacements() {
-            return replacements;
+            return context.getReplacements();
         }
 
         @Override
@@ -82,7 +79,7 @@
 
         @Override
         public Assumptions assumptions() {
-            return assumptions;
+            return context.getAssumptions();
         }
 
         @Override
@@ -120,19 +117,9 @@
         }
     }
 
-    private final TargetDescription target;
-    private final GraalCodeCacheProvider runtime;
-    private final Replacements replacements;
-    private final Assumptions assumptions;
     private final LoweringType loweringType;
 
-    private boolean deferred;
-
-    public LoweringPhase(TargetDescription target, GraalCodeCacheProvider runtime, Replacements replacements, Assumptions assumptions, LoweringType loweringType) {
-        this.target = target;
-        this.runtime = runtime;
-        this.replacements = replacements;
-        this.assumptions = assumptions;
+    public LoweringPhase(LoweringType loweringType) {
         this.loweringType = loweringType;
     }
 
@@ -146,20 +133,18 @@
     }
 
     @Override
-    protected void run(final StructuredGraph graph) {
+    protected void run(final StructuredGraph graph, PhaseContext context) {
         int i = 0;
         NodeBitMap processed = graph.createNodeBitMap();
         while (true) {
+            Round round = new Round(i++, context, processed);
             int mark = graph.getMark();
-            final SchedulePhase schedule = new SchedulePhase();
-            schedule.apply(graph, false);
 
-            deferred = false;
-            processBlock(schedule.getCFG().getStartBlock(), graph.createNodeBitMap(), null, schedule, processed);
-            Debug.dump(graph, "Lowering iteration %d", i++);
-            new CanonicalizerPhase.Instance(runtime, assumptions, mark, null).apply(graph);
+            IncrementalCanonicalizerPhase<PhaseContext> canonicalizer = new IncrementalCanonicalizerPhase<>();
+            canonicalizer.addPhase(round);
+            canonicalizer.apply(graph, context);
 
-            if (!deferred && !containsLowerable(graph.getNewNodes(mark))) {
+            if (!round.deferred && !containsLowerable(graph.getNewNodes(mark))) {
                 // No new lowerable nodes - done!
                 break;
             }
@@ -168,76 +153,98 @@
         }
     }
 
-    private void processBlock(Block block, NodeBitMap activeGuards, FixedNode parentAnchor, SchedulePhase schedule, NodeBitMap processed) {
+    private final class Round extends Phase {
 
-        FixedNode anchor = parentAnchor;
-        if (anchor == null) {
-            anchor = block.getBeginNode();
+        private final PhaseContext context;
+        private final NodeBitMap processed;
+        private final SchedulePhase schedule;
+        private boolean deferred = false;
+
+        private Round(int iteration, PhaseContext context, NodeBitMap processed) {
+            super(String.format("Lowering iteration %d", iteration));
+            this.context = context;
+            this.processed = processed;
+            this.schedule = new SchedulePhase();
         }
-        process(block, activeGuards, anchor, schedule, processed);
 
-        // Process always reached block first.
-        Block alwaysReachedBlock = block.getPostdominator();
-        if (alwaysReachedBlock != null && alwaysReachedBlock.getDominator() == block) {
-            processBlock(alwaysReachedBlock, activeGuards, anchor, schedule, processed);
+        @Override
+        public void run(StructuredGraph graph) {
+            schedule.apply(graph, false);
+            processBlock(schedule.getCFG().getStartBlock(), graph.createNodeBitMap(), null);
         }
 
-        // Now go for the other dominators.
-        for (Block dominated : block.getDominated()) {
-            if (dominated != alwaysReachedBlock) {
-                assert dominated.getDominator() == block;
-                processBlock(dominated, activeGuards, null, schedule, processed);
+        private void processBlock(Block block, NodeBitMap activeGuards, FixedNode parentAnchor) {
+
+            FixedNode anchor = parentAnchor;
+            if (anchor == null) {
+                anchor = block.getBeginNode();
+            }
+            process(block, activeGuards, anchor);
+
+            // Process always reached block first.
+            Block alwaysReachedBlock = block.getPostdominator();
+            if (alwaysReachedBlock != null && alwaysReachedBlock.getDominator() == block) {
+                processBlock(alwaysReachedBlock, activeGuards, anchor);
+            }
+
+            // Now go for the other dominators.
+            for (Block dominated : block.getDominated()) {
+                if (dominated != alwaysReachedBlock) {
+                    assert dominated.getDominator() == block;
+                    processBlock(dominated, activeGuards, null);
+                }
+            }
+
+            if (parentAnchor == null && GraalOptions.OptEliminateGuards) {
+                for (GuardNode guard : anchor.usages().filter(GuardNode.class)) {
+                    activeGuards.clear(guard);
+                }
             }
         }
 
-        if (parentAnchor == null && GraalOptions.OptEliminateGuards) {
-            for (GuardNode guard : anchor.usages().filter(GuardNode.class)) {
-                activeGuards.clear(guard);
-            }
-        }
-    }
+        private void process(final Block b, final NodeBitMap activeGuards, final FixedNode anchor) {
 
-    private void process(final Block b, final NodeBitMap activeGuards, final FixedNode anchor, SchedulePhase schedule, NodeBitMap processed) {
+            final LoweringToolImpl loweringTool = new LoweringToolImpl(context, anchor, activeGuards, schedule.getCFG());
 
-        final LoweringToolImpl loweringTool = new LoweringToolImpl(anchor, activeGuards, schedule.getCFG());
+            // Lower the instructions of this block.
+            List<ScheduledNode> nodes = schedule.nodesFor(b);
 
-        // Lower the instructions of this block.
-        List<ScheduledNode> nodes = schedule.nodesFor(b);
-
-        for (Node node : nodes) {
-            FixedNode nextFixedNode = null;
-            if (node instanceof FixedWithNextNode && node.isAlive()) {
-                FixedWithNextNode fixed = (FixedWithNextNode) node;
-                nextFixedNode = fixed.next();
-                loweringTool.setLastFixedNode(fixed);
-            }
+            for (Node node : nodes) {
+                FixedNode nextFixedNode = null;
+                if (node instanceof FixedWithNextNode && node.isAlive()) {
+                    FixedWithNextNode fixed = (FixedWithNextNode) node;
+                    nextFixedNode = fixed.next();
+                    loweringTool.setLastFixedNode(fixed);
+                }
 
-            if (node.isAlive() && !processed.isMarked(node) && node instanceof Lowerable) {
-                if (loweringTool.lastFixedNode() == null) {
-                    /*
-                     * We cannot lower the node now because we don't have a fixed node to anchor the
-                     * replacements. This can happen when previous lowerings in this lowering
-                     * iteration deleted the BeginNode of this block. In the next iteration, we will
-                     * have the new BeginNode available, and we can lower this node.
-                     */
-                    deferred = true;
-                } else {
-                    processed.mark(node);
-                    ((Lowerable) node).lower(loweringTool, loweringType);
+                if (node.isAlive() && !processed.isMarked(node) && node instanceof Lowerable) {
+                    if (loweringTool.lastFixedNode() == null) {
+                        /*
+                         * We cannot lower the node now because we don't have a fixed node to anchor
+                         * the replacements. This can happen when previous lowerings in this
+                         * lowering iteration deleted the BeginNode of this block. In the next
+                         * iteration, we will have the new BeginNode available, and we can lower
+                         * this node.
+                         */
+                        deferred = true;
+                    } else {
+                        processed.mark(node);
+                        ((Lowerable) node).lower(loweringTool, loweringType);
+                    }
                 }
-            }
 
-            if (loweringTool.lastFixedNode() == node && !node.isAlive()) {
-                if (nextFixedNode == null || !nextFixedNode.isAlive()) {
-                    loweringTool.setLastFixedNode(null);
-                } else {
-                    Node prev = nextFixedNode.predecessor();
-                    if (prev != node && prev instanceof FixedWithNextNode) {
-                        loweringTool.setLastFixedNode((FixedWithNextNode) prev);
-                    } else if (nextFixedNode instanceof FixedWithNextNode) {
-                        loweringTool.setLastFixedNode((FixedWithNextNode) nextFixedNode);
+                if (loweringTool.lastFixedNode() == node && !node.isAlive()) {
+                    if (nextFixedNode == null || !nextFixedNode.isAlive()) {
+                        loweringTool.setLastFixedNode(null);
                     } else {
-                        loweringTool.setLastFixedNode(null);
+                        Node prev = nextFixedNode.predecessor();
+                        if (prev != node && prev instanceof FixedWithNextNode) {
+                            loweringTool.setLastFixedNode((FixedWithNextNode) prev);
+                        } else if (nextFixedNode instanceof FixedWithNextNode) {
+                            loweringTool.setLastFixedNode((FixedWithNextNode) nextFixedNode);
+                        } else {
+                            loweringTool.setLastFixedNode(null);
+                        }
                     }
                 }
             }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/PhasePlan.java	Tue Apr 23 20:16:34 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/PhasePlan.java	Tue Apr 23 20:16:45 2013 +0200
@@ -51,7 +51,6 @@
     public static enum PhasePosition {
         AFTER_PARSING,
         HIGH_LEVEL,
-        MID_LEVEL,
         LOW_LEVEL
     }
     // @formatter:on
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/CompilerConfiguration.java	Tue Apr 23 20:16:34 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/CompilerConfiguration.java	Tue Apr 23 20:16:45 2013 +0200
@@ -29,4 +29,6 @@
     PhaseSuite<HighTierContext> createHighTier();
 
     PhaseSuite<MidTierContext> createMidTier();
+
+    PhaseSuite<LowTierContext> createLowTier();
 }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/HighTierContext.java	Tue Apr 23 20:16:34 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/HighTierContext.java	Tue Apr 23 20:16:45 2013 +0200
@@ -24,10 +24,11 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.spi.*;
 
 public class HighTierContext extends PhaseContext {
 
-    public HighTierContext(MetaAccessProvider runtime, Assumptions assumptions) {
-        super(runtime, assumptions);
+    public HighTierContext(MetaAccessProvider runtime, Assumptions assumptions, Replacements replacements) {
+        super(runtime, assumptions, replacements);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/LowTierContext.java	Tue Apr 23 20:16:45 2013 +0200
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.phases.tiers;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.spi.*;
+
+public class LowTierContext extends PhaseContext {
+
+    private final TargetDescription target;
+
+    public LowTierContext(MetaAccessProvider runtime, Assumptions assumptions, Replacements replacements, TargetDescription target) {
+        super(runtime, assumptions, replacements);
+        this.target = target;
+    }
+
+    public TargetDescription getTarget() {
+        return target;
+    }
+}
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/MidTierContext.java	Tue Apr 23 20:16:34 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/MidTierContext.java	Tue Apr 23 20:16:45 2013 +0200
@@ -28,14 +28,14 @@
 
 public class MidTierContext extends PhaseContext {
 
-    private final Replacements replacements;
+    private final TargetDescription target;
 
-    public MidTierContext(MetaAccessProvider runtime, Assumptions assumptions, Replacements replacements) {
-        super(runtime, assumptions);
-        this.replacements = replacements;
+    public MidTierContext(MetaAccessProvider runtime, Assumptions assumptions, Replacements replacements, TargetDescription target) {
+        super(runtime, assumptions, replacements);
+        this.target = target;
     }
 
-    public Replacements getReplacements() {
-        return replacements;
+    public TargetDescription getTarget() {
+        return target;
     }
 }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/PhaseContext.java	Tue Apr 23 20:16:34 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/PhaseContext.java	Tue Apr 23 20:16:45 2013 +0200
@@ -24,15 +24,18 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.spi.*;
 
 public class PhaseContext {
 
     private final MetaAccessProvider runtime;
     private final Assumptions assumptions;
+    private final Replacements replacements;
 
-    public PhaseContext(MetaAccessProvider runtime, Assumptions assumptions) {
+    public PhaseContext(MetaAccessProvider runtime, Assumptions assumptions, Replacements replacements) {
         this.runtime = runtime;
         this.assumptions = assumptions;
+        this.replacements = replacements;
     }
 
     public MetaAccessProvider getRuntime() {
@@ -42,4 +45,8 @@
     public Assumptions getAssumptions() {
         return assumptions;
     }
+
+    public Replacements getReplacements() {
+        return replacements;
+    }
 }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java	Tue Apr 23 20:16:34 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java	Tue Apr 23 20:16:45 2013 +0200
@@ -33,6 +33,7 @@
 
     private final PhaseSuite<HighTierContext> highTier;
     private final PhaseSuite<MidTierContext> midTier;
+    private final PhaseSuite<LowTierContext> lowTier;
 
     private static final Map<String, CompilerConfiguration> configurations;
 
@@ -44,6 +45,10 @@
         return midTier;
     }
 
+    public PhaseSuite<LowTierContext> getLowTier() {
+        return lowTier;
+    }
+
     static {
         configurations = new HashMap<>();
         for (CompilerConfiguration config : ServiceLoader.loadInstalled(CompilerConfiguration.class)) {
@@ -60,6 +65,7 @@
     private Suites(CompilerConfiguration config) {
         highTier = config.createHighTier();
         midTier = config.createMidTier();
+        lowTier = config.createLowTier();
     }
 
     public static Suites createDefaultSuites() {
--- a/mxtool/mx.py	Tue Apr 23 20:16:34 2013 +0200
+++ b/mxtool/mx.py	Tue Apr 23 20:16:45 2013 +0200
@@ -980,11 +980,14 @@
     for arg in args:
         assert isinstance(arg, types.StringTypes), 'argument is not a string: ' + str(arg)
 
+    if env is None:
+        env = os.environ
+        
     if _opts.verbose:
         if _opts.very_verbose:
             log('Environment variables:')
-            for key in sorted(os.environ.keys()):
-                log('    ' + key + '=' + os.environ[key])
+            for key in sorted(env.keys()):
+                log('    ' + key + '=' + env[key])
         log(' '.join(args))
 
     if timeout is None and _opts.ptimeout != 0: