# HG changeset patch # User Gilles Duboscq # Date 1367350728 -7200 # Node ID ca34e36c53e84ba209ee7072423c03d9d99149c8 # Parent 3d309a26d4d5c723b9d568db1a8ae42325b0b80c Add loop safepoint elimination diff -r 3d309a26d4d5 -r ca34e36c53e8 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- 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(); diff -r 3d309a26d4d5 -r ca34e36c53e8 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java --- 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; diff -r 3d309a26d4d5 -r ca34e36c53e8 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java --- 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(); + } } diff -r 3d309a26d4d5 -r ca34e36c53e8 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopSafepointEliminationPhase.java --- /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 { + + @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(); + } + } + } + } +} diff -r 3d309a26d4d5 -r ca34e36c53e8 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java --- 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 = ____; diff -r 3d309a26d4d5 -r ca34e36c53e8 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/OptimisticOptimizations.java --- 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 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)) { diff -r 3d309a26d4d5 -r ca34e36c53e8 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/LowTierContext.java --- 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; + } }