changeset 16038:23c4dd4f72a3

avoid duplication of frame states during unrolling
author Lukas Stadler <lukas.stadler@oracle.com>
date Thu, 05 Jun 2014 13:19:59 +0200
parents 3ad5e034ac1d
children 4c284376c374
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/OnStackReplacementPhase.java graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInsideBefore.java graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInsideFrom.java graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentWhole.java graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformHighPhase.java
diffstat 8 files changed, 44 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- 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());
--- 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;
--- 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);
 
--- 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);
     }
 
--- 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);
     }
 
--- 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
 
     }
--- 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);
         }
     }
 
--- 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);
                     }
                 }