changeset 9450:ca34e36c53e8

Add loop safepoint elimination
author Gilles Duboscq <duboscq@ssw.jku.at>
date Tue, 30 Apr 2013 21:38:48 +0200
parents 3d309a26d4d5
children 56c12e0c15c1 861a9e0aba38
files graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopSafepointEliminationPhase.java graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java graal/com.oracle.graal.phases/src/com/oracle/graal/phases/OptimisticOptimizations.java graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/LowTierContext.java
diffstat 7 files changed, 94 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Tue Apr 30 21:38:22 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Tue Apr 30 21:38:48 2013 +0200
@@ -146,7 +146,7 @@
 
         plan.runPhases(PhasePosition.LOW_LEVEL, graph);
 
-        LowTierContext lowTierContext = new LowTierContext(runtime, assumptions, replacements, target);
+        LowTierContext lowTierContext = new LowTierContext(runtime, assumptions, replacements, target, optimisticOpts);
         Suites.DEFAULT.getLowTier().apply(graph, lowTierContext);
 
         final SchedulePhase schedule = new SchedulePhase();
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Tue Apr 30 21:38:22 2013 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Tue Apr 30 21:38:48 2013 +0200
@@ -759,8 +759,11 @@
     }
 
     public boolean edgesEqual(Node node, Node other) {
+        return inputsEqual(node, other) && successorsEqual(node, other);
+    }
+
+    public boolean inputsEqual(Node node, Node other) {
         assert node.getClass() == clazz && other.getClass() == clazz;
-
         int index = 0;
         while (index < directInputCount) {
             if (getNode(other, inputOffsets[index]) != getNode(node, inputOffsets[index])) {
@@ -775,8 +778,12 @@
             }
             index++;
         }
+        return true;
+    }
 
-        index = 0;
+    public boolean successorsEqual(Node node, Node other) {
+        assert node.getClass() == clazz && other.getClass() == clazz;
+        int index = 0;
         while (index < directSuccessorCount) {
             if (getNode(other, successorOffsets[index]) != getNode(node, successorOffsets[index])) {
                 return false;
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java	Tue Apr 30 21:38:22 2013 +0200
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java	Tue Apr 30 21:38:48 2013 +0200
@@ -150,4 +150,8 @@
         }
         return overflowGuard;
     }
+
+    public Kind getKind() {
+        return iv.valueNode().kind();
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopSafepointEliminationPhase.java	Tue Apr 30 21:38:48 2013 +0200
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2011, 2013, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.loop.phases;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.loop.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.cfg.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.tiers.*;
+
+public class LoopSafepointEliminationPhase extends BasePhase<LowTierContext> {
+
+    @Override
+    protected void run(StructuredGraph graph, LowTierContext context) {
+        LoopsData loops = new LoopsData(graph);
+        if (context.getOptimisticOptimizations().useLoopLimitChecks()) {
+            loops.detectedCountedLoops();
+            for (LoopEx loop : loops.countedLoops()) {
+                if (loop.lirLoop().children.isEmpty() && loop.counted().getKind() == Kind.Int) {
+                    loop.loopBegin().dependencies().add(loop.counted().getOverFlowGuard());
+                    for (LoopEndNode loopEnd : loop.loopBegin().loopEnds()) {
+                        loopEnd.disableSafepoint();
+                    }
+                }
+            }
+        }
+        for (LoopEx loop : loops.countedLoops()) {
+            for (LoopEndNode loopEnd : loop.loopBegin().loopEnds()) {
+                Block b = loops.controlFlowGraph().blockFor(loopEnd);
+                blocks: while (b != loop.lirLoop().header) {
+                    assert b != null;
+                    for (FixedNode node : b.getNodes()) {
+                        if (node instanceof Invoke || node instanceof RuntimeCallNode) {
+                            loopEnd.disableSafepoint();
+                            break blocks;
+                        }
+                    }
+                    b = b.getDominator();
+                }
+            }
+        }
+    }
+}
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Tue Apr 30 21:38:22 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Tue Apr 30 21:38:48 2013 +0200
@@ -107,6 +107,7 @@
     public static int     LoopMaxUnswitch                    = 3;
     public static int     LoopUnswitchMaxIncrease            = 50;
     public static int     LoopUnswitchUncertaintyBoost       = 5;
+    public static boolean UseLoopLimitChecks                 = true;
 
     // debugging settings
     public static boolean ZapStackOnMethodEntry              = ____;
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/OptimisticOptimizations.java	Tue Apr 30 21:38:22 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/OptimisticOptimizations.java	Tue Apr 30 21:38:48 2013 +0200
@@ -34,7 +34,7 @@
     private static final DebugMetric disabledOptimisticOptsMetric = Debug.metric("DisabledOptimisticOpts");
 
     public static enum Optimization {
-        RemoveNeverExecutedCode, UseTypeCheckedInlining, UseTypeCheckHints, UseExceptionProbabilityForOperations, UseExceptionProbability
+        RemoveNeverExecutedCode, UseTypeCheckedInlining, UseTypeCheckHints, UseExceptionProbabilityForOperations, UseExceptionProbability, UseLoopLimitChecks
     }
 
     private final Set<Optimization> enabledOpts;
@@ -47,6 +47,7 @@
         addOptimization(method, DeoptimizationReason.TypeCheckedInliningViolated, Optimization.UseTypeCheckedInlining);
         addOptimization(method, DeoptimizationReason.OptimizedTypeCheckViolated, Optimization.UseTypeCheckHints);
         addOptimization(method, DeoptimizationReason.NotCompiledExceptionHandler, Optimization.UseExceptionProbability);
+        addOptimization(method, DeoptimizationReason.LoopLimitCheck, Optimization.UseLoopLimitChecks);
     }
 
     private void addOptimization(ResolvedJavaMethod method, DeoptimizationReason deoptReason, Optimization optimization) {
@@ -109,6 +110,10 @@
         return GraalOptions.UseExceptionProbabilityForOperations && enabledOpts.contains(Optimization.UseExceptionProbabilityForOperations);
     }
 
+    public boolean useLoopLimitChecks() {
+        return GraalOptions.UseLoopLimitChecks && enabledOpts.contains(Optimization.UseLoopLimitChecks);
+    }
+
     public boolean lessOptimisticThan(OptimisticOptimizations other) {
         for (Optimization opt : Optimization.values()) {
             if (!enabledOpts.contains(opt) && other.enabledOpts.contains(opt)) {
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/LowTierContext.java	Tue Apr 30 21:38:22 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/LowTierContext.java	Tue Apr 30 21:38:48 2013 +0200
@@ -25,17 +25,24 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.*;
 
 public class LowTierContext extends PhaseContext {
 
     private final TargetDescription target;
+    private final OptimisticOptimizations optimisticOpts;
 
-    public LowTierContext(MetaAccessProvider runtime, Assumptions assumptions, Replacements replacements, TargetDescription target) {
+    public LowTierContext(MetaAccessProvider runtime, Assumptions assumptions, Replacements replacements, TargetDescription target, OptimisticOptimizations optimisticOpts) {
         super(runtime, assumptions, replacements);
         this.target = target;
+        this.optimisticOpts = optimisticOpts;
     }
 
     public TargetDescription getTarget() {
         return target;
     }
+
+    public OptimisticOptimizations getOptimisticOptimizations() {
+        return optimisticOpts;
+    }
 }