Skip to content

Commit

Permalink
[llvm] Make new pass manager's OptimizationLevel a class
Browse files Browse the repository at this point in the history
Summary:
The old pass manager separated speed optimization and size optimization
levels into two unsigned values. Coallescing both in an enum in the new
pass manager may lead to unintentional casts and comparisons.

In particular, taking a look at how the loop unroll passes were constructed
previously, the Os/Oz are now (==new pass manager) treated just like O3,
likely unintentionally.

This change disallows raw comparisons between optimization levels, to
avoid such unintended effects. As an effect, the O{s|z} behavior changes
for loop unrolling and loop unroll and jam, matching O2 rather than O3.

The change also parameterizes the threshold values used for loop
unrolling, primarily to aid testing.

Reviewers: tejohnson, davidxl

Reviewed By: tejohnson

Subscribers: zzheng, ychen, mehdi_amini, hiraditya, steven_wu, dexonsmith, dang, cfe-commits, llvm-commits

Tags: #clang, #llvm

Differential Revision: https://reviews.llvm.org/D72547
  • Loading branch information
mtrofin committed Jan 16, 2020
1 parent c29a9f6 commit 7acfda6
Show file tree
Hide file tree
Showing 7 changed files with 233 additions and 79 deletions.
10 changes: 5 additions & 5 deletions clang/lib/CodeGen/BackendUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -924,25 +924,25 @@ static PassBuilder::OptimizationLevel mapToLevel(const CodeGenOptions &Opts) {
llvm_unreachable("Invalid optimization level!");

case 1:
return PassBuilder::O1;
return PassBuilder::OptimizationLevel::O1;

case 2:
switch (Opts.OptimizeSize) {
default:
llvm_unreachable("Invalid optimization level for size!");

case 0:
return PassBuilder::O2;
return PassBuilder::OptimizationLevel::O2;

case 1:
return PassBuilder::Os;
return PassBuilder::OptimizationLevel::Os;

case 2:
return PassBuilder::Oz;
return PassBuilder::OptimizationLevel::Oz;
}

case 3:
return PassBuilder::O3;
return PassBuilder::OptimizationLevel::O3;
}
}

Expand Down
54 changes: 41 additions & 13 deletions llvm/include/llvm/Passes/PassBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,26 @@ class PassBuilder {
///
/// This enumerates the LLVM-provided high-level optimization levels. Each
/// level has a specific goal and rationale.
enum OptimizationLevel {
class OptimizationLevel final {
unsigned SpeedLevel = 2;
unsigned SizeLevel = 0;
OptimizationLevel(unsigned SpeedLevel, unsigned SizeLevel)
: SpeedLevel(SpeedLevel), SizeLevel(SizeLevel) {
// Check that only valid combinations are passed.
assert(SpeedLevel <= 3 &&
"Optimization level for speed should be 0, 1, 2, or 3");
assert(SizeLevel <= 2 &&
"Optimization level for size should be 0, 1, or 2");
assert((SizeLevel == 0 || SpeedLevel == 2) &&
"Optimize for size should be encoded with speedup level == 2");
}

public:
OptimizationLevel() = default;
/// Disable as many optimizations as possible. This doesn't completely
/// disable the optimizer in all cases, for example always_inline functions
/// can be required to be inlined for correctness.
O0,
static const OptimizationLevel O0;

/// Optimize quickly without destroying debuggability.
///
Expand All @@ -161,10 +176,9 @@ class PassBuilder {
///
/// As an example, complex loop transformations such as versioning,
/// vectorization, or fusion don't make sense here due to the degree to
/// which the executed code differs from the source code, and the compile time
/// cost.
O1,

/// which the executed code differs from the source code, and the compile
/// time cost.
static const OptimizationLevel O1;
/// Optimize for fast execution as much as possible without triggering
/// significant incremental compile time or code size growth.
///
Expand All @@ -181,8 +195,7 @@ class PassBuilder {
///
/// This is expected to be a good default optimization level for the vast
/// majority of users.
O2,

static const OptimizationLevel O2;
/// Optimize for fast execution as much as possible.
///
/// This mode is significantly more aggressive in trading off compile time
Expand All @@ -197,8 +210,7 @@ class PassBuilder {
/// order to make even significantly slower compile times at least scale
/// reasonably. This does not preclude very substantial constant factor
/// costs though.
O3,

static const OptimizationLevel O3;
/// Similar to \c O2 but tries to optimize for small code size instead of
/// fast execution without triggering significant incremental execution
/// time slowdowns.
Expand All @@ -209,16 +221,32 @@ class PassBuilder {
/// A consequence of the different core goal is that this should in general
/// produce substantially smaller executables that still run in
/// a reasonable amount of time.
Os,

static const OptimizationLevel Os;
/// A very specialized mode that will optimize for code size at any and all
/// costs.
///
/// This is useful primarily when there are absolute size limitations and
/// any effort taken to reduce the size is worth it regardless of the
/// execution time impact. You should expect this level to produce rather
/// slow, but very small, code.
Oz
static const OptimizationLevel Oz;

bool isOptimizingForSpeed() const {
return SizeLevel == 0 && SpeedLevel > 0;
}

bool isOptimizingForSize() const { return SizeLevel > 0; }

bool operator==(const OptimizationLevel &Other) const {
return SizeLevel == Other.SizeLevel && SpeedLevel == Other.SpeedLevel;
}
bool operator!=(const OptimizationLevel &Other) const {
return SizeLevel != Other.SizeLevel || SpeedLevel != Other.SpeedLevel;
}

unsigned getSpeedupLevel() const { return SpeedLevel; }

unsigned getSizeLevel() const { return SizeLevel; }
};

explicit PassBuilder(TargetMachine *TM = nullptr,
Expand Down
8 changes: 4 additions & 4 deletions llvm/lib/LTO/LTOBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,16 +203,16 @@ static void runNewPMPasses(const Config &Conf, Module &Mod, TargetMachine *TM,
default:
llvm_unreachable("Invalid optimization level");
case 0:
OL = PassBuilder::O0;
OL = PassBuilder::OptimizationLevel::O0;
break;
case 1:
OL = PassBuilder::O1;
OL = PassBuilder::OptimizationLevel::O1;
break;
case 2:
OL = PassBuilder::O2;
OL = PassBuilder::OptimizationLevel::O2;
break;
case 3:
OL = PassBuilder::O3;
OL = PassBuilder::OptimizationLevel::O3;
break;
}

Expand Down
Loading

0 comments on commit 7acfda6

Please sign in to comment.