001/* 002 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package com.oracle.graal.phases; 024 025import java.util.*; 026 027import com.oracle.graal.debug.*; 028import jdk.internal.jvmci.meta.*; 029 030import com.oracle.graal.compiler.common.*; 031 032public final class OptimisticOptimizations { 033 034 public static final OptimisticOptimizations ALL = new OptimisticOptimizations(EnumSet.allOf(Optimization.class)); 035 public static final OptimisticOptimizations NONE = new OptimisticOptimizations(EnumSet.noneOf(Optimization.class)); 036 private static final DebugMetric disabledOptimisticOptsMetric = Debug.metric("DisabledOptimisticOpts"); 037 038 public static enum Optimization { 039 RemoveNeverExecutedCode, 040 UseTypeCheckedInlining, 041 UseTypeCheckHints, 042 UseExceptionProbabilityForOperations, 043 UseExceptionProbability, 044 UseLoopLimitChecks 045 } 046 047 private final Set<Optimization> enabledOpts; 048 049 public OptimisticOptimizations(ProfilingInfo info) { 050 this.enabledOpts = EnumSet.noneOf(Optimization.class); 051 052 enabledOpts.add(Optimization.UseExceptionProbabilityForOperations); 053 addOptimization(info, DeoptimizationReason.UnreachedCode, Optimization.RemoveNeverExecutedCode); 054 addOptimization(info, DeoptimizationReason.TypeCheckedInliningViolated, Optimization.UseTypeCheckedInlining); 055 addOptimization(info, DeoptimizationReason.OptimizedTypeCheckViolated, Optimization.UseTypeCheckHints); 056 addOptimization(info, DeoptimizationReason.NotCompiledExceptionHandler, Optimization.UseExceptionProbability); 057 addOptimization(info, DeoptimizationReason.LoopLimitCheck, Optimization.UseLoopLimitChecks); 058 } 059 060 private void addOptimization(ProfilingInfo info, DeoptimizationReason deoptReason, Optimization optimization) { 061 if (checkDeoptimizations(info, deoptReason)) { 062 enabledOpts.add(optimization); 063 } else { 064 disabledOptimisticOptsMetric.increment(); 065 } 066 } 067 068 public OptimisticOptimizations remove(Optimization... optimizations) { 069 Set<Optimization> newOptimizations = EnumSet.copyOf(enabledOpts); 070 for (Optimization o : optimizations) { 071 newOptimizations.remove(o); 072 } 073 return new OptimisticOptimizations(newOptimizations); 074 } 075 076 public OptimisticOptimizations add(Optimization... optimizations) { 077 Set<Optimization> newOptimizations = EnumSet.copyOf(enabledOpts); 078 for (Optimization o : optimizations) { 079 newOptimizations.add(o); 080 } 081 return new OptimisticOptimizations(newOptimizations); 082 } 083 084 private OptimisticOptimizations(Set<Optimization> enabledOpts) { 085 this.enabledOpts = enabledOpts; 086 } 087 088 public boolean removeNeverExecutedCode() { 089 return GraalOptions.RemoveNeverExecutedCode.getValue() && enabledOpts.contains(Optimization.RemoveNeverExecutedCode); 090 } 091 092 public boolean useTypeCheckHints() { 093 return GraalOptions.UseTypeCheckHints.getValue() && enabledOpts.contains(Optimization.UseTypeCheckHints); 094 } 095 096 public boolean inlineMonomorphicCalls() { 097 return GraalOptions.InlineMonomorphicCalls.getValue() && enabledOpts.contains(Optimization.UseTypeCheckedInlining); 098 } 099 100 public boolean inlinePolymorphicCalls() { 101 return GraalOptions.InlinePolymorphicCalls.getValue() && enabledOpts.contains(Optimization.UseTypeCheckedInlining); 102 } 103 104 public boolean inlineMegamorphicCalls() { 105 return GraalOptions.InlineMegamorphicCalls.getValue() && enabledOpts.contains(Optimization.UseTypeCheckedInlining); 106 } 107 108 public boolean devirtualizeInvokes() { 109 return GraalOptions.OptDevirtualizeInvokesOptimistically.getValue() && enabledOpts.contains(Optimization.UseTypeCheckedInlining); 110 } 111 112 public boolean useExceptionProbability() { 113 return GraalOptions.UseExceptionProbability.getValue() && enabledOpts.contains(Optimization.UseExceptionProbability); 114 } 115 116 public boolean useExceptionProbabilityForOperations() { 117 return GraalOptions.UseExceptionProbabilityForOperations.getValue() && enabledOpts.contains(Optimization.UseExceptionProbabilityForOperations); 118 } 119 120 public boolean useLoopLimitChecks() { 121 return GraalOptions.UseLoopLimitChecks.getValue() && enabledOpts.contains(Optimization.UseLoopLimitChecks); 122 } 123 124 public boolean lessOptimisticThan(OptimisticOptimizations other) { 125 for (Optimization opt : Optimization.values()) { 126 if (!enabledOpts.contains(opt) && other.enabledOpts.contains(opt)) { 127 return true; 128 } 129 } 130 return false; 131 } 132 133 private static boolean checkDeoptimizations(ProfilingInfo profilingInfo, DeoptimizationReason reason) { 134 return profilingInfo.getDeoptimizationCount(reason) < GraalOptions.DeoptsToDisableOptimisticOptimization.getValue(); 135 } 136 137 @Override 138 public String toString() { 139 return enabledOpts.toString(); 140 } 141}