# HG changeset patch # User Gilles Duboscq # Date 1340811848 -7200 # Node ID 8c478272fb34c30d1eefd36213a69f9209821a04 # Parent f96e7b39e9fe0b0a074f6bdf6969cfdca5cc6731 Cleanup and fixes in handling of VirtualStates around loop exits merging diff -r f96e7b39e9fe -r 8c478272fb34 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragment.java --- 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 blocks, Collection 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() { + @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); } } diff -r f96e7b39e9fe -r 8c478272fb34 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragmentInside.java --- 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) { diff -r f96e7b39e9fe -r 8c478272fb34 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java --- 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; + } } diff -r f96e7b39e9fe -r 8c478272fb34 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/VirtualState.java --- 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 closure); + public abstract void applyToVirtual(VirtualClosure closure); + + public abstract boolean isPartOfThisState(VirtualState state); + } diff -r f96e7b39e9fe -r 8c478272fb34 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectState.java --- 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); + } }