1 //===-------- LLVM-provided High-Level Optimization levels -*- C++ -*------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// 10 /// This header enumerates the LLVM-provided high-level optimization levels. 11 /// Each level has a specific goal and rationale. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_PASSES_OPTIMIZATIONLEVEL_H 16 #define LLVM_PASSES_OPTIMIZATIONLEVEL_H 17 18 #include "llvm/Support/Compiler.h" 19 #include <assert.h> 20 21 namespace llvm { 22 23 class OptimizationLevel final { 24 unsigned SpeedLevel = 2; 25 unsigned SizeLevel = 0; OptimizationLevel(unsigned SpeedLevel,unsigned SizeLevel)26 OptimizationLevel(unsigned SpeedLevel, unsigned SizeLevel) 27 : SpeedLevel(SpeedLevel), SizeLevel(SizeLevel) { 28 // Check that only valid combinations are passed. 29 assert(SpeedLevel <= 3 && 30 "Optimization level for speed should be 0, 1, 2, or 3"); 31 assert(SizeLevel <= 2 && 32 "Optimization level for size should be 0, 1, or 2"); 33 assert((SizeLevel == 0 || SpeedLevel == 2) && 34 "Optimize for size should be encoded with speedup level == 2"); 35 } 36 37 public: 38 OptimizationLevel() = default; 39 /// Disable as many optimizations as possible. This doesn't completely 40 /// disable the optimizer in all cases, for example always_inline functions 41 /// can be required to be inlined for correctness. 42 LLVM_ABI static const OptimizationLevel O0; 43 44 /// Optimize quickly without destroying debuggability. 45 /// 46 /// This level is tuned to produce a result from the optimizer as quickly 47 /// as possible and to avoid destroying debuggability. This tends to result 48 /// in a very good development mode where the compiled code will be 49 /// immediately executed as part of testing. As a consequence, where 50 /// possible, we would like to produce efficient-to-execute code, but not 51 /// if it significantly slows down compilation or would prevent even basic 52 /// debugging of the resulting binary. 53 /// 54 /// As an example, complex loop transformations such as versioning, 55 /// vectorization, or fusion don't make sense here due to the degree to 56 /// which the executed code differs from the source code, and the compile 57 /// time cost. 58 LLVM_ABI static const OptimizationLevel O1; 59 /// Optimize for fast execution as much as possible without triggering 60 /// significant incremental compile time or code size growth. 61 /// 62 /// The key idea is that optimizations at this level should "pay for 63 /// themselves". So if an optimization increases compile time by 5% or 64 /// increases code size by 5% for a particular benchmark, that benchmark 65 /// should also be one which sees a 5% runtime improvement. If the compile 66 /// time or code size penalties happen on average across a diverse range of 67 /// LLVM users' benchmarks, then the improvements should as well. 68 /// 69 /// And no matter what, the compile time needs to not grow superlinearly 70 /// with the size of input to LLVM so that users can control the runtime of 71 /// the optimizer in this mode. 72 /// 73 /// This is expected to be a good default optimization level for the vast 74 /// majority of users. 75 LLVM_ABI static const OptimizationLevel O2; 76 /// Optimize for fast execution as much as possible. 77 /// 78 /// This mode is significantly more aggressive in trading off compile time 79 /// and code size to get execution time improvements. The core idea is that 80 /// this mode should include any optimization that helps execution time on 81 /// balance across a diverse collection of benchmarks, even if it increases 82 /// code size or compile time for some benchmarks without corresponding 83 /// improvements to execution time. 84 /// 85 /// Despite being willing to trade more compile time off to get improved 86 /// execution time, this mode still tries to avoid superlinear growth in 87 /// order to make even significantly slower compile times at least scale 88 /// reasonably. This does not preclude very substantial constant factor 89 /// costs though. 90 LLVM_ABI static const OptimizationLevel O3; 91 /// Similar to \c O2 but tries to optimize for small code size instead of 92 /// fast execution without triggering significant incremental execution 93 /// time slowdowns. 94 /// 95 /// The logic here is exactly the same as \c O2, but with code size and 96 /// execution time metrics swapped. 97 /// 98 /// A consequence of the different core goal is that this should in general 99 /// produce substantially smaller executables that still run in 100 /// a reasonable amount of time. 101 LLVM_ABI static const OptimizationLevel Os; 102 /// A very specialized mode that will optimize for code size at any and all 103 /// costs. 104 /// 105 /// This is useful primarily when there are absolute size limitations and 106 /// any effort taken to reduce the size is worth it regardless of the 107 /// execution time impact. You should expect this level to produce rather 108 /// slow, but very small, code. 109 LLVM_ABI static const OptimizationLevel Oz; 110 isOptimizingForSpeed()111 bool isOptimizingForSpeed() const { return SizeLevel == 0 && SpeedLevel > 0; } 112 isOptimizingForSize()113 bool isOptimizingForSize() const { return SizeLevel > 0; } 114 115 bool operator==(const OptimizationLevel &Other) const { 116 return SizeLevel == Other.SizeLevel && SpeedLevel == Other.SpeedLevel; 117 } 118 bool operator!=(const OptimizationLevel &Other) const { 119 return SizeLevel != Other.SizeLevel || SpeedLevel != Other.SpeedLevel; 120 } 121 getSpeedupLevel()122 unsigned getSpeedupLevel() const { return SpeedLevel; } 123 getSizeLevel()124 unsigned getSizeLevel() const { return SizeLevel; } 125 }; 126 } // namespace llvm 127 128 #endif 129