# HG changeset patch # User Lukas Stadler # Date 1361976694 -3600 # Node ID 649379d3f88d0fe1c3d5a5b0eed1f51407fb8599 # Parent f7b40e9d490c7439eee990bed006ee17ffcd7766 don't kill memory proxies during RemoveValueProxyPhase diff -r f7b40e9d490c -r 649379d3f88d 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 Wed Feb 27 14:35:16 2013 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Wed Feb 27 15:51:34 2013 +0100 @@ -22,6 +22,8 @@ */ package com.oracle.graal.compiler.test; +import static org.junit.Assert.*; + import java.util.concurrent.*; import org.junit.*; @@ -32,6 +34,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.util.*; +import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.schedule.*; @@ -46,7 +49,7 @@ public class MemoryScheduleTest extends GraphScheduleTest { private static enum TestMode { - WITH_FRAMESTATES, WITHOUT_FRAMESTATES + WITH_FRAMESTATES, WITHOUT_FRAMESTATES, INLINED_WITHOUT_FRAMESTATES } public static class Container { @@ -58,8 +61,10 @@ private static final Container container = new Container(); + /** + * In this test the read should be scheduled before the write. + */ public static int testSimpleSnippet() { - // in this test the read should be scheduled before the write try { return container.a; } finally { @@ -167,6 +172,23 @@ assertReadWithinStartBlock(schedule, false); } + /** + * Here the read should float to the end (into the same block as the return). + */ + public static int testArrayCopySnippet(Integer intValue, char[] a, char[] b, int len) { + System.arraycopy(a, 0, b, 0, len); + return intValue.intValue(); + } + + @Test + public void testArrayCopy() { + SchedulePhase schedule = getFinalSchedule("testArrayCopySnippet", TestMode.INLINED_WITHOUT_FRAMESTATES); + StructuredGraph graph = (StructuredGraph) schedule.getCFG().getStartBlock().getBeginNode().graph(); + ReturnNode ret = graph.getNodes(ReturnNode.class).first(); + assertTrue(ret.result() instanceof FloatingReadNode); + assertEquals(schedule.getCFG().blockFor(ret), schedule.getCFG().blockFor(ret.result())); + } + private void assertReadAfterWrite(SchedulePhase schedule, boolean readAfterWrite) { boolean writeEncountered = false; assertEquals(1, schedule.getCFG().getBlocks().length); @@ -195,7 +217,12 @@ @Override public SchedulePhase call() throws Exception { StructuredGraph graph = parse(snippet); - if (mode == TestMode.WITHOUT_FRAMESTATES) { + if (mode == TestMode.INLINED_WITHOUT_FRAMESTATES) { + Assumptions assumptions = new Assumptions(false); + new InliningPhase(runtime(), null, assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph); + } + new LoweringPhase(null, runtime(), new Assumptions(false)).apply(graph); + if (mode == TestMode.WITHOUT_FRAMESTATES || mode == TestMode.INLINED_WITHOUT_FRAMESTATES) { for (Node node : graph.getNodes()) { if (node instanceof StateSplit) { FrameState stateAfter = ((StateSplit) node).stateAfter(); @@ -206,9 +233,10 @@ } } } - new LoweringPhase(null, runtime(), new Assumptions(false)).apply(graph); new FloatingReadPhase().apply(graph); + new RemoveValueProxyPhase().apply(graph); + SchedulePhase schedule = new SchedulePhase(); schedule.apply(graph); return schedule; diff -r f7b40e9d490c -r 649379d3f88d graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueProxyNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueProxyNode.java Wed Feb 27 14:35:16 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueProxyNode.java Wed Feb 27 15:51:34 2013 +0100 @@ -34,14 +34,14 @@ * inside the loop (i.e. was not live on entry to the loop) and is (potentially) used after the * loop. */ -public class ValueProxyNode extends FloatingNode implements Node.IterableNodeType, ValueNumberable, Canonicalizable, Virtualizable { +public class ValueProxyNode extends FloatingNode implements Node.IterableNodeType, ValueNumberable, Canonicalizable, Virtualizable, LIRLowerable { @Input(notDataflow = true) private BeginNode proxyPoint; @Input private ValueNode value; private final PhiType type; public ValueProxyNode(ValueNode value, BeginNode exit, PhiType type) { - super(value.stamp()); + super(type == PhiType.Value ? value.stamp() : type.stamp); this.type = type; assert exit != null; this.proxyPoint = exit; @@ -78,8 +78,13 @@ } @Override + public void generate(LIRGeneratorTool generator) { + assert type == PhiType.Memory; + } + + @Override public ValueNode canonical(CanonicalizerTool tool) { - if (value.isConstant()) { + if (type == PhiType.Value && value.isConstant()) { return value; } return this; @@ -87,9 +92,11 @@ @Override public void virtualize(VirtualizerTool tool) { - State state = tool.getObjectState(value); - if (state != null && state.getState() == EscapeState.Virtual) { - tool.replaceWithVirtual(state.getVirtualObject()); + if (type == PhiType.Value) { + State state = tool.getObjectState(value); + if (state != null && state.getState() == EscapeState.Virtual) { + tool.replaceWithVirtual(state.getVirtualObject()); + } } } } diff -r f7b40e9d490c -r 649379d3f88d graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/RemoveValueProxyPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/RemoveValueProxyPhase.java Wed Feb 27 14:35:16 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/RemoveValueProxyPhase.java Wed Feb 27 15:51:34 2013 +0100 @@ -23,6 +23,7 @@ package com.oracle.graal.phases.common; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.PhiNode.*; import com.oracle.graal.phases.*; public class RemoveValueProxyPhase extends Phase { @@ -30,7 +31,9 @@ @Override protected void run(StructuredGraph graph) { for (ValueProxyNode vpn : graph.getNodes(ValueProxyNode.class)) { - graph.replaceFloating(vpn, vpn.value()); + if (vpn.type() == PhiType.Value) { + graph.replaceFloating(vpn, vpn.value()); + } } for (LoopExitNode exit : graph.getNodes(LoopExitNode.class)) { FrameState stateAfter = exit.stateAfter();