IonOptimizationLevels.h (6670B)
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 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 redundant shape guards get removed. 54 bool eliminateRedundantShapeGuards_; 55 56 // Toggles whether redundant GC barriers get removed. 57 bool eliminateRedundantGCBarriers_; 58 59 // Toggles whether interpreted scripts get inlined. 60 bool inlineInterpreted_; 61 62 // Toggles whether native scripts get inlined. 63 bool inlineNative_; 64 65 // Toggles whether global value numbering is used. 66 bool gvn_; 67 68 // Toggles whether loop invariant code motion is performed. 69 bool licm_; 70 71 // Toggles whether Range Analysis is used. 72 bool rangeAnalysis_; 73 74 // Toggles whether instruction reordering is performed. 75 bool reordering_; 76 77 // Toggles whether Truncation based on Range Analysis is used. 78 bool autoTruncate_; 79 80 // Toggles whether sink is used. 81 bool sink_; 82 83 // Toggles whether scalar replacement is used. 84 bool scalarReplacement_; 85 86 // Describes which register allocator to use. 87 IonRegisterAllocator registerAllocator_; 88 89 public: 90 constexpr OptimizationInfo() 91 : level_(OptimizationLevel::Normal), 92 eaa_(false), 93 ama_(false), 94 edgeCaseAnalysis_(false), 95 eliminateRedundantChecks_(false), 96 eliminateRedundantShapeGuards_(false), 97 eliminateRedundantGCBarriers_(false), 98 inlineInterpreted_(false), 99 inlineNative_(false), 100 gvn_(false), 101 licm_(false), 102 rangeAnalysis_(false), 103 reordering_(false), 104 autoTruncate_(false), 105 sink_(false), 106 scalarReplacement_(false), 107 registerAllocator_(RegisterAllocator_Backtracking) {} 108 109 constexpr void initNormalOptimizationInfo() { 110 level_ = OptimizationLevel::Normal; 111 112 autoTruncate_ = true; 113 eaa_ = true; 114 edgeCaseAnalysis_ = true; 115 eliminateRedundantChecks_ = true; 116 eliminateRedundantShapeGuards_ = true; 117 eliminateRedundantGCBarriers_ = true; 118 inlineInterpreted_ = true; 119 inlineNative_ = true; 120 licm_ = true; 121 gvn_ = true; 122 rangeAnalysis_ = true; 123 reordering_ = true; 124 scalarReplacement_ = true; 125 sink_ = true; 126 127 registerAllocator_ = RegisterAllocator_Backtracking; 128 } 129 constexpr void initWasmOptimizationInfo() { 130 // The Wasm optimization level 131 // Disables some passes that don't work well with wasm. 132 133 // Take normal option values for not specified values. 134 initNormalOptimizationInfo(); 135 136 level_ = OptimizationLevel::Wasm; 137 138 ama_ = true; 139 autoTruncate_ = false; 140 edgeCaseAnalysis_ = false; 141 eliminateRedundantChecks_ = false; 142 eliminateRedundantShapeGuards_ = false; 143 eliminateRedundantGCBarriers_ = false; 144 scalarReplacement_ = true; 145 sink_ = false; 146 } 147 148 OptimizationLevel level() const { return level_; } 149 150 bool inlineInterpreted() const { 151 return inlineInterpreted_ && !JitOptions.disableInlining; 152 } 153 154 bool inlineNative() const { 155 return inlineNative_ && !JitOptions.disableInlining; 156 } 157 158 static uint32_t baseWarmUpThresholdForScript(JSContext* cx, JSScript* script); 159 static uint32_t warmUpThresholdForPC(JSScript* script, jsbytecode* pc, 160 uint32_t baseThreshold); 161 162 bool gvnEnabled() const { return gvn_ && !JitOptions.disableGvn; } 163 164 bool licmEnabled() const { return licm_ && !JitOptions.disableLicm; } 165 166 bool rangeAnalysisEnabled() const { 167 return rangeAnalysis_ && !JitOptions.disableRangeAnalysis; 168 } 169 170 bool instructionReorderingEnabled() const { 171 return reordering_ && !JitOptions.disableInstructionReordering; 172 } 173 174 bool autoTruncateEnabled() const { 175 return autoTruncate_ && rangeAnalysisEnabled(); 176 } 177 178 bool sinkEnabled() const { return sink_ && !JitOptions.disableSink; } 179 180 bool eaaEnabled() const { return eaa_ && !JitOptions.disableEaa; } 181 182 bool amaEnabled() const { return ama_ && !JitOptions.disableAma; } 183 184 bool edgeCaseAnalysisEnabled() const { 185 return edgeCaseAnalysis_ && !JitOptions.disableEdgeCaseAnalysis; 186 } 187 188 bool eliminateRedundantChecksEnabled() const { 189 return eliminateRedundantChecks_; 190 } 191 192 bool eliminateRedundantShapeGuardsEnabled() const { 193 return eliminateRedundantShapeGuards_ && 194 !JitOptions.disableRedundantShapeGuards; 195 } 196 197 bool eliminateRedundantGCBarriersEnabled() const { 198 return eliminateRedundantGCBarriers_ && 199 !JitOptions.disableRedundantGCBarriers; 200 } 201 202 IonRegisterAllocator registerAllocator() const; 203 204 bool scalarReplacementEnabled() const { 205 return scalarReplacement_ && !JitOptions.disableScalarReplacement; 206 } 207 }; 208 209 class OptimizationLevelInfo { 210 private: 211 mozilla::EnumeratedArray<OptimizationLevel, OptimizationInfo, 212 size_t(OptimizationLevel::Count)> 213 infos_; 214 215 public: 216 constexpr OptimizationLevelInfo() { 217 infos_[OptimizationLevel::Normal].initNormalOptimizationInfo(); 218 infos_[OptimizationLevel::Wasm].initWasmOptimizationInfo(); 219 } 220 221 const OptimizationInfo* get(OptimizationLevel level) const { 222 return &infos_[level]; 223 } 224 225 OptimizationLevel levelForScript(JSContext* cx, JSScript* script, 226 jsbytecode* pc = nullptr) const; 227 }; 228 229 constexpr OptimizationLevelInfo IonOptimizations; 230 231 } // namespace jit 232 } // namespace js 233 234 #endif /* jit_IonOptimizationLevels_h */