changeset 15141:6f132c0219e9

Remove dead phi loops during loop peeling
author Gilles Duboscq <duboscq@ssw.jku.at>
date Mon, 14 Apr 2014 15:07:28 +0200
parents 393935e524e9
children c92546febda6
files graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java
diffstat 2 files changed, 24 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java	Mon Apr 14 11:46:36 2014 +0200
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java	Mon Apr 14 15:07:28 2014 +0200
@@ -63,6 +63,7 @@
             Mark mark = graph.getMark();
             peel(loop);
             canonicalizer.applyIncremental(graph, context, mark);
+            loopBegin.removeDeadPhis();
             loop.invalidateFragments();
             if (iterations++ > UNROLL_LIMIT || graph.getNodeCount() > MaximumDesiredSize.getValue() * 3) {
                 throw new BailoutException("FullUnroll : Graph seems to grow out of proportion");
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java	Mon Apr 14 11:46:36 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java	Mon Apr 14 15:07:28 2014 +0200
@@ -201,4 +201,27 @@
         updateUsagesInterface(this.overflowGuard, overflowGuard);
         this.overflowGuard = overflowGuard;
     }
+
+    /**
+     * Removes dead {@linkplain PhiNode phi nodes} hanging from this node.
+     *
+     * This method uses the heuristic that any node which not a phi node of this LoopBeginNode is
+     * alive. This allows the removal of dead phi loops.
+     */
+    public void removeDeadPhis() {
+        Set<PhiNode> alive = new HashSet<>();
+        for (PhiNode phi : phis()) {
+            NodePredicate isAlive = u -> !isPhiAtMerge(u) || alive.contains(u);
+            if (phi.usages().filter(isAlive).isNotEmpty()) {
+                alive.add(phi);
+                for (PhiNode keptAlive : phi.values().filter(PhiNode.class).filter(isAlive.negate())) {
+                    alive.add(keptAlive);
+                }
+            }
+        }
+        for (PhiNode phi : phis().filter(((NodePredicate) alive::contains).negate()).snapshot()) {
+            phi.replaceAtUsages(null);
+            phi.safeDelete();
+        }
+    }
 }