changeset 9267:950a385e059b

Make LoweringPhase reentrant.
author Roland Schatz <roland.schatz@oracle.com>
date Tue, 23 Apr 2013 17:49:10 +0200
parents 223e01540fe8
children 2d80e5f17bf8
files 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/MemoryScheduleTest.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/ReadAfterCheckCastTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/WriteBarrierAdditionTest.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java
diffstat 7 files changed, 112 insertions(+), 88 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java	Tue Apr 23 17:49:08 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java	Tue Apr 23 17:49:10 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(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 17:49:08 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java	Tue Apr 23 17:49:10 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(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 17:49:08 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java	Tue Apr 23 17:49:10 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(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 17:49:08 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java	Tue Apr 23 17:49:10 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(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 17:49:08 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/WriteBarrierAdditionTest.java	Tue Apr 23 17:49:10 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(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/src/com/oracle/graal/compiler/GraalCompiler.java	Tue Apr 23 17:49:08 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Tue Apr 23 17:49:10 2013 +0200
@@ -140,7 +140,7 @@
 
         Suites.DEFAULT.getHighTier().apply(graph, highTierContext);
 
-        new LoweringPhase(runtime, replacements, assumptions, LoweringType.BEFORE_GUARDS).apply(graph);
+        new LoweringPhase(LoweringType.BEFORE_GUARDS).apply(graph, highTierContext);
 
         MidTierContext midTierContext = new MidTierContext(runtime, assumptions, replacements, target);
         Suites.DEFAULT.getMidTier().apply(graph, midTierContext);
@@ -157,7 +157,7 @@
         LowTierContext lowTierContext = new LowTierContext(runtime, assumptions, replacements, target);
         Suites.DEFAULT.getLowTier().apply(graph, lowTierContext);
 
-        new LoweringPhase(runtime, replacements, assumptions, LoweringType.AFTER_GUARDS).apply(graph);
+        new LoweringPhase(LoweringType.AFTER_GUARDS).apply(graph, lowTierContext);
 
         new FrameStateAssignmentPhase().apply(graph);
 
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Tue Apr 23 17:49:08 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Tue Apr 23 17:49:10 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,20 +35,23 @@
 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;
@@ -57,12 +59,12 @@
 
         @Override
         public GraalCodeCacheProvider getRuntime() {
-            return runtime;
+            return (GraalCodeCacheProvider) context.getRuntime();
         }
 
         @Override
         public Replacements getReplacements() {
-            return replacements;
+            return context.getReplacements();
         }
 
         @Override
@@ -77,7 +79,7 @@
 
         @Override
         public Assumptions assumptions() {
-            return assumptions;
+            return context.getAssumptions();
         }
 
         @Override
@@ -115,17 +117,9 @@
         }
     }
 
-    private final GraalCodeCacheProvider runtime;
-    private final Replacements replacements;
-    private final Assumptions assumptions;
     private final LoweringType loweringType;
 
-    private boolean deferred;
-
-    public LoweringPhase(GraalCodeCacheProvider runtime, Replacements replacements, Assumptions assumptions, LoweringType loweringType) {
-        this.runtime = runtime;
-        this.replacements = replacements;
-        this.assumptions = assumptions;
+    public LoweringPhase(LoweringType loweringType) {
         this.loweringType = loweringType;
     }
 
@@ -139,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;
             }
@@ -161,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);
+                        }
                     }
                 }
             }