changeset 5713:8c478272fb34

Cleanup and fixes in handling of VirtualStates around loop exits merging
author Gilles Duboscq <duboscq@ssw.jku.at>
date Wed, 27 Jun 2012 17:44:08 +0200
parents f96e7b39e9fe
children cc64f42d10d1
files graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragment.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragmentInside.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/VirtualState.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectState.java
diffstat 5 files changed, 73 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragment.java	Wed Jun 27 15:40:03 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragment.java	Wed Jun 27 17:44:08 2012 +0200
@@ -30,6 +30,7 @@
 import com.oracle.graal.lir.cfg.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.PhiNode.PhiType;
+import com.oracle.graal.nodes.VirtualState.*;
 
 
 public abstract class LoopFragment {
@@ -139,7 +140,7 @@
     }
 
     protected static NodeBitMap computeNodes(Graph graph, Collection<BeginNode> blocks, Collection<BeginNode> earlyExits) {
-        NodeBitMap nodes = graph.createNodeBitMap(true);
+        final NodeBitMap nodes = graph.createNodeBitMap(true);
         for (BeginNode b : blocks) {
             for (Node n : b.getBlockNodes()) {
                 if (n instanceof Invoke) {
@@ -158,6 +159,12 @@
             FrameState stateAfter = earlyExit.stateAfter();
             if (stateAfter != null) {
                 nodes.mark(stateAfter);
+                stateAfter.applyToVirtual(new VirtualClosure() {
+                    @Override
+                    public void apply(VirtualState node) {
+                        nodes.mark(node);
+                    }
+                });
             }
             nodes.mark(earlyExit);
             for (ValueProxyNode proxy : earlyExit.proxies()) {
@@ -229,9 +236,10 @@
             merge.setNext(next);
 
             FrameState exitState = earlyExit.stateAfter();
+            FrameState newExitState = newEarlyExit.stateAfter();
             FrameState state = null;
             if (exitState != null) {
-                state = exitState.duplicate();
+                state = exitState.duplicateWithVirtualState();
                 merge.setStateAfter(state);
             }
 
@@ -239,8 +247,8 @@
                 anchored.replaceFirstInput(earlyExit, merge);
             }
 
-            for (ValueProxyNode vpn : earlyExit.proxies().snapshot()) {
-                ValueNode replaceWith;
+            for (final ValueProxyNode vpn : earlyExit.proxies().snapshot()) {
+                final ValueNode replaceWith;
                 ValueProxyNode newVpn = getDuplicatedNode(vpn);
                 if (newVpn != null) {
                     PhiNode phi = graph.add(vpn.type() == PhiType.Value ? new PhiNode(vpn.kind(), merge) : new PhiNode(vpn.type(), merge));
@@ -251,10 +259,23 @@
                     replaceWith = vpn.value();
                 }
                 if (state != null) {
-                    state.replaceFirstInput(vpn, replaceWith);
+                    state.applyToNonVirtual(new NodeClosure<ValueNode>() {
+                        @Override
+                        public void apply(Node from, ValueNode node) {
+                            if (node == vpn) {
+                                from.replaceFirstInput(vpn, replaceWith);
+                            }
+                        }
+                    });
                 }
                 for (Node usage : vpn.usages().snapshot()) {
-                    if (usage != exitState && !merge.isPhiAtMerge(usage)) {
+                    if (!merge.isPhiAtMerge(usage)) {
+                        if (usage instanceof VirtualState) {
+                            VirtualState stateUsage = (VirtualState) usage;
+                            if (exitState.isPartOfThisState(stateUsage) || newExitState.isPartOfThisState(stateUsage)) {
+                                continue;
+                            }
+                        }
                         usage.replaceFirstInput(vpn, replaceWith);
                     }
                 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragmentInside.java	Wed Jun 27 15:40:03 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragmentInside.java	Wed Jun 27 17:44:08 2012 +0200
@@ -229,7 +229,7 @@
             FrameState state = loopBegin.stateAfter();
             FrameState duplicateState = null;
             if (state != null) {
-                duplicateState = state.duplicate();
+                duplicateState = state.duplicateWithVirtualState();
                 newExitMerge.setStateAfter(duplicateState);
             }
             for (EndNode end : endsToMerge) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java	Wed Jun 27 15:40:03 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java	Wed Jun 27 17:44:08 2012 +0200
@@ -401,4 +401,31 @@
             outerFrameState().applyToNonVirtual(closure);
         }
     }
+
+    @Override
+    public void applyToVirtual(VirtualClosure closure) {
+        closure.apply(this);
+        for (VirtualObjectState state : virtualObjectMappings) {
+            state.applyToVirtual(closure);
+        }
+        if (outerFrameState() != null) {
+            outerFrameState().applyToVirtual(closure);
+        }
+    }
+
+    @Override
+    public boolean isPartOfThisState(VirtualState state) {
+        if (state == this) {
+            return true;
+        }
+        if (outerFrameState() != null && outerFrameState().isPartOfThisState(state)) {
+            return true;
+        }
+        for (VirtualObjectState objectState : virtualObjectMappings) {
+            if (objectState.isPartOfThisState(state)) {
+                return true;
+            }
+        }
+        return false;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/VirtualState.java	Wed Jun 27 15:40:03 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/VirtualState.java	Wed Jun 27 17:44:08 2012 +0200
@@ -34,8 +34,16 @@
         void apply(Node usage, T node);
     }
 
+    public interface VirtualClosure {
+        void apply(VirtualState node);
+    }
+
     public abstract VirtualState duplicateWithVirtualState();
 
     public abstract void applyToNonVirtual(NodeClosure<? super ValueNode> closure);
 
+    public abstract void applyToVirtual(VirtualClosure closure);
+
+    public abstract boolean isPartOfThisState(VirtualState state);
+
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectState.java	Wed Jun 27 15:40:03 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectState.java	Wed Jun 27 17:44:08 2012 +0200
@@ -72,4 +72,14 @@
             closure.apply(this, value);
         }
     }
+
+    @Override
+    public boolean isPartOfThisState(VirtualState state) {
+        return this == state;
+    }
+
+    @Override
+    public void applyToVirtual(VirtualClosure closure) {
+        closure.apply(this);
+    }
 }