1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2  * vim: set ts=8 sts=2 et sw=2 tw=80:
3  * This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef jit_IonOptimizationLevels_h
8 #define jit_IonOptimizationLevels_h
9 
10 #include "mozilla/EnumeratedArray.h"
11 
12 #include "jstypes.h"
13 
14 #include "jit/JitOptions.h"
15 #include "js/TypeDecls.h"
16 
17 namespace js {
18 namespace jit {
19 
20 enum class OptimizationLevel : uint8_t { Normal, Wasm, Count, DontCompile };
21 
22 #ifdef JS_JITSPEW
OptimizationLevelString(OptimizationLevel level)23 inline const char* OptimizationLevelString(OptimizationLevel level) {
24   switch (level) {
25     case OptimizationLevel::DontCompile:
26       return "Optimization_DontCompile";
27     case OptimizationLevel::Normal:
28       return "Optimization_Normal";
29     case OptimizationLevel::Wasm:
30       return "Optimization_Wasm";
31     case OptimizationLevel::Count:;
32   }
33   MOZ_CRASH("Invalid OptimizationLevel");
34 }
35 #endif
36 
37 // Class representing the Ion optimization settings for an OptimizationLevel.
38 class OptimizationInfo {
39   OptimizationLevel level_;
40 
41   // Toggles whether Effective Address Analysis is performed.
42   bool eaa_;
43 
44   // Toggles whether Alignment Mask Analysis is performed.
45   bool ama_;
46 
47   // Toggles whether Edge Case Analysis is used.
48   bool edgeCaseAnalysis_;
49 
50   // Toggles whether redundant checks get removed.
51   bool eliminateRedundantChecks_;
52 
53   // Toggles whether interpreted scripts get inlined.
54   bool inlineInterpreted_;
55 
56   // Toggles whether native scripts get inlined.
57   bool inlineNative_;
58 
59   // Toggles whether global value numbering is used.
60   bool gvn_;
61 
62   // Toggles whether loop invariant code motion is performed.
63   bool licm_;
64 
65   // Toggles whether Range Analysis is used.
66   bool rangeAnalysis_;
67 
68   // Toggles whether instruction reordering is performed.
69   bool reordering_;
70 
71   // Toggles whether Truncation based on Range Analysis is used.
72   bool autoTruncate_;
73 
74   // Toggles whether sink is used.
75   bool sink_;
76 
77   // Toggles whether scalar replacement is used.
78   bool scalarReplacement_;
79 
80   // Describes which register allocator to use.
81   IonRegisterAllocator registerAllocator_;
82 
baseCompilerWarmUpThreshold()83   uint32_t baseCompilerWarmUpThreshold() const {
84     MOZ_ASSERT(level_ == OptimizationLevel::Normal);
85     return JitOptions.normalIonWarmUpThreshold;
86   }
87 
88  public:
OptimizationInfo()89   constexpr OptimizationInfo()
90       : level_(OptimizationLevel::Normal),
91         eaa_(false),
92         ama_(false),
93         edgeCaseAnalysis_(false),
94         eliminateRedundantChecks_(false),
95         inlineInterpreted_(false),
96         inlineNative_(false),
97         gvn_(false),
98         licm_(false),
99         rangeAnalysis_(false),
100         reordering_(false),
101         autoTruncate_(false),
102         sink_(false),
103         scalarReplacement_(false),
104         registerAllocator_(RegisterAllocator_Backtracking) {}
105 
106   void initNormalOptimizationInfo();
107   void initWasmOptimizationInfo();
108 
level()109   OptimizationLevel level() const { return level_; }
110 
inlineInterpreted()111   bool inlineInterpreted() const {
112     return inlineInterpreted_ && !JitOptions.disableInlining;
113   }
114 
inlineNative()115   bool inlineNative() const {
116     return inlineNative_ && !JitOptions.disableInlining;
117   }
118 
119   uint32_t compilerWarmUpThreshold(JSScript* script,
120                                    jsbytecode* pc = nullptr) const;
121 
122   uint32_t recompileWarmUpThreshold(JSScript* script, jsbytecode* pc) const;
123 
gvnEnabled()124   bool gvnEnabled() const { return gvn_ && !JitOptions.disableGvn; }
125 
licmEnabled()126   bool licmEnabled() const { return licm_ && !JitOptions.disableLicm; }
127 
rangeAnalysisEnabled()128   bool rangeAnalysisEnabled() const {
129     return rangeAnalysis_ && !JitOptions.disableRangeAnalysis;
130   }
131 
instructionReorderingEnabled()132   bool instructionReorderingEnabled() const {
133     return reordering_ && !JitOptions.disableInstructionReordering;
134   }
135 
autoTruncateEnabled()136   bool autoTruncateEnabled() const {
137     return autoTruncate_ && rangeAnalysisEnabled();
138   }
139 
sinkEnabled()140   bool sinkEnabled() const { return sink_ && !JitOptions.disableSink; }
141 
eaaEnabled()142   bool eaaEnabled() const { return eaa_ && !JitOptions.disableEaa; }
143 
amaEnabled()144   bool amaEnabled() const { return ama_ && !JitOptions.disableAma; }
145 
edgeCaseAnalysisEnabled()146   bool edgeCaseAnalysisEnabled() const {
147     return edgeCaseAnalysis_ && !JitOptions.disableEdgeCaseAnalysis;
148   }
149 
eliminateRedundantChecksEnabled()150   bool eliminateRedundantChecksEnabled() const {
151     return eliminateRedundantChecks_;
152   }
153 
registerAllocator()154   IonRegisterAllocator registerAllocator() const {
155     return JitOptions.forcedRegisterAllocator.valueOr(registerAllocator_);
156   }
157 
scalarReplacementEnabled()158   bool scalarReplacementEnabled() const {
159     return scalarReplacement_ && !JitOptions.disableScalarReplacement;
160   }
161 };
162 
163 class OptimizationLevelInfo {
164  private:
165   mozilla::EnumeratedArray<OptimizationLevel, OptimizationLevel::Count,
166                            OptimizationInfo>
167       infos_;
168 
169  public:
170   OptimizationLevelInfo();
171 
get(OptimizationLevel level)172   const OptimizationInfo* get(OptimizationLevel level) const {
173     return &infos_[level];
174   }
175 
176   OptimizationLevel levelForScript(JSScript* script,
177                                    jsbytecode* pc = nullptr) const;
178 };
179 
180 extern const OptimizationLevelInfo IonOptimizations;
181 
182 }  // namespace jit
183 }  // namespace js
184 
185 #endif /* jit_IonOptimizationLevels_h */
186