# HG changeset patch # User Lukas Stadler # Date 1401967199 -7200 # Node ID 23c4dd4f72a3e119e7a6589f75f10ff54e7aa2df # Parent 3ad5e034ac1d53ee9dbb9ff7c2271714aba62e0a avoid duplication of frame states during unrolling diff -r 3ad5e034ac1d -r 23c4dd4f72a3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/OnStackReplacementPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/OnStackReplacementPhase.java Thu Jun 05 13:19:59 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/OnStackReplacementPhase.java Thu Jun 05 13:19:59 2014 +0200 @@ -73,7 +73,7 @@ break; } - LoopTransformations.peel(osrLoop); + LoopTransformations.peel(osrLoop, true); for (Node usage : osr.usages().snapshot()) { ProxyNode proxy = (ProxyNode) usage; proxy.replaceAndDelete(proxy.value()); diff -r 3ad5e034ac1d -r 23c4dd4f72a3 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 Jun 05 13:19:59 2014 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java Thu Jun 05 13:19:59 2014 +0200 @@ -57,9 +57,9 @@ return loop; } - public abstract LoopFragment duplicate(); + public abstract LoopFragment duplicate(boolean createExitFrameStates); - public abstract void insertBefore(LoopEx l); + public abstract void insertBefore(LoopEx l, boolean createExitFrameStates); public void disconnect() { // TODO (gd) possibly abstract @@ -299,7 +299,7 @@ * Merges the early exits (i.e. loop exits) that were duplicated as part of this fragment, with * the original fragment's exits. */ - protected void mergeEarlyExits() { + protected void mergeEarlyExits(boolean createExitFrameStates) { assert isDuplicate(); StructuredGraph graph = graph(); for (BeginNode earlyExit : LoopFragment.toHirBlocks(original().loop().lirLoop().getExits())) { @@ -325,19 +325,24 @@ FrameState state = null; if (exitState != null) { state = exitState; - exitState = exitState.duplicateWithVirtualState(); - loopEarlyExit.setStateAfter(exitState); merge.setStateAfter(state); - /* - * Using the old exit's state as the merge's state is necessary because some of the - * 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(node -> original.nodes.clearAndGrow(node)); - exitState.applyToVirtual(node -> original.nodes.markAndGrow(node)); + + if (createExitFrameStates) { + exitState = exitState.duplicateWithVirtualState(); + loopEarlyExit.setStateAfter(exitState); + /* + * Using the old exit's state as the merge's state is necessary because some of + * the 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(node -> original.nodes.clearAndGrow(node)); + exitState.applyToVirtual(node -> original.nodes.markAndGrow(node)); + } else { + loopEarlyExit.setStateAfter(null); + } } FrameState finalExitState = exitState; @@ -373,7 +378,7 @@ if (merge.isPhiAtMerge(usage)) { return false; } - if (usage instanceof VirtualState) { + if (finalExitState != null && usage instanceof VirtualState) { VirtualState stateUsage = (VirtualState) usage; if (finalExitState.isPartOfThisState(stateUsage)) { return false; diff -r 3ad5e034ac1d -r 23c4dd4f72a3 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 Jun 05 13:19:59 2014 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java Thu Jun 05 13:19:59 2014 +0200 @@ -63,7 +63,7 @@ } @Override - public LoopFragmentInside duplicate() { + public LoopFragmentInside duplicate(boolean createExitFrameStates) { assert !isDuplicate(); return new LoopFragmentInside(this); } @@ -85,14 +85,14 @@ } @Override - public void insertBefore(LoopEx loop) { + public void insertBefore(LoopEx loop, boolean createExitFrameStates) { assert this.isDuplicate() && this.original().loop() == loop; patchNodes(dataFixBefore); BeginNode end = mergeEnds(); - mergeEarlyExits(); + mergeEarlyExits(createExitFrameStates); original().patchPeeling(this); diff -r 3ad5e034ac1d -r 23c4dd4f72a3 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInsideBefore.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInsideBefore.java Thu Jun 05 13:19:59 2014 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInsideBefore.java Thu Jun 05 13:19:59 2014 +0200 @@ -45,7 +45,7 @@ } @Override - public LoopFragmentInsideBefore duplicate() { + public LoopFragmentInsideBefore duplicate(boolean createExitFrameStates) { return new LoopFragmentInsideBefore(this); } diff -r 3ad5e034ac1d -r 23c4dd4f72a3 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInsideFrom.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInsideFrom.java Thu Jun 05 13:19:59 2014 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInsideFrom.java Thu Jun 05 13:19:59 2014 +0200 @@ -45,7 +45,7 @@ } @Override - public LoopFragmentInsideFrom duplicate() { + public LoopFragmentInsideFrom duplicate(boolean createExitFrameStates) { return new LoopFragmentInsideFrom(this); } diff -r 3ad5e034ac1d -r 23c4dd4f72a3 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentWhole.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentWhole.java Thu Jun 05 13:19:59 2014 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentWhole.java Thu Jun 05 13:19:59 2014 +0200 @@ -39,18 +39,18 @@ } @Override - public LoopFragmentWhole duplicate() { + public LoopFragmentWhole duplicate(boolean createExitFrameStates) { LoopFragmentWhole loopFragmentWhole = new LoopFragmentWhole(this); - loopFragmentWhole.reify(); + loopFragmentWhole.reify(createExitFrameStates); return loopFragmentWhole; } - private void reify() { + private void reify(boolean createExitFrameStates) { assert this.isDuplicate(); patchNodes(null); - mergeEarlyExits(); + mergeEarlyExits(createExitFrameStates); } @Override @@ -102,7 +102,7 @@ } @Override - public void insertBefore(LoopEx loop) { + public void insertBefore(LoopEx loop, boolean createExitFrameStates) { // TODO Auto-generated method stub } diff -r 3ad5e034ac1d -r 23c4dd4f72a3 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java Thu Jun 05 13:19:59 2014 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java Thu Jun 05 13:19:59 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,14 +44,14 @@ public static void invert(LoopEx loop, FixedNode point) { LoopFragmentInsideBefore head = loop.insideBefore(point); - LoopFragmentInsideBefore duplicate = head.duplicate(); + LoopFragmentInsideBefore duplicate = head.duplicate(true); head.disconnect(); - head.insertBefore(loop); + head.insertBefore(loop, true); duplicate.appendInside(loop); } - public static void peel(LoopEx loop) { - loop.inside().duplicate().insertBefore(loop); + public static void peel(LoopEx loop, boolean createExitFrameStates) { + loop.inside().duplicate(createExitFrameStates).insertBefore(loop, createExitFrameStates); } public static void fullUnroll(LoopEx loop, PhaseContext context, CanonicalizerPhase canonicalizer) { @@ -61,7 +61,7 @@ StructuredGraph graph = loopBegin.graph(); while (!loopBegin.isDeleted()) { Mark mark = graph.getMark(); - peel(loop); + peel(loop, false); canonicalizer.applyIncremental(graph, context, mark); loopBegin.removeDeadPhis(); loop.invalidateFragments(); @@ -88,7 +88,7 @@ while (successors.hasNext()) { Position position = successors.nextPosition(); // create a new loop duplicate, connect it and simplify it - LoopFragmentWhole duplicateLoop = originalLoop.duplicate(); + LoopFragmentWhole duplicateLoop = originalLoop.duplicate(true); controlSplitClass.set(newControlSplit, position, BeginNode.begin(duplicateLoop.entryPoint())); ControlSplitNode duplicatedControlSplit = duplicateLoop.getDuplicatedNode(controlSplitNode); graph.removeSplitPropagate(duplicatedControlSplit, (BeginNode) controlSplitClass.get(duplicatedControlSplit, position)); @@ -105,8 +105,8 @@ } // TODO (gd) implement counted loop LoopFragmentWhole main = loop.whole(); - LoopFragmentWhole prologue = main.duplicate(); - prologue.insertBefore(loop); + LoopFragmentWhole prologue = main.duplicate(true); + prologue.insertBefore(loop, false); // CountedLoopBeginNode counted = prologue.countedLoop(); // StructuredGraph graph = (StructuredGraph) counted.graph(); // ValueNode tripCountPrologue = counted.tripCount(); @@ -115,7 +115,7 @@ // graph.replaceFloating(tripCountMain, "tripCountMain - (tripCountPrologue % factor)"); LoopFragmentInside inside = loop.inside(); for (int i = 0; i < factor; i++) { - inside.duplicate().appendInside(loop); + inside.duplicate(false).appendInside(loop); } } diff -r 3ad5e034ac1d -r 23c4dd4f72a3 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformHighPhase.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformHighPhase.java Thu Jun 05 13:19:59 2014 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformHighPhase.java Thu Jun 05 13:19:59 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ for (LoopEx loop : data.outterFirst()) { if (LoopPolicies.shouldPeel(loop, probabilities)) { Debug.log("Peeling %s", loop); - LoopTransformations.peel(loop); + LoopTransformations.peel(loop, true); Debug.dump(graph, "After peeling %s", loop); } }