# HG changeset patch # User Gilles Duboscq # Date 1397747765 -7200 # Node ID 4d19ee79fcee5ae34484fbea6f0c0da431020297 # Parent a40e775ecb83a2575206c0efe738293e1eef961a Fix loop peeling problem with VirtualState: duplicate states deeply and only clear the parts of the exit's state that's not used by the duplicated nodes. diff -r a40e775ecb83 -r 4d19ee79fcee graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java Thu Apr 17 15:43:50 2014 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java Thu Apr 17 17:16:05 2014 +0200 @@ -29,7 +29,6 @@ import com.oracle.graal.graph.Graph.DuplicationReplacement; import com.oracle.graal.graph.iterators.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.VirtualState.VirtualClosure; import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.virtual.*; @@ -168,7 +167,7 @@ if (n instanceof StateSplit) { FrameState stateAfter = ((StateSplit) n).stateAfter(); if (stateAfter != null) { - nodes.mark(stateAfter); + stateAfter.applyToVirtual(node -> nodes.mark(node)); } } nodes.mark(n); @@ -181,14 +180,7 @@ FrameState stateAfter = earlyExit.stateAfter(); if (stateAfter != null) { - nodes.mark(stateAfter); - stateAfter.applyToVirtual(new VirtualClosure() { - - @Override - public void apply(VirtualState node) { - nodes.mark(node); - } - }); + stateAfter.applyToVirtual(node -> nodes.mark(node)); } nodes.mark(earlyExit); for (ProxyNode proxy : earlyExit.proxies()) { @@ -342,19 +334,11 @@ * VirtualState nodes contained in the old exit's state may be shared by other * dominated VirtualStates. Those dominated virtual states need to see the * proxy->phi update that are applied below. - * + * * We now update the original fragment's nodes accordingly: */ - state.applyToVirtual(new VirtualClosure() { - public void apply(VirtualState node) { - original.nodes.clear(node); - } - }); - exitState.applyToVirtual(new VirtualClosure() { - public void apply(VirtualState node) { - original.nodes.mark(node); - } - }); + state.applyToVirtual(node -> original.nodes.clear(node)); + exitState.applyToVirtual(node -> original.nodes.mark(node)); } FrameState finalExitState = exitState; diff -r a40e775ecb83 -r 4d19ee79fcee graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java Thu Apr 17 15:43:50 2014 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java Thu Apr 17 17:16:05 2014 +0200 @@ -113,7 +113,11 @@ for (LoopExitNode exit : exits()) { FrameState exitState = exit.stateAfter(); if (exitState != null) { - exitState.applyToVirtual(v -> nodes.clear(v)); + exitState.applyToVirtual(v -> { + if (v.usages().filter(n -> nodes.isMarked(n) && !(n instanceof VirtualState && exitState.isPartOfThisState((VirtualState) n))).isEmpty()) { + nodes.clear(v); + } + }); } for (ProxyNode proxy : exit.proxies()) { nodes.clear(proxy);