# HG changeset patch # User Roland Schatz # Date 1366732150 -7200 # Node ID 950a385e059b201591e48e48359304620dc5fab9 # Parent 223e01540fe81e28d6b1f7b245ad8d1e40fa82a0 Make LoweringPhase reentrant. diff -r 223e01540fe8 -r 950a385e059b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java 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; diff -r 223e01540fe8 -r 950a385e059b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java 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) { diff -r 223e01540fe8 -r 950a385e059b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java 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; } diff -r 223e01540fe8 -r 950a385e059b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java 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"); diff -r 223e01540fe8 -r 950a385e059b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/WriteBarrierAdditionTest.java --- 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(); diff -r 223e01540fe8 -r 950a385e059b graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java 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); diff -r 223e01540fe8 -r 950a385e059b graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java 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 { 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 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 nodes = schedule.nodesFor(b); - // Lower the instructions of this block. - List 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); + } } } }