changeset 7896:649379d3f88d

don't kill memory proxies during RemoveValueProxyPhase
author Lukas Stadler <lukas.stadler@jku.at>
date Wed, 27 Feb 2013 15:51:34 +0100
parents f7b40e9d490c
children a58851061377
files graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueProxyNode.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/RemoveValueProxyPhase.java
diffstat 3 files changed, 49 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- 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;
--- 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());
+            }
         }
     }
 }
--- 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();