diff --git a/flang/lib/Optimizer/Passes/Pipelines.cpp b/flang/lib/Optimizer/Passes/Pipelines.cpp index 16c2cda5d6d9..879a22482411 100644 --- a/flang/lib/Optimizer/Passes/Pipelines.cpp +++ b/flang/lib/Optimizer/Passes/Pipelines.cpp @@ -68,7 +68,7 @@ void addCfgConversionPass(mlir::PassManager &pm, void addAVC(mlir::PassManager &pm, const llvm::OptimizationLevel &optLevel) { ArrayValueCopyOptions options; - options.optimizeConflicts = optLevel.isOptimizingForSpeed(); + options.optimizeConflicts = optLevel != llvm::OptimizationLevel::O0; addNestedPassConditionally( pm, disableFirAvc, [&]() { return createArrayValueCopyPass(options); }); } @@ -210,7 +210,7 @@ void createDefaultFIROptimizerPassPipeline(mlir::PassManager &pm, pm, fir::createCharacterConversion); pm.addPass(mlir::createCanonicalizerPass(config)); pm.addPass(fir::createSimplifyRegionLite()); - if (pc.OptLevel.isOptimizingForSpeed()) { + if (pc.OptLevel != llvm::OptimizationLevel::O0) { // These passes may increase code size. pm.addPass(fir::createSimplifyIntrinsics()); pm.addPass(fir::createAlgebraicSimplificationPass(config)); @@ -235,7 +235,7 @@ void createDefaultFIROptimizerPassPipeline(mlir::PassManager &pm, pm.addPass(mlir::createCSEPass()); // Run LICM after CSE, which may reduce the number of operations to hoist. - if (enableFirLICM && pc.OptLevel.isOptimizingForSpeed()) + if (enableFirLICM && pc.OptLevel != llvm::OptimizationLevel::O0) pm.addPass(fir::createLoopInvariantCodeMotion()); // Polymorphic types @@ -244,13 +244,14 @@ void createDefaultFIROptimizerPassPipeline(mlir::PassManager &pm, // Optimize redundant array repacking operations, // if the source is known to be contiguous. - if (pc.OptLevel.isOptimizingForSpeed()) + if (pc.OptLevel != llvm::OptimizationLevel::O0) pm.addPass(fir::createOptimizeArrayRepacking()); pm.addPass(fir::createLowerRepackArraysPass()); // Expand FIR operations that may use SCF dialect for their // implementation. This is a mandatory pass. pm.addPass(fir::createSimplifyFIROperations( - {/*preferInlineImplementation=*/pc.OptLevel.isOptimizingForSpeed()})); + {/*preferInlineImplementation=*/pc.OptLevel != + llvm::OptimizationLevel::O0})); addNestedPassToAllTopLevelOperations( pm, fir::createStackReclaim); @@ -264,7 +265,7 @@ void createDefaultFIROptimizerPassPipeline(mlir::PassManager &pm, pm.addPass(fir::createConvertComplexPow()); pm.addPass(mlir::createCSEPass()); - if (pc.OptLevel.isOptimizingForSpeed()) + if (pc.OptLevel != llvm::OptimizationLevel::O0) pm.addPass(fir::createSetRuntimeCallAttributes()); // Last Optimizer EP Callback @@ -280,11 +281,9 @@ void createHLFIRToFIRPassPipeline(mlir::PassManager &pm, EnableOpenMP enableOpenMP, const MLIRToLLVMPassPipelineConfig &config) { llvm::OptimizationLevel optLevel = config.OptLevel; - if (optLevel.getSpeedupLevel() > 0) { + if (optLevel != llvm::OptimizationLevel::O0) { addNestedPassToAllTopLevelOperations( pm, hlfir::createExpressionSimplification); - } - if (optLevel.isOptimizingForSpeed()) { addCanonicalizerPassWithoutRegionSimplification(pm); addNestedPassToAllTopLevelOperations(pm, [&]() { return hlfir::createSimplifyHLFIRIntrinsics( @@ -295,7 +294,7 @@ void createHLFIRToFIRPassPipeline(mlir::PassManager &pm, pm, hlfir::createInlineElementals); addNestedPassToAllTopLevelOperations( pm, hlfir::createSeparateAllocatableAssign); - if (optLevel.isOptimizingForSpeed()) { + if (optLevel != llvm::OptimizationLevel::O0) { addCanonicalizerPassWithoutRegionSimplification(pm); pm.addPass(mlir::createCSEPass()); // Run SimplifyHLFIRIntrinsics pass late after CSE, @@ -328,7 +327,7 @@ void createHLFIRToFIRPassPipeline(mlir::PassManager &pm, }); } pm.addPass(hlfir::createLowerHLFIROrderedAssignments( - {/*tryFusingAssignments=*/optLevel.isOptimizingForSpeed()})); + {/*tryFusingAssignments=*/optLevel != llvm::OptimizationLevel::O0})); pm.addPass(hlfir::createLowerHLFIRIntrinsics()); hlfir::BufferizeHLFIROptions bufferizeOptions; @@ -336,7 +335,7 @@ void createHLFIRToFIRPassPipeline(mlir::PassManager &pm, // from hlfir.elemental lowering, if the result is an empty array. // This helps to avoid long running loops for elementals with // shapes like (0, HUGE). - if (optLevel.isOptimizingForSpeed()) + if (optLevel != llvm::OptimizationLevel::O0) bufferizeOptions.optimizeEmptyElementals = true; pm.addPass(hlfir::createBufferizeHLFIR(bufferizeOptions)); // Run hlfir.assign inlining again after BufferizeHLFIR, @@ -346,7 +345,7 @@ void createHLFIRToFIRPassPipeline(mlir::PassManager &pm, // TODO: we can remove the previous InlineHLFIRAssign, when // FIR AliasAnalysis is good enough to say that a temporary // array does not alias with any user object. - if (optLevel.isOptimizingForSpeed()) + if (optLevel != llvm::OptimizationLevel::O0) addNestedPassToAllTopLevelOperations( pm, hlfir::createInlineHLFIRAssign); pm.addPass(hlfir::createConvertHLFIRtoFIR()); @@ -406,7 +405,7 @@ void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm, llvm::StringRef inputFilename) { pm.addPass(fir::createMIFOpConversion()); fir::addBoxedProcedurePass(pm, config.EnableSafeTrampoline); - if (config.OptLevel.isOptimizingForSpeed() && config.AliasAnalysis && + if (config.OptLevel != llvm::OptimizationLevel::O0 && config.AliasAnalysis && !disableFirAliasTags && !useOldAliasTags) pm.addPass(fir::createAddAliasTags()); addNestedPassToAllTopLevelOperations( @@ -446,8 +445,8 @@ void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm, // TODO: re-enable setNoAlias by default (when optimizing for speed) once // function specialization is fixed. bool setNoAlias = forceNoAlias; - bool setNoCapture = config.OptLevel.isOptimizingForSpeed(); - bool setReadOnly = config.OptLevel.isOptimizingForSpeed(); + bool setNoCapture = config.OptLevel != llvm::OptimizationLevel::O0; + bool setReadOnly = config.OptLevel != llvm::OptimizationLevel::O0; pm.addPass(fir::createFunctionAttr( {framePointerKind, config.InstrumentFunctionEntry, diff --git a/llvm/include/llvm/Passes/OptimizationLevel.h b/llvm/include/llvm/Passes/OptimizationLevel.h index c74407beb859..3aa1a9d2fcf3 100644 --- a/llvm/include/llvm/Passes/OptimizationLevel.h +++ b/llvm/include/llvm/Passes/OptimizationLevel.h @@ -20,20 +20,11 @@ namespace llvm { -class OptimizationLevel final { - unsigned SpeedLevel = 2; - OptimizationLevel(unsigned SpeedLevel) : SpeedLevel(SpeedLevel) { - // Check that only valid values are passed. - assert(SpeedLevel <= 3 && - "Optimization level for speed should be 0, 1, 2, or 3"); - } - -public: - OptimizationLevel() = default; +enum class OptimizationLevel { /// 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. - LLVM_ABI static const OptimizationLevel O0; + O0 = 0, /// Optimize quickly without destroying debuggability. /// @@ -49,7 +40,8 @@ public: /// 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. - LLVM_ABI static const OptimizationLevel O1; + O1 = 1, + /// Optimize for fast execution as much as possible without triggering /// significant incremental compile time or code size growth. /// @@ -66,7 +58,7 @@ public: /// /// This is expected to be a good default optimization level for the vast /// majority of users. - LLVM_ABI static const OptimizationLevel O2; + O2 = 2, /// Optimize for fast execution as much as possible. /// /// This mode is significantly more aggressive in trading off compile time @@ -81,18 +73,7 @@ public: /// order to make even significantly slower compile times at least scale /// reasonably. This does not preclude very substantial constant factor /// costs though. - LLVM_ABI static const OptimizationLevel O3; - - bool isOptimizingForSpeed() const { return SpeedLevel > 0; } - - bool operator==(const OptimizationLevel &Other) const { - return SpeedLevel == Other.SpeedLevel; - } - bool operator!=(const OptimizationLevel &Other) const { - return SpeedLevel != Other.SpeedLevel; - } - - unsigned getSpeedupLevel() const { return SpeedLevel; } + O3 = 3, }; } // namespace llvm diff --git a/llvm/include/llvm/Transforms/IPO/ExpandVariadics.h b/llvm/include/llvm/Transforms/IPO/ExpandVariadics.h index 191b208862e3..06baa3a32ecd 100644 --- a/llvm/include/llvm/Transforms/IPO/ExpandVariadics.h +++ b/llvm/include/llvm/Transforms/IPO/ExpandVariadics.h @@ -14,7 +14,6 @@ namespace llvm { class Module; class ModulePass; -class OptimizationLevel; enum class ExpandVariadicsMode { Unspecified, // Use the implementation defaults diff --git a/llvm/lib/Passes/CMakeLists.txt b/llvm/lib/Passes/CMakeLists.txt index 5d7cd3689f3f..eaabf60b018f 100644 --- a/llvm/lib/Passes/CMakeLists.txt +++ b/llvm/lib/Passes/CMakeLists.txt @@ -1,6 +1,5 @@ add_llvm_component_library(LLVMPasses CodeGenPassBuilder.cpp - OptimizationLevel.cpp PassBuilder.cpp PassBuilderBindings.cpp PassBuilderPipelines.cpp diff --git a/llvm/lib/Passes/OptimizationLevel.cpp b/llvm/lib/Passes/OptimizationLevel.cpp deleted file mode 100644 index 68c2ddc475b4..000000000000 --- a/llvm/lib/Passes/OptimizationLevel.cpp +++ /dev/null @@ -1,16 +0,0 @@ -//===- OptimizationLevel.cpp ----------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "llvm/Passes/OptimizationLevel.h" - -using namespace llvm; - -const OptimizationLevel OptimizationLevel::O0 = {0}; -const OptimizationLevel OptimizationLevel::O1 = {1}; -const OptimizationLevel OptimizationLevel::O2 = {2}; -const OptimizationLevel OptimizationLevel::O3 = {3}; diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index 7f99f6376bcb..48a5108355c3 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -892,7 +892,7 @@ Expected parseLoopUnrollOptions(StringRef Params) { std::tie(ParamName, Params) = Params.split(';'); std::optional OptLevel = parseOptLevel(ParamName); if (OptLevel) { - UnrollOpts.setOptLevel(OptLevel->getSpeedupLevel()); + UnrollOpts.setOptLevel(static_cast(*OptLevel)); continue; } if (ParamName.consume_front("full-unroll-max=")) { @@ -2064,8 +2064,8 @@ PassBuilder::parsePipelineText(StringRef Text) { static void setupOptionsForPipelineAlias(PipelineTuningOptions &PTO, OptimizationLevel L) { - PTO.LoopVectorization = L.getSpeedupLevel() > 1; - PTO.SLPVectorization = L.getSpeedupLevel() > 1; + PTO.LoopVectorization = L >= OptimizationLevel::O2; + PTO.SLPVectorization = L >= OptimizationLevel::O2; } Error PassBuilder::parseModulePass(ModulePassManager &MPM, diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp index f89dc099a912..d62828c78bfe 100644 --- a/llvm/lib/Passes/PassBuilderPipelines.cpp +++ b/llvm/lib/Passes/PassBuilderPipelines.cpp @@ -570,7 +570,7 @@ PassBuilder::buildO1FunctionSimplificationPipeline(OptimizationLevel Level, // attention to it. if (!isThinLTOPreLink(Phase) || !PGOOpt || PGOOpt->Action != PGOOptions::SampleUse) - LPM2.addPass(LoopFullUnrollPass(Level.getSpeedupLevel(), + LPM2.addPass(LoopFullUnrollPass(static_cast(Level), /* OnlyWhenForced= */ !PTO.LoopUnrolling, PTO.ForgetAllSCEVInLoopUnroll)); @@ -630,7 +630,7 @@ PassBuilder::buildFunctionSimplificationPipeline(OptimizationLevel Level, // The O1 pipeline has a separate pipeline creation function to simplify // construction readability. - if (Level.getSpeedupLevel() == 1) + if (Level == OptimizationLevel::O1) return buildO1FunctionSimplificationPipeline(Level, Phase); FunctionPassManager FPM; @@ -752,7 +752,7 @@ PassBuilder::buildFunctionSimplificationPipeline(OptimizationLevel Level, // attention to it. if (!isThinLTOPreLink(Phase) || !PGOOpt || PGOOpt->Action != PGOOptions::SampleUse) - LPM2.addPass(LoopFullUnrollPass(Level.getSpeedupLevel(), + LPM2.addPass(LoopFullUnrollPass(static_cast(Level), /* OnlyWhenForced= */ !PTO.LoopUnrolling, PTO.ForgetAllSCEVInLoopUnroll)); @@ -963,7 +963,7 @@ void PassBuilder::addPGOInstrPassesForO0(ModulePassManager &MPM, } static InlineParams getInlineParamsFromOptLevel(OptimizationLevel Level) { - return getInlineParamsFromOptLevel(Level.getSpeedupLevel()); + return getInlineParamsFromOptLevel(static_cast(Level)); } ModuleInlinerWrapperPass @@ -1368,9 +1368,9 @@ void PassBuilder::addVectorPasses(OptimizationLevel Level, // We do UnrollAndJam in a separate LPM to ensure it happens before unroll if (EnableUnrollAndJam && PTO.LoopUnrolling) FPM.addPass(createFunctionToLoopPassAdaptor( - LoopUnrollAndJamPass(Level.getSpeedupLevel()))); + LoopUnrollAndJamPass(static_cast(Level)))); FPM.addPass(LoopUnrollPass(LoopUnrollOptions( - Level.getSpeedupLevel(), /*OnlyWhenForced=*/!PTO.LoopUnrolling, + static_cast(Level), /*OnlyWhenForced=*/!PTO.LoopUnrolling, PTO.ForgetAllSCEVInLoopUnroll))); FPM.addPass(WarnMissedTransformationsPass()); // Now that we are done with loop unrolling, be it either by LoopVectorizer, @@ -1399,7 +1399,7 @@ void PassBuilder::addVectorPasses(OptimizationLevel Level, // Cleanup after the loop optimization passes. FPM.addPass(InstCombinePass()); - if (Level.getSpeedupLevel() > 1 && ExtraVectorizerPasses) { + if (Level > OptimizationLevel::O1 && ExtraVectorizerPasses) { ExtraFunctionPassManager ExtraPasses; // At higher optimization levels, try to clean up any runtime overlap and // alignment checks inserted by the vectorizer. We want to track correlated @@ -1450,7 +1450,7 @@ void PassBuilder::addVectorPasses(OptimizationLevel Level, // Optimize parallel scalar instruction chains into SIMD instructions. if (PTO.SLPVectorization) { FPM.addPass(SLPVectorizerPass()); - if (Level.getSpeedupLevel() > 1 && ExtraVectorizerPasses) { + if (Level >= OptimizationLevel::O2 && ExtraVectorizerPasses) { FPM.addPass(EarlyCSEPass()); } } @@ -1468,10 +1468,10 @@ void PassBuilder::addVectorPasses(OptimizationLevel Level, // We do UnrollAndJam in a separate LPM to ensure it happens before unroll if (EnableUnrollAndJam && PTO.LoopUnrolling) { FPM.addPass(createFunctionToLoopPassAdaptor( - LoopUnrollAndJamPass(Level.getSpeedupLevel()))); + LoopUnrollAndJamPass(static_cast(Level)))); } FPM.addPass(LoopUnrollPass(LoopUnrollOptions( - Level.getSpeedupLevel(), /*OnlyWhenForced=*/!PTO.LoopUnrolling, + static_cast(Level), /*OnlyWhenForced=*/!PTO.LoopUnrolling, PTO.ForgetAllSCEVInLoopUnroll))); FPM.addPass(WarnMissedTransformationsPass()); // Now that we are done with loop unrolling, be it either by LoopVectorizer, @@ -2091,7 +2091,7 @@ PassBuilder::buildLTODefaultPipeline(OptimizationLevel Level, // libraries and other oracles. MPM.addPass(InferFunctionAttrsPass()); - if (Level.getSpeedupLevel() > 1) { + if (Level >= OptimizationLevel::O2) { MPM.addPass(createModuleToFunctionPassAdaptor( CallSiteSplittingPass(), PTO.EagerlyInvalidateAnalyses)); @@ -2182,7 +2182,7 @@ PassBuilder::buildLTODefaultPipeline(OptimizationLevel Level, // calls, etc, so let instcombine do this. FunctionPassManager PeepholeFPM; PeepholeFPM.addPass(InstCombinePass()); - if (Level.getSpeedupLevel() > 1) + if (Level >= OptimizationLevel::O2) PeepholeFPM.addPass(AggressiveInstCombinePass()); invokePeepholeEPCallbacks(PeepholeFPM, Level); @@ -2305,14 +2305,14 @@ PassBuilder::buildLTODefaultPipeline(OptimizationLevel Level, invokeVectorizerStartEPCallbacks(MainFPM, Level); LoopPassManager LPM; - if (EnableLoopFlatten && Level.getSpeedupLevel() > 1) + if (EnableLoopFlatten && Level >= OptimizationLevel::O2) LPM.addPass(LoopFlattenPass()); LPM.addPass(IndVarSimplifyPass()); LPM.addPass(LoopDeletionPass()); // FIXME: Add loop interchange. // Unroll small loops and perform peeling. - LPM.addPass(LoopFullUnrollPass(Level.getSpeedupLevel(), + LPM.addPass(LoopFullUnrollPass(static_cast(Level), /* OnlyWhenForced= */ !PTO.LoopUnrolling, PTO.ForgetAllSCEVInLoopUnroll)); // The loop passes in LPM (LoopFullUnrollPass) do not preserve MemorySSA. diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp index fd7dde2d253e..7c795731f7bd 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp @@ -1076,8 +1076,7 @@ void AMDGPUTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) { // Add promote kernel arguments pass to the opt pipeline right before // infer address spaces which is needed to do actual address space // rewriting. - if (Level.getSpeedupLevel() > OptimizationLevel::O1.getSpeedupLevel() && - EnablePromoteKernelArguments) + if (Level > OptimizationLevel::O1 && EnablePromoteKernelArguments) FPM.addPass(AMDGPUPromoteKernelArgumentsPass()); // Add infer address spaces pass to the opt pipeline after inlining diff --git a/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp b/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp index 7811c5692808..8728bd996551 100644 --- a/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp +++ b/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp @@ -295,12 +295,12 @@ void HexagonTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) { PB.registerLateLoopOptimizationsEPCallback( [=](LoopPassManager &LPM, OptimizationLevel Level) { - if (Level.getSpeedupLevel() > 0) + if (Level != OptimizationLevel::O0) LPM.addPass(HexagonLoopIdiomRecognitionPass()); }); PB.registerLoopOptimizerEndEPCallback( [=](LoopPassManager &LPM, OptimizationLevel Level) { - if (Level.getSpeedupLevel() > 0) + if (Level != OptimizationLevel::O0) LPM.addPass(HexagonVectorLoopCarriedReusePass()); }); } diff --git a/polly/lib/Support/RegisterPasses.cpp b/polly/lib/Support/RegisterPasses.cpp index b1c0e3c32a91..a00176bb653a 100644 --- a/polly/lib/Support/RegisterPasses.cpp +++ b/polly/lib/Support/RegisterPasses.cpp @@ -483,7 +483,7 @@ static void buildEarlyPollyPipeline(llvm::ModulePassManager &MPM, llvm::OptimizationLevel Level, IntrusiveRefCntPtr FS) { bool EnableForOpt = - shouldEnablePollyForOptimization() && Level.isOptimizingForSpeed(); + shouldEnablePollyForOptimization() && Level != OptimizationLevel::O0; if (!shouldEnablePollyForDiagnostic() && !EnableForOpt) return; @@ -513,7 +513,7 @@ static void buildLatePollyPipeline(FunctionPassManager &PM, llvm::OptimizationLevel Level, IntrusiveRefCntPtr FS) { bool EnableForOpt = - shouldEnablePollyForOptimization() && Level.isOptimizingForSpeed(); + shouldEnablePollyForOptimization() && Level != OptimizationLevel::O0; if (!shouldEnablePollyForDiagnostic() && !EnableForOpt) return;