Mercurial > hg > graal-compiler
changeset 18975:88083bb2e0f8
Merge.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Tue, 27 Jan 2015 16:58:48 +0100 |
parents | c597c72e163b (diff) c1f8125b4207 (current diff) |
children | 3faa4f98d5c8 |
files | |
diffstat | 41 files changed, 401 insertions(+), 336 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Tue Jan 27 16:58:48 2015 +0100 @@ -319,7 +319,7 @@ canonicalId.set(node, id); } String name = node instanceof ConstantNode && checkConstants ? node.toString(Verbosity.Name) : node.getClass().getSimpleName(); - result.append(" " + id + "|" + name + (excludeVirtual ? "\n" : " (" + node.usages().count() + ")\n")); + result.append(" " + id + "|" + name + (excludeVirtual ? "\n" : " (" + node.getUsageCount() + ")\n")); } } }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraphScheduleTest.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraphScheduleTest.java Tue Jan 27 16:58:48 2015 +0100 @@ -34,7 +34,7 @@ public class GraphScheduleTest extends GraalCompilerTest { protected void assertOrderedAfterSchedule(StructuredGraph graph, Node a, Node b) { - SchedulePhase ibp = new SchedulePhase(); + SchedulePhase ibp = new SchedulePhase(SchedulePhase.SchedulingStrategy.LATEST); ibp.apply(graph); assertOrderedAfterSchedule(ibp, a, b); }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Tue Jan 27 16:58:48 2015 +0100 @@ -45,7 +45,6 @@ import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.common.inlining.*; import com.oracle.graal.phases.schedule.*; -import com.oracle.graal.phases.schedule.SchedulePhase.MemoryScheduling; import com.oracle.graal.phases.schedule.SchedulePhase.SchedulingStrategy; import com.oracle.graal.phases.tiers.*; @@ -459,7 +458,7 @@ @Test public void testBlockSchedule2() { - SchedulePhase schedule = getFinalSchedule("testBlockSchedule2Snippet", TestMode.WITHOUT_FRAMESTATES, MemoryScheduling.OPTIMAL, SchedulingStrategy.LATEST); + SchedulePhase schedule = getFinalSchedule("testBlockSchedule2Snippet", TestMode.WITHOUT_FRAMESTATES, SchedulingStrategy.LATEST); assertReadWithinStartBlock(schedule, false); assertReadWithinAllReturnBlocks(schedule, false); assertReadAndWriteInSameBlock(schedule, false); @@ -593,14 +592,10 @@ } private SchedulePhase getFinalSchedule(final String snippet, final TestMode mode) { - return getFinalSchedule(snippet, mode, MemoryScheduling.OPTIMAL); + return getFinalSchedule(snippet, mode, SchedulingStrategy.LATEST_OUT_OF_LOOPS); } - private SchedulePhase getFinalSchedule(final String snippet, final TestMode mode, final MemoryScheduling memsched) { - return getFinalSchedule(snippet, mode, memsched, SchedulingStrategy.LATEST_OUT_OF_LOOPS); - } - - private SchedulePhase getFinalSchedule(final String snippet, final TestMode mode, final MemoryScheduling memsched, final SchedulingStrategy schedulingStrategy) { + private SchedulePhase getFinalSchedule(final String snippet, final TestMode mode, final SchedulingStrategy schedulingStrategy) { final StructuredGraph graph = parseEager(snippet); try (Scope d = Debug.scope("FloatingReadTest", graph)) { try (OverrideScope s = OptionValue.override(OptScheduleOutOfLoops, schedulingStrategy == SchedulingStrategy.LATEST_OUT_OF_LOOPS, OptImplicitNullChecks, false)) { @@ -633,7 +628,7 @@ new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, midContext); new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.LOW_TIER).apply(graph, midContext); - SchedulePhase schedule = new SchedulePhase(schedulingStrategy, memsched); + SchedulePhase schedule = new SchedulePhase(schedulingStrategy); schedule.apply(graph); assertDeepEquals(1, graph.getNodes().filter(StartNode.class).count()); return schedule;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/TypeSystemTest.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/TypeSystemTest.java Tue Jan 27 16:58:48 2015 +0100 @@ -217,7 +217,7 @@ } private static void outputNode(Node node) { - TTY.print(" " + node + " (usage count: " + node.usages().count() + ") (inputs:"); + TTY.print(" " + node + " (usage count: " + node.getUsageCount() + ") (inputs:"); for (Node input : node.inputs()) { TTY.print(" " + input.toString(Verbosity.Id)); }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java Tue Jan 27 16:58:48 2015 +0100 @@ -158,7 +158,7 @@ */ public void setMatchResult(ValueNode x, Value operand) { assert operand.equals(ComplexMatchValue.INTERIOR_MATCH) || operand instanceof ComplexMatchValue; - assert operand instanceof ComplexMatchValue || x.usages().count() == 1 : "interior matches must be single user"; + assert operand instanceof ComplexMatchValue || x.getUsageCount() == 1 : "interior matches must be single user"; assert nodeOperands != null && nodeOperands.get(x) == null : "operand cannot be set twice"; assert !(x instanceof VirtualObjectNode); nodeOperands.set(x, operand); @@ -256,7 +256,7 @@ if (LogVerbose.getValue()) { int i = 0; for (ValueNode node : nodes) { - Debug.log("%d: (%s) %1S", i++, node.usages().count(), node); + Debug.log("%d: (%s) %1S", i++, node.getUsageCount(), node); } }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchContext.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchContext.java Tue Jan 27 16:58:48 2015 +0100 @@ -109,7 +109,7 @@ Debug.log("unexpected node %s", node); for (int j = startIndex; j <= endIndex; j++) { ValueNode theNode = nodes.get(j); - Debug.log("%s(%s) %1s", (consumed != null && consumed.contains(theNode) || theNode == root) ? "*" : " ", theNode.usages().count(), theNode); + Debug.log("%s(%s) %1s", (consumed != null && consumed.contains(theNode) || theNode == root) ? "*" : " ", theNode.getUsageCount(), theNode); } } return Result.notSafe(node, rule.getPattern()); @@ -147,7 +147,7 @@ * @return Result.OK if the node can be safely consumed. */ public Result consume(ValueNode node) { - assert node.usages().count() <= 1 : "should have already been checked"; + assert node.getUsageCount() <= 1 : "should have already been checked"; // Check NOT_IN_BLOCK first since that usually implies ALREADY_USED int index = nodes.indexOf(node);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchPattern.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchPattern.java Tue Jan 27 16:58:48 2015 +0100 @@ -251,7 +251,7 @@ } if (singleUser && !atRoot) { - if (node.usages().count() > 1) { + if (node.getUsageCount() > 1) { return Result.tooManyUsers(node, statement.getPattern()); } }
--- a/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/NodeUsagesTests.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/NodeUsagesTests.java Tue Jan 27 16:58:48 2015 +0100 @@ -62,7 +62,7 @@ Use use1 = graph.add(new Use(null, def0, null)); Use use2 = graph.add(new Use(null, null, def0)); - assertEquals(3, def0.usages().count()); + assertEquals(3, def0.getUsageCount()); assertThat(def0.usages(), contains(use0)); assertThat(def0.usages(), contains(use1)); assertThat(def0.usages(), contains(use2)); @@ -74,7 +74,7 @@ assertThat(def0.usages(), isEmpty()); - assertEquals(3, def1.usages().count()); + assertEquals(3, def1.getUsageCount()); assertThat(def1.usages(), contains(use0)); assertThat(def1.usages(), contains(use1)); assertThat(def1.usages(), contains(use2)); @@ -91,7 +91,7 @@ Use use1 = graph.add(new Use(null, def0, null)); Use use2 = graph.add(new Use(null, null, def0)); - assertEquals(3, def0.usages().count()); + assertEquals(3, def0.getUsageCount()); assertThat(def0.usages(), contains(use0)); assertThat(def0.usages(), contains(use1)); assertThat(def0.usages(), contains(use2)); @@ -103,7 +103,7 @@ assertThat(def0.usages(), isEmpty()); - assertEquals(3, def1.usages().count()); + assertEquals(3, def1.getUsageCount()); assertThat(def1.usages(), contains(use0)); assertThat(def1.usages(), contains(use1)); assertThat(def1.usages(), contains(use2)); @@ -120,7 +120,7 @@ Use use1 = graph.add(new Use(null, def0, null)); Use use2 = graph.add(new Use(null, null, def0)); - assertEquals(3, def0.usages().count()); + assertEquals(3, def0.getUsageCount()); assertThat(def0.usages(), contains(use0)); assertThat(def0.usages(), contains(use1)); assertThat(def0.usages(), contains(use2)); @@ -132,7 +132,7 @@ assertThat(def1.usages(), isEmpty()); - assertEquals(3, def0.usages().count()); + assertEquals(3, def0.getUsageCount()); assertThat(def0.usages(), contains(use0)); assertThat(def0.usages(), contains(use1)); assertThat(def0.usages(), contains(use2)); @@ -149,7 +149,7 @@ Use use1 = graph.add(new Use(null, def0, null)); Use use2 = graph.add(new Use(null, null, def0)); - assertEquals(3, def0.usages().count()); + assertEquals(3, def0.getUsageCount()); assertThat(def0.usages(), contains(use0)); assertThat(def0.usages(), contains(use1)); assertThat(def0.usages(), contains(use2)); @@ -159,12 +159,12 @@ def0.replaceAtMatchingUsages(def1, u -> u == use1); - assertEquals(1, def1.usages().count()); + assertEquals(1, def1.getUsageCount()); assertThat(def1.usages(), contains(use1)); assertThat(def1.usages(), isNotEmpty()); - assertEquals(2, def0.usages().count()); + assertEquals(2, def0.getUsageCount()); assertThat(def0.usages(), contains(use0)); assertThat(def0.usages(), contains(use2)); @@ -180,7 +180,7 @@ Use use1 = graph.add(new Use(null, def0, null)); Use use2 = graph.add(new Use(null, null, def0)); - assertEquals(3, def0.usages().count()); + assertEquals(3, def0.getUsageCount()); assertThat(def0.usages(), contains(use0)); assertThat(def0.usages(), contains(use1)); assertThat(def0.usages(), contains(use2)); @@ -190,12 +190,12 @@ def0.replaceAtMatchingUsages(def1, u -> u == use2); - assertEquals(1, def1.usages().count()); + assertEquals(1, def1.getUsageCount()); assertThat(def1.usages(), contains(use2)); assertThat(def1.usages(), isNotEmpty()); - assertEquals(2, def0.usages().count()); + assertEquals(2, def0.getUsageCount()); assertThat(def0.usages(), contains(use0)); assertThat(def0.usages(), contains(use1)); @@ -211,7 +211,7 @@ Use use1 = graph.add(new Use(null, def0, null)); Use use2 = graph.add(new Use(null, null, def0)); - assertEquals(3, def0.usages().count()); + assertEquals(3, def0.getUsageCount()); assertThat(def0.usages(), contains(use0)); assertThat(def0.usages(), contains(use1)); assertThat(def0.usages(), contains(use2)); @@ -221,12 +221,12 @@ def0.replaceAtMatchingUsages(def1, u -> u == use0); - assertEquals(1, def1.usages().count()); + assertEquals(1, def1.getUsageCount()); assertThat(def1.usages(), contains(use0)); assertThat(def1.usages(), isNotEmpty()); - assertEquals(2, def0.usages().count()); + assertEquals(2, def0.getUsageCount()); assertThat(def0.usages(), contains(use1)); assertThat(def0.usages(), contains(use2)); @@ -242,7 +242,7 @@ Use use1 = graph.add(new Use(null, def0, null)); Use use2 = graph.add(new Use(null, null, def0)); - assertEquals(3, def0.usages().count()); + assertEquals(3, def0.getUsageCount()); assertThat(def0.usages(), contains(use0)); assertThat(def0.usages(), contains(use1)); assertThat(def0.usages(), contains(use2)); @@ -252,12 +252,12 @@ def0.replaceAtMatchingUsages(def1, u -> u != use1); - assertEquals(1, def0.usages().count()); + assertEquals(1, def0.getUsageCount()); assertThat(def0.usages(), contains(use1)); assertThat(def0.usages(), isNotEmpty()); - assertEquals(2, def1.usages().count()); + assertEquals(2, def1.getUsageCount()); assertThat(def1.usages(), contains(use0)); assertThat(def1.usages(), contains(use2)); @@ -274,7 +274,7 @@ Use use2 = graph.add(new Use(null, null, def0)); Use use3 = graph.add(new Use(null, null, def0)); - assertEquals(4, def0.usages().count()); + assertEquals(4, def0.getUsageCount()); assertThat(def0.usages(), contains(use0)); assertThat(def0.usages(), contains(use1)); assertThat(def0.usages(), contains(use2)); @@ -285,12 +285,12 @@ def0.replaceAtMatchingUsages(def1, u -> u != use1); - assertEquals(1, def0.usages().count()); + assertEquals(1, def0.getUsageCount()); assertThat(def0.usages(), contains(use1)); assertThat(def0.usages(), isNotEmpty()); - assertEquals(3, def1.usages().count()); + assertEquals(3, def1.getUsageCount()); assertThat(def1.usages(), contains(use0)); assertThat(def1.usages(), contains(use2)); assertThat(def1.usages(), contains(use3)); @@ -308,7 +308,7 @@ Use use2 = graph.add(new Use(null, null, def0)); Use use3 = graph.add(new Use(null, null, def0)); - assertEquals(4, def0.usages().count()); + assertEquals(4, def0.getUsageCount()); assertThat(def0.usages(), contains(use0)); assertThat(def0.usages(), contains(use1)); assertThat(def0.usages(), contains(use2)); @@ -319,12 +319,12 @@ def0.replaceAtMatchingUsages(def1, u -> u != use2); - assertEquals(1, def0.usages().count()); + assertEquals(1, def0.getUsageCount()); assertThat(def0.usages(), contains(use2)); assertThat(def0.usages(), isNotEmpty()); - assertEquals(3, def1.usages().count()); + assertEquals(3, def1.getUsageCount()); assertThat(def1.usages(), contains(use0)); assertThat(def1.usages(), contains(use1)); assertThat(def1.usages(), contains(use3)); @@ -342,7 +342,7 @@ Use use2 = graph.add(new Use(null, null, def0)); Use use3 = graph.add(new Use(null, null, def0)); - assertEquals(4, def0.usages().count()); + assertEquals(4, def0.getUsageCount()); assertThat(def0.usages(), contains(use0)); assertThat(def0.usages(), contains(use1)); assertThat(def0.usages(), contains(use2)); @@ -353,12 +353,12 @@ def0.replaceAtMatchingUsages(def1, u -> u == use2); - assertEquals(1, def1.usages().count()); + assertEquals(1, def1.getUsageCount()); assertThat(def1.usages(), contains(use2)); assertThat(def1.usages(), isNotEmpty()); - assertEquals(3, def0.usages().count()); + assertEquals(3, def0.getUsageCount()); assertThat(def0.usages(), contains(use0)); assertThat(def0.usages(), contains(use1)); assertThat(def0.usages(), contains(use3)); @@ -375,7 +375,7 @@ Use use1 = graph.add(new Use(null, def0, null)); Use use2 = graph.add(new Use(null, null, def0)); - assertEquals(3, def0.usages().count()); + assertEquals(3, def0.getUsageCount()); assertThat(def0.usages(), contains(use0)); assertThat(def0.usages(), contains(use1)); assertThat(def0.usages(), contains(use2)); @@ -385,12 +385,12 @@ def0.replaceAtMatchingUsages(def1, u -> u != use2); - assertEquals(1, def0.usages().count()); + assertEquals(1, def0.getUsageCount()); assertThat(def0.usages(), contains(use2)); assertThat(def0.usages(), isNotEmpty()); - assertEquals(2, def1.usages().count()); + assertEquals(2, def1.getUsageCount()); assertThat(def1.usages(), contains(use0)); assertThat(def1.usages(), contains(use1)); @@ -406,7 +406,7 @@ Use use1 = graph.add(new Use(null, def0, null)); Use use2 = graph.add(new Use(null, null, def0)); - assertEquals(3, def0.usages().count()); + assertEquals(3, def0.getUsageCount()); assertThat(def0.usages(), contains(use0)); assertThat(def0.usages(), contains(use1)); assertThat(def0.usages(), contains(use2)); @@ -416,12 +416,12 @@ def0.replaceAtMatchingUsages(def1, u -> u != use0); - assertEquals(1, def0.usages().count()); + assertEquals(1, def0.getUsageCount()); assertThat(def0.usages(), contains(use0)); assertThat(def0.usages(), isNotEmpty()); - assertEquals(2, def1.usages().count()); + assertEquals(2, def1.getUsageCount()); assertThat(def1.usages(), contains(use1)); assertThat(def1.usages(), contains(use2));
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java Tue Jan 27 16:58:48 2015 +0100 @@ -120,31 +120,31 @@ instanceofSnippets.lower((InstanceOfDynamicNode) n, tool); } } else if (n instanceof NewInstanceNode) { - if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { + if (graph.getGuardsStage().areFrameStatesAtDeopts()) { newObjectSnippets.lower((NewInstanceNode) n, registers, tool); } } else if (n instanceof DynamicNewInstanceNode) { - if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { + if (graph.getGuardsStage().areFrameStatesAtDeopts()) { newObjectSnippets.lower((DynamicNewInstanceNode) n, registers, tool); } } else if (n instanceof NewArrayNode) { - if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { + if (graph.getGuardsStage().areFrameStatesAtDeopts()) { newObjectSnippets.lower((NewArrayNode) n, registers, runtime, tool); } } else if (n instanceof DynamicNewArrayNode) { - if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { + if (graph.getGuardsStage().areFrameStatesAtDeopts()) { newObjectSnippets.lower((DynamicNewArrayNode) n, registers, tool); } } else if (n instanceof VerifyHeapNode) { - if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { + if (graph.getGuardsStage().areFrameStatesAtDeopts()) { newObjectSnippets.lower((VerifyHeapNode) n, registers, runtime, tool); } } else if (n instanceof MonitorEnterNode) { - if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { + if (graph.getGuardsStage().areFrameStatesAtDeopts()) { monitorSnippets.lower((MonitorEnterNode) n, registers, tool); } } else if (n instanceof MonitorExitNode) { - if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { + if (graph.getGuardsStage().areFrameStatesAtDeopts()) { monitorSnippets.lower((MonitorExitNode) n, tool); } } else if (n instanceof G1PreWriteBarrier) { @@ -162,7 +162,7 @@ } else if (n instanceof G1ArrayRangePostWriteBarrier) { writeBarrierSnippets.lower((G1ArrayRangePostWriteBarrier) n, registers, tool); } else if (n instanceof NewMultiArrayNode) { - if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { + if (graph.getGuardsStage().areFrameStatesAtDeopts()) { newObjectSnippets.lower((NewMultiArrayNode) n, tool); } } else if (n instanceof LoadExceptionObjectNode) { @@ -307,7 +307,7 @@ @Override protected void lowerUnsafeLoadNode(UnsafeLoadNode load, LoweringTool tool) { StructuredGraph graph = load.graph(); - if (load.getGuardingCondition() == null && graph.getGuardsStage().ordinal() > StructuredGraph.GuardsStage.FLOATING_GUARDS.ordinal() && addReadBarrier(load)) { + if (load.getGuardingCondition() == null && !graph.getGuardsStage().allowsFloatingGuards() && addReadBarrier(load)) { unsafeLoadSnippets.lower(load, tool); } else { super.lowerUnsafeLoadNode(load, tool); @@ -367,7 +367,7 @@ private void lowerDynamicCounterNode(DynamicCounterNode n) { StructuredGraph graph = n.graph(); - if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { + if (graph.getGuardsStage().areFrameStatesAtDeopts()) { BenchmarkCounters.lower(n, registers, runtime.getConfig(), runtime.getTarget().wordKind); } } @@ -391,7 +391,7 @@ private void lowerBytecodeExceptionNode(BytecodeExceptionNode node) { StructuredGraph graph = node.graph(); - if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FLOATING_GUARDS) { + if (graph.getGuardsStage().allowsFloatingGuards()) { if (OmitHotExceptionStacktrace.getValue()) { Throwable exception; if (node.getExceptionClass() == NullPointerException.class) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrier.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrier.java Tue Jan 27 16:58:48 2015 +0100 @@ -62,7 +62,7 @@ @Override public void lower(LoweringTool tool) { - assert graph().getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA; + assert graph().getGuardsStage().areFrameStatesAtDeopts(); tool.getLowerer().lower(this, tool); } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/ArrayCopyCallNode.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/ArrayCopyCallNode.java Tue Jan 27 16:58:48 2015 +0100 @@ -117,7 +117,7 @@ @Override public void lower(LoweringTool tool) { - if (graph().getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { + if (graph().getGuardsStage().areFrameStatesAtDeopts()) { updateAlignedDisjoint(); ForeignCallDescriptor desc = HotSpotHostForeignCallsProvider.lookupArraycopyDescriptor(elementKind, isAligned(), isDisjoint(), isUninitialized()); StructuredGraph graph = graph();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/CheckcastArrayCopyCallNode.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/CheckcastArrayCopyCallNode.java Tue Jan 27 16:58:48 2015 +0100 @@ -99,7 +99,7 @@ @Override public void lower(LoweringTool tool) { - if (graph().getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { + if (graph().getGuardsStage().areFrameStatesAtDeopts()) { ForeignCallDescriptor desc = HotSpotHostForeignCallsProvider.lookupCheckcastArraycopyDescriptor(isUninit()); StructuredGraph graph = graph(); ValueNode srcAddr = computeBase(getSource(), getSourcePosition());
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/UnsafeArrayCopyNode.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/UnsafeArrayCopyNode.java Tue Jan 27 16:58:48 2015 +0100 @@ -95,7 +95,7 @@ @Override public void lower(LoweringTool tool) { - if (graph().getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { + if (graph().getGuardsStage().areFrameStatesAtDeopts()) { UnsafeArrayCopySnippets.Templates templates = tool.getReplacements().getSnippetTemplateCache(UnsafeArrayCopySnippets.Templates.class); templates.lower(this, tool); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractEndNode.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractEndNode.java Tue Jan 27 16:58:48 2015 +0100 @@ -47,7 +47,7 @@ @Override public boolean verify() { - assertTrue(usages().count() <= 1, "at most one usage"); + assertTrue(getUsageCount() <= 1, "at most one usage"); return super.verify(); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Tue Jan 27 16:58:48 2015 +0100 @@ -76,7 +76,7 @@ * deoptimizing without invalidating the code. Conditional elimination will eliminate the * guard if it's truly redundant in this case. */ - if (graph().getGuardsStage() == StructuredGraph.GuardsStage.FLOATING_GUARDS && getAction() != DeoptimizationAction.None) { + if (graph().getGuardsStage().allowsFloatingGuards() && getAction() != DeoptimizationAction.None) { ValueNode guard = tool.createGuard(this, condition(), getReason(), getAction(), isNegated()).asNode(); this.replaceAtUsages(guard); ValueAnchorNode newAnchor = graph().add(new ValueAnchorNode(guard.asNode()));
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java Tue Jan 27 16:58:48 2015 +0100 @@ -458,8 +458,10 @@ @Override public void applyToNonVirtual(NodeClosure<? super ValueNode> closure) { - for (ValueNode value : values.nonNull()) { - closure.apply(this, value); + for (ValueNode value : values) { + if (value != null) { + closure.apply(this, value); + } } if (monitorIds != null) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Tue Jan 27 16:58:48 2015 +0100 @@ -657,7 +657,7 @@ } CompareNode compare = (CompareNode) condition(); - if (compare.usages().count() != 1) { + if (compare.getUsageCount() != 1) { return false; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Tue Jan 27 16:58:48 2015 +0100 @@ -65,7 +65,19 @@ * introduced any more. {@link FrameState} nodes are now associated with * {@link DeoptimizingNode} nodes. */ - AFTER_FSA + AFTER_FSA; + + public boolean allowsFloatingGuards() { + return this == FLOATING_GUARDS; + } + + public boolean areFrameStatesAtDeopts() { + return this == AFTER_FSA; + } + + public boolean areFrameStatesAtSideEffects() { + return !this.areFrameStatesAtDeopts(); + } } public static final int INVOCATION_ENTRY_BCI = -1;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java Tue Jan 27 16:58:48 2015 +0100 @@ -48,12 +48,12 @@ return stamp; } - public void setStamp(Stamp stamp) { + public final void setStamp(Stamp stamp) { this.stamp = stamp; } @Override - public StructuredGraph graph() { + public final StructuredGraph graph() { return (StructuredGraph) super.graph(); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/VirtualState.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/VirtualState.java Tue Jan 27 16:58:48 2015 +0100 @@ -32,9 +32,9 @@ @NodeInfo(allowedUsageTypes = {InputType.State}) public abstract class VirtualState extends Node { - public interface NodeClosure<T extends Node> { + public abstract static class NodeClosure<T extends Node> { - void apply(Node usage, T node); + public abstract void apply(Node usage, T node); } public interface VirtualClosure { @@ -54,4 +54,9 @@ public abstract boolean isPartOfThisState(VirtualState state); + @Override + public final StructuredGraph graph() { + return (StructuredGraph) super.graph(); + } + }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/WeakCounterNode.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/WeakCounterNode.java Tue Jan 27 16:58:48 2015 +0100 @@ -45,7 +45,7 @@ @Override public void simplify(SimplifierTool tool) { - if (checkedValue instanceof FloatingNode && checkedValue.usages().count() == 1) { + if (checkedValue instanceof FloatingNode && checkedValue.getUsageCount() == 1) { tool.addToWorkList(checkedValue); graph().removeFixed(this); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BranchProbabilityNode.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BranchProbabilityNode.java Tue Jan 27 16:58:48 2015 +0100 @@ -113,7 +113,7 @@ } private boolean isSubstitutionGraph() { - return usages().count() == 1 && usages().first() instanceof ReturnNode; + return getUsageCount() == 1 && usages().first() instanceof ReturnNode; } /**
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Tue Jan 27 16:58:48 2015 +0100 @@ -69,7 +69,7 @@ @Override public boolean verify() { - assert usages().count() <= 1 : "call target may only be used by a single invoke"; + assert getUsageCount() <= 1 : "call target may only be used by a single invoke"; for (Node n : usages()) { assertTrue(n instanceof Invoke, "call target can only be used from an invoke (%s)", n); } @@ -171,7 +171,7 @@ if (singleImplementor != null && !singleImplementor.equals(declaredReceiverType)) { ResolvedJavaMethod singleImplementorMethod = singleImplementor.resolveMethod(targetMethod(), invoke().getContextType(), true); if (singleImplementorMethod != null) { - assert graph().getGuardsStage().ordinal() < StructuredGraph.GuardsStage.FIXED_DEOPTS.ordinal() : "Graph already fixed!"; + assert graph().getGuardsStage().allowsFloatingGuards() : "Graph already fixed!"; /** * We have an invoke on an interface with a single implementor. We can replace this * with an invoke virtual.
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java Tue Jan 27 16:58:48 2015 +0100 @@ -24,9 +24,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.nodes.extended.*; public interface LoweringTool { @@ -47,8 +45,6 @@ Assumptions assumptions(); - Block getBlockFor(Node node); - /** * Gets the closest fixed node preceding the node currently being lowered. */
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java Tue Jan 27 16:58:48 2015 +0100 @@ -106,8 +106,8 @@ @Override protected void run(StructuredGraph graph) { - assert graph.getGuardsStage().ordinal() >= GuardsStage.FIXED_DEOPTS.ordinal() && checkFixedDeopts(graph); - if (graph.getGuardsStage().ordinal() < GuardsStage.AFTER_FSA.ordinal()) { + assert !graph.getGuardsStage().allowsFloatingGuards() && checkFixedDeopts(graph); + if (graph.getGuardsStage().areFrameStatesAtSideEffects()) { ReentrantNodeIterator.apply(new FrameStateAssignmentClosure(), graph.start(), null); graph.setGuardsStage(GuardsStage.AFTER_FSA); graph.getNodes(FrameState.class).filter(state -> state.hasNoUsages()).forEach(GraphUtil::killWithUnusedFloatingInputs);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java Tue Jan 27 16:58:48 2015 +0100 @@ -193,7 +193,7 @@ @Override protected void run(StructuredGraph graph, MidTierContext context) { - if (graph.getGuardsStage().ordinal() < GuardsStage.FIXED_DEOPTS.ordinal()) { + if (graph.getGuardsStage().allowsFloatingGuards()) { SchedulePhase schedule = new SchedulePhase(SchedulingStrategy.EARLIEST); schedule.apply(graph);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Tue Jan 27 16:58:48 2015 +0100 @@ -77,14 +77,12 @@ private final NodeBitMap activeGuards; private AnchoringNode guardAnchor; private FixedWithNextNode lastFixedNode; - private ControlFlowGraph cfg; - public LoweringToolImpl(PhaseContext context, AnchoringNode guardAnchor, NodeBitMap activeGuards, FixedWithNextNode lastFixedNode, ControlFlowGraph cfg) { + public LoweringToolImpl(PhaseContext context, AnchoringNode guardAnchor, NodeBitMap activeGuards, FixedWithNextNode lastFixedNode) { this.context = context; this.guardAnchor = guardAnchor; this.activeGuards = activeGuards; this.lastFixedNode = lastFixedNode; - this.cfg = cfg; } @Override @@ -141,7 +139,7 @@ } } StructuredGraph graph = before.graph(); - if (condition.graph().getGuardsStage().ordinal() >= StructuredGraph.GuardsStage.FIXED_DEOPTS.ordinal()) { + if (!condition.graph().getGuardsStage().allowsFloatingGuards()) { FixedGuardNode fixedGuard = graph.add(new FixedGuardNode(condition, deoptReason, action, negated)); graph.addBeforeFixed(before, fixedGuard); DummyGuardHandle handle = graph.add(new DummyGuardHandle(fixedGuard)); @@ -158,11 +156,6 @@ } } - @Override - public Block getBlockFor(Node node) { - return cfg.blockFor(node); - } - public FixedWithNextNode lastFixedNode() { return lastFixedNode; } @@ -298,7 +291,7 @@ private AnchoringNode process(final Block b, final NodeBitMap activeGuards, final AnchoringNode startAnchor) { - final LoweringToolImpl loweringTool = new LoweringToolImpl(context, startAnchor, activeGuards, b.getBeginNode(), schedule.getCFG()); + final LoweringToolImpl loweringTool = new LoweringToolImpl(context, startAnchor, activeGuards, b.getBeginNode()); // Lower the instructions of this block. List<ValueNode> nodes = schedule.nodesFor(b);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/OptimizeGuardAnchorsPhase.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/OptimizeGuardAnchorsPhase.java Tue Jan 27 16:58:48 2015 +0100 @@ -96,7 +96,7 @@ int successorCount = controlSplit.successors().count(); List<GuardNode> otherGuards = new ArrayList<>(successorCount - 1); for (GuardNode guard : successor.guards().snapshot()) { - if (guard.isDeleted() || guard.condition().usages().count() < successorCount) { + if (guard.isDeleted() || guard.condition().getUsageCount() < successorCount) { continue; } for (GuardNode conditonGuard : guard.condition().usages().filter(GuardNode.class)) { @@ -129,10 +129,10 @@ private static BeginNode findMinimumUsagesSuccessor(ControlSplitNode controlSplit) { NodePosIterator successors = controlSplit.successors().iterator(); BeginNode min = (BeginNode) successors.next(); - int minUsages = min.usages().count(); + int minUsages = min.getUsageCount(); while (successors.hasNext()) { BeginNode successor = (BeginNode) successors.next(); - int count = successor.usages().count(); + int count = successor.getUsageCount(); if (count < minUsages) { minUsages = count; min = successor;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java Tue Jan 27 16:58:48 2015 +0100 @@ -29,7 +29,6 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.StructuredGraph.GuardsStage; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.util.*; @@ -47,7 +46,7 @@ if (context.getTarget().implicitNullCheckLimit <= 0) { return; } - assert graph.getGuardsStage().ordinal() >= GuardsStage.AFTER_FSA.ordinal(); + assert graph.getGuardsStage().areFrameStatesAtDeopts(); for (DeoptimizeNode deopt : graph.getNodes(DeoptimizeNode.class)) { tryUseTrappingNullCheck(deopt, deopt.predecessor(), deopt.reason(), deopt.getSpeculation());
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ReentrantBlockIterator.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ReentrantBlockIterator.java Tue Jan 27 16:58:48 2015 +0100 @@ -23,8 +23,8 @@ package com.oracle.graal.phases.graph; import java.util.*; +import java.util.function.*; -import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; @@ -61,7 +61,7 @@ } public static <StateT> LoopInfo<StateT> processLoop(BlockIteratorClosure<StateT> closure, Loop<Block> loop, StateT initialState) { - Map<FixedNode, StateT> blockEndStates = apply(closure, loop.getHeader(), initialState, CollectionsFactory.newSet(loop.getBlocks())); + Map<FixedNode, StateT> blockEndStates = apply(closure, loop.getHeader(), initialState, block -> !(block.getLoop() == loop || block.isLoopHeader())); List<Block> predecessors = loop.getHeader().getPredecessors(); LoopInfo<StateT> info = new LoopInfo<>(predecessors.size() - 1, loop.getExits().size()); @@ -84,7 +84,7 @@ apply(closure, start, closure.getInitialState(), null); } - public static <StateT> Map<FixedNode, StateT> apply(BlockIteratorClosure<StateT> closure, Block start, StateT initialState, Set<Block> boundary) { + public static <StateT> Map<FixedNode, StateT> apply(BlockIteratorClosure<StateT> closure, Block start, StateT initialState, Predicate<Block> stopAtBlock) { Deque<Block> blockQueue = new ArrayDeque<>(); /* * States are stored on EndNodes before merges, and on BeginNodes after ControlSplitNodes. @@ -95,81 +95,50 @@ Block current = start; while (true) { - if (boundary != null && !boundary.contains(current)) { + Block next = null; + if (stopAtBlock != null && stopAtBlock.test(current)) { states.put(current.getBeginNode(), state); } else { state = closure.processBlock(current, state); - if (current.getSuccessors().isEmpty()) { + List<Block> successors = current.getSuccessors(); + if (successors.isEmpty()) { // nothing to do... - } else if (current.getSuccessors().size() == 1) { - Block successor = current.getSuccessors().get(0); + } else if (successors.size() == 1) { + Block successor = successors.get(0); if (successor.isLoopHeader()) { if (current.isLoopEnd()) { // nothing to do... loop ends only lead to loop begins we've already // visited states.put(current.getEndNode(), state); } else { - // recurse into the loop - Loop<Block> loop = successor.getLoop(); - LoopBeginNode loopBegin = (LoopBeginNode) loop.getHeader().getBeginNode(); - assert successor.getBeginNode() == loopBegin; - - List<StateT> exitStates = closure.processLoop(loop, state); - - int i = 0; - assert loop.getExits().size() == exitStates.size(); - for (Block exit : loop.getExits()) { - states.put(exit.getBeginNode(), exitStates.get(i++)); - blockQueue.addFirst(exit); - } + recurseIntoLoop(closure, blockQueue, states, state, successor); } } else if (current.getEndNode() instanceof AbstractEndNode) { - assert successor.getPredecessors().size() > 1 : "invalid block schedule at " + successor.getBeginNode(); AbstractEndNode end = (AbstractEndNode) current.getEndNode(); // add the end node and see if the merge is ready for processing MergeNode merge = end.merge(); - boolean endsVisited = true; - for (AbstractEndNode forwardEnd : merge.forwardEnds()) { - if (forwardEnd != current.getEndNode() && !states.containsKey(forwardEnd)) { - endsVisited = false; - break; - } - } - if (endsVisited) { - ArrayList<StateT> mergedStates = new ArrayList<>(merge.forwardEndCount()); - for (Block predecessor : successor.getPredecessors()) { - assert predecessor == current || states.containsKey(predecessor.getEndNode()); - StateT endState = predecessor == current ? state : states.remove(predecessor.getEndNode()); - mergedStates.add(endState); - } + if (allEndsVisited(states, current, merge)) { + ArrayList<StateT> mergedStates = mergeStates(states, state, current, successor, merge); state = closure.merge(successor, mergedStates); - current = successor; - continue; + next = successor; } else { assert !states.containsKey(end); states.put(end, state); } } else { - assert successor.getPredecessors().size() == 1 : "invalid block schedule at " + successor.getBeginNode(); - current = successor; - continue; + next = successor; } } else { - assert current.getSuccessors().size() > 1; - for (int i = 1; i < current.getSuccessors().size(); i++) { - Block successor = current.getSuccessors().get(i); - blockQueue.addFirst(successor); - states.put(successor.getBeginNode(), closure.cloneState(state)); - } - current = current.getSuccessors().get(0); - continue; + next = processMultipleSuccessors(closure, blockQueue, states, state, successors); } } // get next queued block - if (blockQueue.isEmpty()) { + if (next != null) { + current = next; + } else if (blockQueue.isEmpty()) { return states; } else { current = blockQueue.removeFirst(); @@ -179,4 +148,49 @@ } } } + + private static <StateT> boolean allEndsVisited(Map<FixedNode, StateT> states, Block current, MergeNode merge) { + for (AbstractEndNode forwardEnd : merge.forwardEnds()) { + if (forwardEnd != current.getEndNode() && !states.containsKey(forwardEnd)) { + return false; + } + } + return true; + } + + private static <StateT> Block processMultipleSuccessors(BlockIteratorClosure<StateT> closure, Deque<Block> blockQueue, Map<FixedNode, StateT> states, StateT state, List<Block> successors) { + assert successors.size() > 1; + for (int i = 1; i < successors.size(); i++) { + Block successor = successors.get(i); + blockQueue.addFirst(successor); + states.put(successor.getBeginNode(), closure.cloneState(state)); + } + return successors.get(0); + } + + private static <StateT> ArrayList<StateT> mergeStates(Map<FixedNode, StateT> states, StateT state, Block current, Block successor, MergeNode merge) { + ArrayList<StateT> mergedStates = new ArrayList<>(merge.forwardEndCount()); + for (Block predecessor : successor.getPredecessors()) { + assert predecessor == current || states.containsKey(predecessor.getEndNode()); + StateT endState = predecessor == current ? state : states.remove(predecessor.getEndNode()); + mergedStates.add(endState); + } + return mergedStates; + } + + private static <StateT> void recurseIntoLoop(BlockIteratorClosure<StateT> closure, Deque<Block> blockQueue, Map<FixedNode, StateT> states, StateT state, Block successor) { + // recurse into the loop + Loop<Block> loop = successor.getLoop(); + LoopBeginNode loopBegin = (LoopBeginNode) loop.getHeader().getBeginNode(); + assert successor.getBeginNode() == loopBegin; + + List<StateT> exitStates = closure.processLoop(loop, state); + + int i = 0; + assert loop.getExits().size() == exitStates.size(); + for (Block exit : loop.getExits()) { + states.put(exit.getBeginNode(), exitStates.get(i++)); + blockQueue.addFirst(exit); + } + } }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Tue Jan 27 16:58:48 2015 +0100 @@ -77,11 +77,6 @@ LATEST_OUT_OF_LOOPS } - public static enum MemoryScheduling { - NONE, - OPTIMAL - } - private class KillSet implements Iterable<LocationIdentity> { private List<LocationIdentity> list; @@ -272,22 +267,15 @@ private BlockMap<List<ValueNode>> blockToNodesMap; private BlockMap<KillSet> blockToKillSet; private final SchedulingStrategy selectedStrategy; - private final MemoryScheduling memsched; public SchedulePhase() { this(OptScheduleOutOfLoops.getValue() ? SchedulingStrategy.LATEST_OUT_OF_LOOPS : SchedulingStrategy.LATEST); } public SchedulePhase(SchedulingStrategy strategy) { - this.memsched = MemoryScheduling.OPTIMAL; this.selectedStrategy = strategy; } - public SchedulePhase(SchedulingStrategy strategy, MemoryScheduling memsched) { - this.selectedStrategy = strategy; - this.memsched = memsched; - } - @Override protected void run(StructuredGraph graph) { assert GraphOrder.assertNonCyclicGraph(graph); @@ -295,7 +283,7 @@ earliestCache = graph.createNodeMap(); blockToNodesMap = new BlockMap<>(cfg); - if (memsched == MemoryScheduling.OPTIMAL && selectedStrategy != SchedulingStrategy.EARLIEST) { + if (selectedStrategy != SchedulingStrategy.EARLIEST) { blockToKillSet = new BlockMap<>(cfg); } @@ -324,7 +312,7 @@ private void printScheduleHelper(String desc) { Formatter buf = new Formatter(); - buf.format("=== %s / %s / %s (%s) ===%n", getCFG().getStartBlock().getBeginNode().graph(), selectedStrategy, memsched, desc); + buf.format("=== %s / %s / %s ===%n", getCFG().getStartBlock().getBeginNode().graph(), selectedStrategy, desc); for (Block b : getCFG().getBlocks()) { buf.format("==== b: %s (loopDepth: %s). ", b, b.getLoopDepth()); buf.format("dom: %s. ", b.getDominator()); @@ -438,7 +426,7 @@ break; case LATEST: case LATEST_OUT_OF_LOOPS: - boolean scheduleRead = memsched == MemoryScheduling.OPTIMAL && node instanceof FloatingReadNode && !((FloatingReadNode) node).location().getLocationIdentity().isImmutable(); + boolean scheduleRead = node instanceof FloatingReadNode && !((FloatingReadNode) node).location().getLocationIdentity().isImmutable(); if (scheduleRead) { FloatingReadNode read = (FloatingReadNode) node; block = optimalBlock(read, strategy); @@ -472,7 +460,7 @@ throw new GraalInternalError("unknown scheduling strategy"); } if (!dominates(earliestBlock, block)) { - throw new SchedulingError("%s: Graph cannot be scheduled : inconsistent for %s, %d usages, (%s needs to dominate %s)", node.graph(), node, node.usages().count(), earliestBlock, block); + throw new SchedulingError("%s: Graph cannot be scheduled : inconsistent for %s, %d usages, (%s needs to dominate %s)", node.graph(), node, node.getUsageCount(), earliestBlock, block); } cfg.getNodeToBlock().set(node, block); blockToNodesMap.get(block).add(node); @@ -506,8 +494,6 @@ * */ private Block optimalBlock(FloatingReadNode n, SchedulingStrategy strategy) { - assert memsched == MemoryScheduling.OPTIMAL; - LocationIdentity locid = n.location().getLocationIdentity(); assert !locid.isImmutable(); @@ -535,9 +521,6 @@ // the dominated block is not a successor -> we have a split assert dominatedBlock.getBeginNode() instanceof MergeNode; - HashSet<Block> region = computeRegion(currentBlock, dominatedBlock); - Debug.log("> merge. %s: region for %s -> %s: %s", n, currentBlock, dominatedBlock, region); - NewMemoryScheduleClosure closure = null; if (currentBlock == upperBoundBlock) { assert earliestBlock == upperBoundBlock; @@ -547,7 +530,7 @@ closure = new NewMemoryScheduleClosure(); } Map<FixedNode, KillSet> states; - states = ReentrantBlockIterator.apply(closure, currentBlock, new KillSet(), region); + states = ReentrantBlockIterator.apply(closure, currentBlock, new KillSet(), block -> block == dominatedBlock); KillSet mergeState = states.get(dominatedBlock.getBeginNode()); if (mergeState.isKilled(locid)) { @@ -587,31 +570,6 @@ } /** - * compute a set that contains all blocks in a region spanned by dominatorBlock and - * dominatedBlock (exclusive the dominatedBlock). - */ - private static HashSet<Block> computeRegion(Block dominatorBlock, Block dominatedBlock) { - HashSet<Block> region = new HashSet<>(); - Queue<Block> workList = new LinkedList<>(); - - region.add(dominatorBlock); - workList.addAll(dominatorBlock.getSuccessors()); - while (workList.size() > 0) { - Block current = workList.poll(); - if (current != dominatedBlock) { - region.add(current); - for (Block b : current.getSuccessors()) { - if (!region.contains(b) && !workList.contains(b)) { - workList.offer(b); - } - } - } - } - assert !region.contains(dominatedBlock) && region.containsAll(dominatedBlock.getPredecessors()); - return region; - } - - /** * Calculates the last block that the given node could be scheduled in, i.e., the common * dominator of all usages. To do so all usages are also assigned to blocks. * @@ -993,16 +951,14 @@ SortState state = new SortState(b, visited, beforeLastLocation, new ArrayList<>(blockToNodesMap.get(b).size() + 2)); List<ValueNode> instructions = blockToNodesMap.get(b); - if (memsched == MemoryScheduling.OPTIMAL) { - for (ValueNode i : instructions) { - if (i instanceof FloatingReadNode) { - FloatingReadNode frn = (FloatingReadNode) i; - if (!frn.location().getLocationIdentity().isImmutable()) { - state.addRead(frn); - if (nodesFor(b).contains(frn.getLastLocationAccess())) { - assert !state.isBeforeLastLocation(frn); - state.markBeforeLastLocation(frn); - } + for (ValueNode i : instructions) { + if (i instanceof FloatingReadNode) { + FloatingReadNode frn = (FloatingReadNode) i; + if (!frn.location().getLocationIdentity().isImmutable()) { + state.addRead(frn); + if (nodesFor(b).contains(frn.getLastLocationAccess())) { + assert !state.isBeforeLastLocation(frn); + state.markBeforeLastLocation(frn); } } } @@ -1094,7 +1050,7 @@ } } - if (memsched == MemoryScheduling.OPTIMAL && state.readsSize() != 0) { + if (state.readsSize() != 0) { if (i instanceof MemoryCheckpoint.Single) { LocationIdentity identity = ((MemoryCheckpoint.Single) i).getLocationIdentity(); processKillLocation(i, identity, state);
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java Tue Jan 27 16:58:48 2015 +0100 @@ -34,7 +34,6 @@ import com.oracle.graal.phases.graph.*; import com.oracle.graal.phases.graph.ReentrantBlockIterator.BlockIteratorClosure; import com.oracle.graal.phases.schedule.*; -import com.oracle.graal.phases.schedule.SchedulePhase.MemoryScheduling; import com.oracle.graal.phases.schedule.SchedulePhase.SchedulingStrategy; public final class GraphOrder { @@ -135,7 +134,7 @@ */ public static boolean assertSchedulableGraph(final StructuredGraph graph) { try { - final SchedulePhase schedule = new SchedulePhase(SchedulingStrategy.LATEST_OUT_OF_LOOPS, MemoryScheduling.NONE); + final SchedulePhase schedule = new SchedulePhase(SchedulingStrategy.LATEST_OUT_OF_LOOPS); final Map<LoopBeginNode, NodeBitMap> loopEntryStates = Node.newIdentityMap(); schedule.apply(graph, false); @@ -164,6 +163,7 @@ if (pendingStateAfter != null && node instanceof FixedNode) { pendingStateAfter.applyToNonVirtual(new NodeClosure<Node>() { + @Override public void apply(Node usage, Node nonVirtualNode) { assert currentState.isMarked(nonVirtualNode) || nonVirtualNode instanceof VirtualObjectNode : nonVirtualNode + " not available at virtualstate " + usage + " before " + node + " in block " + block + " \n" + list; @@ -197,8 +197,11 @@ for (Node input : node.inputs()) { if (input != stateAfter) { if (input instanceof FrameState) { - ((FrameState) input).applyToNonVirtual((usage, nonVirtual) -> { - assert currentState.isMarked(nonVirtual) : nonVirtual + " not available at " + node + " in block " + block + "\n" + list; + ((FrameState) input).applyToNonVirtual(new VirtualState.NodeClosure<Node>() { + @Override + public void apply(Node usage, Node nonVirtual) { + assert currentState.isMarked(nonVirtual) : nonVirtual + " not available at " + node + " in block " + block + "\n" + list; + } }); } else { assert currentState.isMarked(input) || input instanceof VirtualObjectNode : input + " not available at " + node + " in block " + block + "\n" + list; @@ -221,6 +224,7 @@ } if (pendingStateAfter != null) { pendingStateAfter.applyToNonVirtual(new NodeClosure<Node>() { + @Override public void apply(Node usage, Node nonVirtualNode) { assert currentState.isMarked(nonVirtualNode) || nonVirtualNode instanceof VirtualObjectNode : nonVirtualNode + " not available at virtualstate " + usage + " at end of block " + block + " \n" + list;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java Tue Jan 27 16:58:48 2015 +0100 @@ -228,7 +228,7 @@ protected void lowerLoadHubNode(LoadHubNode loadHub) { StructuredGraph graph = loadHub.graph(); - if (graph.getGuardsStage().ordinal() < StructuredGraph.GuardsStage.FIXED_DEOPTS.ordinal()) { + if (graph.getGuardsStage().allowsFloatingGuards()) { return; } ValueNode hub = createReadHub(graph, loadHub.getValue(), loadHub.getGuard()); @@ -270,7 +270,7 @@ ReadNode memoryRead = createUnsafeRead(graph, load, valueAnchorNode); graph.replaceFixedWithFixed(load, valueAnchorNode); graph.addAfterFixed(valueAnchorNode, memoryRead); - } else if (graph.getGuardsStage().ordinal() > StructuredGraph.GuardsStage.FLOATING_GUARDS.ordinal()) { + } else if (!graph.getGuardsStage().allowsFloatingGuards()) { assert load.getKind() != Kind.Illegal; ReadNode memoryRead = createUnsafeRead(graph, load, null); // An unsafe read must not float outside its block otherwise
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Tue Jan 27 16:58:48 2015 +0100 @@ -407,7 +407,7 @@ Debug.log("%s: Checkcast used in a return with forNodeIntrinsic stamp", Debug.contextSnapshot(JavaMethod.class)); } else if (usage instanceof IsNullNode) { if (!usage.hasNoUsages()) { - assert usage.usages().count() == 1 && usage.usages().first().predecessor() == input : usage + " " + input; + assert usage.getUsageCount() == 1 && usage.usages().first().predecessor() == input : usage + " " + input; graph.replaceFloating((FloatingNode) usage, LogicConstantNode.contradiction(graph)); Debug.log("%s: Replaced IsNull with false", Debug.contextSnapshot(JavaMethod.class)); } else {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Tue Jan 27 16:58:48 2015 +0100 @@ -675,7 +675,7 @@ GuardsStage guardsStage = args.cacheKey.guardsStage; // Perform lowering on the snippet - if (guardsStage.ordinal() >= GuardsStage.FIXED_DEOPTS.ordinal()) { + if (!guardsStage.allowsFloatingGuards()) { new GuardLoweringPhase().apply(snippetCopy, null); } snippetCopy.setGuardsStage(guardsStage);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java Tue Jan 27 16:58:48 2015 +0100 @@ -134,9 +134,9 @@ new RemoveValueProxyPhase().apply(replacementGraph); } GuardsStage guardsStage = graph().getGuardsStage(); - if (guardsStage.ordinal() >= GuardsStage.FIXED_DEOPTS.ordinal()) { + if (!guardsStage.allowsFloatingGuards()) { new GuardLoweringPhase().apply(replacementGraph, null); - if (guardsStage.ordinal() >= GuardsStage.AFTER_FSA.ordinal()) { + if (guardsStage.areFrameStatesAtDeopts()) { new FrameStateAssignmentPhase().apply(replacementGraph); } }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java Tue Jan 27 16:58:48 2015 +0100 @@ -177,9 +177,7 @@ assert info.exitStates.size() == loop.getExits().size(); loopEntryStates.put((LoopBeginNode) loop.getHeader().getBeginNode(), loopEntryState); - for (int i = 0; i < loop.getExits().size(); i++) { - assert info.exitStates.get(i) != null : "no loop exit state at " + loop.getExits().get(i) + " / " + loop.getHeader(); - } + assert assertExitStatesNonEmpty(loop, info); return info.exitStates; } else { @@ -192,6 +190,13 @@ throw new GraalInternalError("too many iterations at %s", loop); } + private boolean assertExitStatesNonEmpty(Loop<Block> loop, LoopInfo<BlockT> info) { + for (int i = 0; i < loop.getExits().size(); i++) { + assert info.exitStates.get(i) != null : "no loop exit state at " + loop.getExits().get(i) + " / " + loop.getHeader(); + } + return true; + } + protected abstract void processLoopExit(LoopExitNode exitNode, BlockT initialState, BlockT exitState, GraphEffectList effects); protected abstract MergeProcessor createMergeProcessor(Block merge);
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java Tue Jan 27 16:58:48 2015 +0100 @@ -190,7 +190,7 @@ } } if (phi) { - PhiNode phiNode = getCachedPhi(entry, value.stamp().unrestricted()); + PhiNode phiNode = getPhi(entry, value.stamp().unrestricted()); mergeEffects.addFloatingNode(phiNode, "mergeReadCache"); for (int i = 0; i < states.size(); i++) { afterMergeEffects.addPhiInput(phiNode, states.get(i).getReadCache(key.object, key.identity, PEReadEliminationClosure.this)); @@ -222,7 +222,7 @@ values[i] = value; } - PhiNode phiNode = getCachedPhi(new ReadCacheEntry(identity, phi), values[0].stamp().unrestricted()); + PhiNode phiNode = getPhi(new ReadCacheEntry(identity, phi), values[0].stamp().unrestricted()); mergeEffects.addFloatingNode(phiNode, "mergeReadCachePhi"); for (int i = 0; i < values.length; i++) { afterMergeEffects.addPhiInput(phiNode, values[i]);
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeBlockState.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeBlockState.java Tue Jan 27 16:58:48 2015 +0100 @@ -102,7 +102,7 @@ commit.addLocks(monitorIds); } - assert commit.usages().filter(AllocatedObjectNode.class).count() == commit.usages().count(); + assert commit.usages().filter(AllocatedObjectNode.class).count() == commit.getUsageCount(); List<AllocatedObjectNode> materializedValues = commit.usages().filter(AllocatedObjectNode.class).snapshot(); for (int i = 0; i < commit.getValues().size(); i++) { if (materializedValues.contains(commit.getValues().get(i))) {
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Tue Jan 27 16:58:48 2015 +0100 @@ -56,6 +56,38 @@ private final NodeBitMap usages; private final VirtualizerToolImpl tool; + private final class CollectVirtualObjectsClosure extends NodeClosure<ValueNode> { + private final Set<ObjectState> virtual; + private final GraphEffectList effects; + private final BlockT state; + + private CollectVirtualObjectsClosure(Set<ObjectState> virtual, GraphEffectList effects, BlockT state) { + this.virtual = virtual; + this.effects = effects; + this.state = state; + } + + @Override + public void apply(Node usage, ValueNode value) { + ObjectState valueObj = getObjectState(state, value); + if (valueObj != null) { + virtual.add(valueObj); + effects.replaceFirstInput(usage, value, valueObj.virtual); + } else if (value instanceof VirtualObjectNode) { + ObjectState virtualObj = null; + for (ObjectState obj : state.getStates()) { + if (value == obj.virtual) { + virtualObj = obj; + break; + } + } + if (virtualObj != null) { + virtual.add(virtualObj); + } + } + } + } + /** * Final subclass of PartialEscapeClosure, for performance and to make everything behave nicely * with generics. @@ -108,11 +140,13 @@ return !(node instanceof CommitAllocationNode || node instanceof AllocatedObjectNode || node instanceof BoxNode); } if (isMarked) { - for (ValueNode input : node.inputs().filter(ValueNode.class)) { - ObjectState obj = getObjectState(state, input); - if (obj != null) { - VirtualUtil.trace("replacing input %s at %s: %s", input, node, obj); - replaceWithMaterialized(input, node, insertBefore, state, obj, effects, METRIC_MATERIALIZATIONS_UNHANDLED); + for (Node input : node.inputs()) { + if (input instanceof ValueNode) { + ObjectState obj = getObjectState(state, (ValueNode) input); + if (obj != null) { + VirtualUtil.trace("replacing input %s at %s: %s", input, node, obj); + replaceWithMaterialized(input, node, insertBefore, state, obj, effects, METRIC_MATERIALIZATIONS_UNHANDLED); + } } } if (node instanceof NodeWithState) { @@ -124,75 +158,76 @@ private void processNodeWithState(NodeWithState nodeWithState, final BlockT state, final GraphEffectList effects) { for (FrameState fs : nodeWithState.states()) { - FrameState frameState = fs; - if (frameState.usages().count() > 1) { - FrameState copy = (FrameState) frameState.copyWithInputs(); - nodeWithState.asNode().replaceFirstInput(frameState, copy); - frameState = copy; - } - final Set<ObjectState> virtual = new ArraySet<>(); - frameState.applyToNonVirtual(new NodeClosure<ValueNode>() { + FrameState frameState = getUniqueFramestate(nodeWithState, fs); + Set<ObjectState> virtual = new ArraySet<>(); + frameState.applyToNonVirtual(new CollectVirtualObjectsClosure(virtual, effects, state)); + collectLockedVirtualObjects(state, virtual); + collectReferencedVirtualObjects(state, virtual); + addVirtualMappings(state, effects, frameState, virtual); + } + } + + private static FrameState getUniqueFramestate(NodeWithState nodeWithState, FrameState frameState) { + if (frameState.getUsageCount() > 1) { + // Can happen for example from inlined snippets with multiple state split nodes. + FrameState copy = (FrameState) frameState.copyWithInputs(); + nodeWithState.asNode().replaceFirstInput(frameState, copy); + return copy; + } + return frameState; + } - @Override - public void apply(Node usage, ValueNode value) { - ObjectState valueObj = getObjectState(state, value); - if (valueObj != null) { - virtual.add(valueObj); - effects.replaceFirstInput(usage, value, valueObj.virtual); - } else if (value instanceof VirtualObjectNode) { - ObjectState virtualObj = null; - for (ObjectState obj : state.getStates()) { - if (value == obj.virtual) { - virtualObj = obj; - break; - } - } - if (virtualObj != null) { - virtual.add(virtualObj); - } - } - } - }); - for (ObjectState obj : state.getStates()) { - if (obj.isVirtual() && obj.hasLocks()) { - virtual.add(obj); - } + private void addVirtualMappings(final BlockT state, final GraphEffectList effects, FrameState frameState, Set<ObjectState> virtual) { + for (ObjectState obj : virtual) { + EscapeObjectState v; + if (obj.isVirtual()) { + v = createVirtualObjectState(state, obj); + } else { + v = new MaterializedObjectState(obj.virtual, obj.getMaterializedValue()); } + effects.addVirtualMapping(frameState, v); + } + } - ArrayDeque<ObjectState> queue = new ArrayDeque<>(virtual); - while (!queue.isEmpty()) { - ObjectState obj = queue.removeLast(); - if (obj.isVirtual()) { - for (ValueNode field : obj.getEntries()) { - if (field instanceof VirtualObjectNode) { - ObjectState fieldObj = state.getObjectState((VirtualObjectNode) field); - if (fieldObj.isVirtual() && !virtual.contains(fieldObj)) { - virtual.add(fieldObj); - queue.addLast(fieldObj); - } + private void collectReferencedVirtualObjects(final BlockT state, final Set<ObjectState> virtual) { + ArrayDeque<ObjectState> queue = new ArrayDeque<>(virtual); + while (!queue.isEmpty()) { + ObjectState obj = queue.removeLast(); + if (obj.isVirtual()) { + for (ValueNode entry : obj.getEntries()) { + if (entry instanceof VirtualObjectNode) { + ObjectState fieldObj = state.getObjectState((VirtualObjectNode) entry); + if (fieldObj.isVirtual() && !virtual.contains(fieldObj)) { + virtual.add(fieldObj); + queue.addLast(fieldObj); } } } } - for (ObjectState obj : virtual) { - EscapeObjectState v; - if (obj.isVirtual()) { - ValueNode[] fieldState = obj.getEntries().clone(); - for (int i = 0; i < fieldState.length; i++) { - ObjectState valueObj = getObjectState(state, fieldState[i]); - if (valueObj != null) { - if (valueObj.isVirtual()) { - fieldState[i] = valueObj.virtual; - } else { - fieldState[i] = valueObj.getMaterializedValue(); - } - } - } - v = new VirtualObjectState(obj.virtual, fieldState); + } + } + + private EscapeObjectState createVirtualObjectState(final BlockT state, ObjectState obj) { + EscapeObjectState v; + ValueNode[] fieldState = obj.getEntries().clone(); + for (int i = 0; i < fieldState.length; i++) { + ObjectState valueObj = getObjectState(state, fieldState[i]); + if (valueObj != null) { + if (valueObj.isVirtual()) { + fieldState[i] = valueObj.virtual; } else { - v = new MaterializedObjectState(obj.virtual, obj.getMaterializedValue()); + fieldState[i] = valueObj.getMaterializedValue(); } - effects.addVirtualMapping(frameState, v); + } + } + v = new VirtualObjectState(obj.virtual, fieldState); + return v; + } + + private void collectLockedVirtualObjects(final BlockT state, final Set<ObjectState> virtual) { + for (ObjectState obj : state.getStates()) { + if (obj.isVirtual() && obj.hasLocks()) { + virtual.add(obj); } } } @@ -213,7 +248,7 @@ } } - private boolean replaceWithMaterialized(ValueNode value, Node usage, FixedNode materializeBefore, BlockT state, ObjectState obj, GraphEffectList effects, DebugMetric metric) { + private boolean replaceWithMaterialized(Node value, Node usage, FixedNode materializeBefore, BlockT state, ObjectState obj, GraphEffectList effects, DebugMetric metric) { boolean materialized = ensureMaterialized(state, obj, materializeBefore, effects, metric); effects.replaceFirstInput(usage, value, obj.getMaterializedValue()); return materialized; @@ -221,44 +256,51 @@ @Override protected void processLoopExit(LoopExitNode exitNode, BlockT initialState, BlockT exitState, GraphEffectList effects) { - Map<VirtualObjectNode, ProxyNode> proxies = Node.newMap(); - - for (ProxyNode proxy : exitNode.proxies()) { - ObjectState obj = getObjectState(exitState, proxy.value()); - if (obj != null) { - proxies.put(obj.virtual, proxy); + if (exitNode.graph().hasValueProxies()) { + Map<VirtualObjectNode, ProxyNode> proxies = Node.newMap(); + for (ProxyNode proxy : exitNode.proxies()) { + ObjectState obj = getObjectState(exitState, proxy.value()); + if (obj != null) { + proxies.put(obj.virtual, proxy); + } } - } - if (exitNode.graph().hasValueProxies()) { for (ObjectState obj : exitState.getStates()) { ObjectState initialObj = initialState.getObjectStateOptional(obj.virtual); if (obj.isVirtual()) { - for (int i = 0; i < obj.getEntries().length; i++) { - ValueNode value = obj.getEntry(i); - if (!(value instanceof VirtualObjectNode || value.isConstant())) { - if (exitNode.loopBegin().isPhiAtMerge(value) || initialObj == null || !initialObj.isVirtual() || initialObj.getEntry(i) != value) { - ProxyNode proxy = new ValueProxyNode(value, exitNode); - obj.setEntry(i, proxy); - effects.addFloatingNode(proxy, "virtualProxy"); - } - } - } + processVirtualAtLoopExit(exitNode, effects, obj, initialObj); } else { - if (initialObj == null || initialObj.isVirtual()) { - ProxyNode proxy = proxies.get(obj.virtual); - if (proxy == null) { - proxy = new ValueProxyNode(obj.getMaterializedValue(), exitNode); - effects.addFloatingNode(proxy, "proxy"); - } else { - effects.replaceFirstInput(proxy, proxy.value(), obj.getMaterializedValue()); - // nothing to do - will be handled in processNode - } - obj.updateMaterializedValue(proxy); - } else { - if (initialObj.getMaterializedValue() == obj.getMaterializedValue()) { - Debug.log("materialized value changes within loop: %s vs. %s at %s", initialObj.getMaterializedValue(), obj.getMaterializedValue(), exitNode); - } - } + processMaterializedAtLoopExit(exitNode, effects, proxies, obj, initialObj); + } + } + } + } + + private static void processMaterializedAtLoopExit(LoopExitNode exitNode, GraphEffectList effects, Map<VirtualObjectNode, ProxyNode> proxies, ObjectState obj, ObjectState initialObj) { + if (initialObj == null || initialObj.isVirtual()) { + ProxyNode proxy = proxies.get(obj.virtual); + if (proxy == null) { + proxy = new ValueProxyNode(obj.getMaterializedValue(), exitNode); + effects.addFloatingNode(proxy, "proxy"); + } else { + effects.replaceFirstInput(proxy, proxy.value(), obj.getMaterializedValue()); + // nothing to do - will be handled in processNode + } + obj.updateMaterializedValue(proxy); + } else { + if (initialObj.getMaterializedValue() == obj.getMaterializedValue()) { + Debug.log("materialized value changes within loop: %s vs. %s at %s", initialObj.getMaterializedValue(), obj.getMaterializedValue(), exitNode); + } + } + } + + private static void processVirtualAtLoopExit(LoopExitNode exitNode, GraphEffectList effects, ObjectState obj, ObjectState initialObj) { + for (int i = 0; i < obj.getEntries().length; i++) { + ValueNode value = obj.getEntry(i); + if (!(value instanceof VirtualObjectNode || value.isConstant())) { + if (exitNode.loopBegin().isPhiAtMerge(value) || initialObj == null || !initialObj.isVirtual() || initialObj.getEntry(i) != value) { + ProxyNode proxy = new ValueProxyNode(value, exitNode); + obj.setEntry(i, proxy); + effects.addFloatingNode(proxy, "virtualProxy"); } } } @@ -271,15 +313,28 @@ protected class MergeProcessor extends EffectsClosure<BlockT>.MergeProcessor { - private final HashMap<Object, ValuePhiNode> materializedPhis = CollectionsFactory.newMap(); - private final Map<ValueNode, ValuePhiNode[]> valuePhis = Node.newIdentityMap(); - private final Map<ValuePhiNode, VirtualObjectNode> valueObjectVirtuals = Node.newIdentityMap(); + private HashMap<Object, ValuePhiNode> materializedPhis; + private Map<ValueNode, ValuePhiNode[]> valuePhis; + private Map<ValuePhiNode, VirtualObjectNode> valueObjectVirtuals; + private final boolean needsCaching; public MergeProcessor(Block mergeBlock) { super(mergeBlock); + needsCaching = mergeBlock.isLoopHeader(); } - protected <T> PhiNode getCachedPhi(T virtual, Stamp stamp) { + protected <T> PhiNode getPhi(T virtual, Stamp stamp) { + if (needsCaching) { + return getPhiCached(virtual, stamp); + } else { + return new ValuePhiNode(stamp, merge); + } + } + + private <T> PhiNode getPhiCached(T virtual, Stamp stamp) { + if (materializedPhis == null) { + materializedPhis = CollectionsFactory.newMap(); + } ValuePhiNode result = materializedPhis.get(virtual); if (result == null) { result = new ValuePhiNode(stamp, merge); @@ -289,6 +344,17 @@ } private PhiNode[] getValuePhis(ValueNode key, int entryCount) { + if (needsCaching) { + return getValuePhisCached(key, entryCount); + } else { + return new ValuePhiNode[entryCount]; + } + } + + private PhiNode[] getValuePhisCached(ValueNode key, int entryCount) { + if (valuePhis == null) { + valuePhis = Node.newIdentityMap(); + } ValuePhiNode[] result = valuePhis.get(key); if (result == null) { result = new ValuePhiNode[entryCount]; @@ -299,6 +365,17 @@ } private VirtualObjectNode getValueObjectVirtual(ValuePhiNode phi, VirtualObjectNode virtual) { + if (needsCaching) { + return getValueObjectVirtualCached(phi, virtual); + } else { + return virtual.duplicate(); + } + } + + private VirtualObjectNode getValueObjectVirtualCached(ValuePhiNode phi, VirtualObjectNode virtual) { + if (valueObjectVirtuals == null) { + valueObjectVirtuals = Node.newIdentityMap(); + } VirtualObjectNode result = valueObjectVirtuals.get(phi); if (result == null) { result = virtual.duplicate(); @@ -321,10 +398,7 @@ super.merge(states); // calculate the set of virtual objects that exist in all predecessors - Set<VirtualObjectNode> virtualObjTemp = Node.newSet(states.get(0).getVirtualObjects()); - for (int i = 1; i < states.size(); i++) { - virtualObjTemp.retainAll(states.get(i).getVirtualObjects()); - } + Set<VirtualObjectNode> virtualObjTemp = intersectVirtualObjects(states); ObjectState[] objStates = new ObjectState[states.size()]; boolean materialized; @@ -356,12 +430,14 @@ if (uniqueMaterializedValue != null) { newState.addObject(object, new ObjectState(object, uniqueMaterializedValue, EscapeState.Materialized, null)); } else { - PhiNode materializedValuePhi = getCachedPhi(object, StampFactory.forKind(Kind.Object)); + PhiNode materializedValuePhi = getPhi(object, StampFactory.forKind(Kind.Object)); mergeEffects.addFloatingNode(materializedValuePhi, "materializedPhi"); for (int i = 0; i < objStates.length; i++) { ObjectState obj = objStates[i]; - Block predecessor = mergeBlock.getPredecessors().get(i); - materialized |= ensureMaterialized(states.get(i), obj, predecessor.getEndNode(), blockEffects.get(predecessor), METRIC_MATERIALIZATIONS_MERGE); + if (obj.isVirtual()) { + Block predecessor = mergeBlock.getPredecessors().get(i); + materialized |= ensureMaterialized(states.get(i), obj, predecessor.getEndNode(), blockEffects.get(predecessor), METRIC_MATERIALIZATIONS_MERGE); + } afterMergeEffects.addPhiInput(materializedValuePhi, obj.getMaterializedValue()); } newState.addObject(object, new ObjectState(object, materializedValuePhi, EscapeState.Materialized, null)); @@ -382,6 +458,14 @@ } while (materialized); } + private Set<VirtualObjectNode> intersectVirtualObjects(List<BlockT> states) { + Set<VirtualObjectNode> virtualObjTemp = Node.newSet(states.get(0).getVirtualObjects()); + for (int i = 1; i < states.size(); i++) { + virtualObjTemp.retainAll(states.get(i).getVirtualObjects()); + } + return virtualObjTemp; + } + /** * Try to merge multiple virtual object states into a single object state. If the incoming * object states are compatible, then this method will create PhiNodes for the object's @@ -489,7 +573,7 @@ return materialized; } else { // not compatible: materialize in all predecessors - PhiNode materializedValuePhi = getCachedPhi(object, StampFactory.forKind(Kind.Object)); + PhiNode materializedValuePhi = getPhi(object, StampFactory.forKind(Kind.Object)); for (int i = 0; i < blockStates.size(); i++) { ObjectState obj = objStates[i]; Block predecessor = mergeBlock.getPredecessors().get(i);
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java Tue Jan 27 15:10:32 2015 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java Tue Jan 27 16:58:48 2015 +0100 @@ -61,7 +61,7 @@ @Override public Node canonical(CanonicalizerTool tool) { - if (usages().count() == 0) { + if (getUsageCount() == 0) { /* If the cast is unused, it can be eliminated. */ return input; }