1 /*
2  * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 
25 package org.graalvm.compiler.phases;
26 
27 import java.util.EnumSet;
28 import java.util.Set;
29 
30 import org.graalvm.compiler.core.common.GraalOptions;
31 import org.graalvm.compiler.options.OptionValues;
32 
33 import jdk.vm.ci.meta.DeoptimizationReason;
34 import jdk.vm.ci.meta.ProfilingInfo;
35 
36 public final class OptimisticOptimizations {
37 
38     public static final OptimisticOptimizations ALL = new OptimisticOptimizations(EnumSet.allOf(Optimization.class));
39     public static final OptimisticOptimizations NONE = new OptimisticOptimizations(EnumSet.noneOf(Optimization.class));
40 
41     public enum Optimization {
42         RemoveNeverExecutedCode,
43         UseTypeCheckedInlining,
44         UseTypeCheckHints,
45         UseExceptionProbabilityForOperations,
46         UseExceptionProbability,
47         UseLoopLimitChecks
48     }
49 
50     private final Set<Optimization> enabledOpts;
51 
OptimisticOptimizations(ProfilingInfo info, OptionValues options)52     public OptimisticOptimizations(ProfilingInfo info, OptionValues options) {
53         this.enabledOpts = EnumSet.noneOf(Optimization.class);
54 
55         enabledOpts.add(Optimization.UseExceptionProbabilityForOperations);
56         addOptimization(options, info, DeoptimizationReason.UnreachedCode, Optimization.RemoveNeverExecutedCode);
57         addOptimization(options, info, DeoptimizationReason.TypeCheckedInliningViolated, Optimization.UseTypeCheckedInlining);
58         addOptimization(options, info, DeoptimizationReason.OptimizedTypeCheckViolated, Optimization.UseTypeCheckHints);
59         addOptimization(options, info, DeoptimizationReason.NotCompiledExceptionHandler, Optimization.UseExceptionProbability);
60         addOptimization(options, info, DeoptimizationReason.LoopLimitCheck, Optimization.UseLoopLimitChecks);
61     }
62 
addOptimization(OptionValues options, ProfilingInfo info, DeoptimizationReason deoptReason, Optimization optimization)63     private void addOptimization(OptionValues options, ProfilingInfo info, DeoptimizationReason deoptReason, Optimization optimization) {
64         if (checkDeoptimizations(options, info, deoptReason)) {
65             enabledOpts.add(optimization);
66         }
67     }
68 
remove(Optimization... optimizations)69     public OptimisticOptimizations remove(Optimization... optimizations) {
70         Set<Optimization> newOptimizations = EnumSet.copyOf(enabledOpts);
71         for (Optimization o : optimizations) {
72             newOptimizations.remove(o);
73         }
74         return new OptimisticOptimizations(newOptimizations);
75     }
76 
add(Optimization... optimizations)77     public OptimisticOptimizations add(Optimization... optimizations) {
78         Set<Optimization> newOptimizations = EnumSet.copyOf(enabledOpts);
79         for (Optimization o : optimizations) {
80             newOptimizations.add(o);
81         }
82         return new OptimisticOptimizations(newOptimizations);
83     }
84 
OptimisticOptimizations(Set<Optimization> enabledOpts)85     private OptimisticOptimizations(Set<Optimization> enabledOpts) {
86         this.enabledOpts = enabledOpts;
87     }
88 
removeNeverExecutedCode(OptionValues options)89     public boolean removeNeverExecutedCode(OptionValues options) {
90         return GraalOptions.RemoveNeverExecutedCode.getValue(options) && enabledOpts.contains(Optimization.RemoveNeverExecutedCode);
91     }
92 
useTypeCheckHints(OptionValues options)93     public boolean useTypeCheckHints(OptionValues options) {
94         return GraalOptions.UseTypeCheckHints.getValue(options) && enabledOpts.contains(Optimization.UseTypeCheckHints);
95     }
96 
inlineMonomorphicCalls(OptionValues options)97     public boolean inlineMonomorphicCalls(OptionValues options) {
98         return GraalOptions.InlineMonomorphicCalls.getValue(options) && enabledOpts.contains(Optimization.UseTypeCheckedInlining);
99     }
100 
inlinePolymorphicCalls(OptionValues options)101     public boolean inlinePolymorphicCalls(OptionValues options) {
102         return GraalOptions.InlinePolymorphicCalls.getValue(options) && enabledOpts.contains(Optimization.UseTypeCheckedInlining);
103     }
104 
inlineMegamorphicCalls(OptionValues options)105     public boolean inlineMegamorphicCalls(OptionValues options) {
106         return GraalOptions.InlineMegamorphicCalls.getValue(options) && enabledOpts.contains(Optimization.UseTypeCheckedInlining);
107     }
108 
devirtualizeInvokes(OptionValues options)109     public boolean devirtualizeInvokes(OptionValues options) {
110         return GraalOptions.OptDevirtualizeInvokesOptimistically.getValue(options) && enabledOpts.contains(Optimization.UseTypeCheckedInlining);
111     }
112 
useExceptionProbability(OptionValues options)113     public boolean useExceptionProbability(OptionValues options) {
114         return GraalOptions.UseExceptionProbability.getValue(options) && enabledOpts.contains(Optimization.UseExceptionProbability);
115     }
116 
useExceptionProbabilityForOperations()117     public boolean useExceptionProbabilityForOperations() {
118         return enabledOpts.contains(Optimization.UseExceptionProbabilityForOperations);
119     }
120 
useLoopLimitChecks(OptionValues options)121     public boolean useLoopLimitChecks(OptionValues options) {
122         return GraalOptions.UseLoopLimitChecks.getValue(options) && enabledOpts.contains(Optimization.UseLoopLimitChecks);
123     }
124 
lessOptimisticThan(OptimisticOptimizations other)125     public boolean lessOptimisticThan(OptimisticOptimizations other) {
126         for (Optimization opt : Optimization.values()) {
127             if (!enabledOpts.contains(opt) && other.enabledOpts.contains(opt)) {
128                 return true;
129             }
130         }
131         return false;
132     }
133 
checkDeoptimizations(OptionValues options, ProfilingInfo profilingInfo, DeoptimizationReason reason)134     private static boolean checkDeoptimizations(OptionValues options, ProfilingInfo profilingInfo, DeoptimizationReason reason) {
135         return profilingInfo.getDeoptimizationCount(reason) < GraalOptions.DeoptsToDisableOptimisticOptimization.getValue(options);
136     }
137 
138     @Override
toString()139     public String toString() {
140         return enabledOpts.toString();
141     }
142 }
143