diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -299,21 +299,6 @@ return TLII; } -static CodeGenOpt::Level getCGOptLevel(const CodeGenOptions &CodeGenOpts) { - switch (CodeGenOpts.OptimizationLevel) { - default: - llvm_unreachable("Invalid optimization level!"); - case 0: - return CodeGenOpt::None; - case 1: - return CodeGenOpt::Less; - case 2: - return CodeGenOpt::Default; // O2/Os/Oz - case 3: - return CodeGenOpt::Aggressive; - } -} - static std::optional getCodeModel(const CodeGenOptions &CodeGenOpts) { unsigned CodeModel = llvm::StringSwitch(CodeGenOpts.CodeModel) @@ -578,7 +563,10 @@ std::string FeaturesStr = llvm::join(TargetOpts.Features.begin(), TargetOpts.Features.end(), ","); llvm::Reloc::Model RM = CodeGenOpts.RelocationModel; - CodeGenOpt::Level OptLevel = getCGOptLevel(CodeGenOpts); + std::optional OptLevelOrNone = + CodeGenOpt::getLevel(CodeGenOpts.OptimizationLevel); + assert(OptLevelOrNone); + CodeGenOpt::Level OptLevel = *OptLevelOrNone; llvm::TargetOptions Options; if (!initTargetOptions(Diags, Options, CodeGenOpts, TargetOpts, LangOpts, @@ -1160,7 +1148,7 @@ Conf.CodeModel = getCodeModel(CGOpts); Conf.MAttrs = TOpts.Features; Conf.RelocModel = CGOpts.RelocationModel; - Conf.CGOptLevel = getCGOptLevel(CGOpts); + Conf.CGOptLevel = *CodeGenOpt::getLevel(CGOpts.OptimizationLevel); Conf.OptLevel = CGOpts.OptimizationLevel; initTargetOptions(Diags, Conf.Options, CGOpts, TOpts, LOpts, HeaderOpts); Conf.SampleProfile = std::move(SampleProfile); diff --git a/clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp b/clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp --- a/clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp +++ b/clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp @@ -54,14 +54,11 @@ CodeGenOpt::Level OLvl = CodeGenOpt::Default; for (auto &A : ExtraArgs) { if (A[0] == '-' && A[1] == 'O') { - switch(A[2]) { - case '0': OLvl = CodeGenOpt::None; break; - case '1': OLvl = CodeGenOpt::Less; break; - case '2': OLvl = CodeGenOpt::Default; break; - case '3': OLvl = CodeGenOpt::Aggressive; break; - default: - errs() << "error: opt level must be between 0 and 3.\n"; - std::exit(1); + if (auto Level = CodeGenOpt::parseLevel(A[2])) { + OLvl = *Level; + } else { + errs() << "error: opt level must be between 0 and 3.\n"; + std::exit(1); } } } diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -661,20 +661,6 @@ return UnifiedFeatures; } -CodeGenOpt::Level getCGOptLevel(unsigned OptLevel) { - switch (OptLevel) { - case 0: - return CodeGenOpt::None; - case 1: - return CodeGenOpt::Less; - case 2: - return CodeGenOpt::Default; - case 3: - return CodeGenOpt::Aggressive; - } - llvm_unreachable("Invalid optimization level"); -} - template > std::unique_ptr createLTO( const ArgList &Args, const std::vector &Features, @@ -692,7 +678,10 @@ StringRef OptLevel = Args.getLastArgValue(OPT_opt_level, "O2"); Conf.MAttrs = Features; - Conf.CGOptLevel = getCGOptLevel(OptLevel[1] - '0'); + std::optional CGOptLevelOrNone = + CodeGenOpt::parseLevel(OptLevel[1]); + assert(CGOptLevelOrNone); + Conf.CGOptLevel = *CGOptLevelOrNone; Conf.OptLevel = OptLevel[1] - '0'; if (Conf.OptLevel > 0) Conf.UseDefaultPipeline = true; diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -573,22 +573,6 @@ } } -static llvm::CodeGenOpt::Level -getCGOptLevel(const Fortran::frontend::CodeGenOptions &opts) { - switch (opts.OptimizationLevel) { - default: - llvm_unreachable("Invalid optimization level!"); - case 0: - return llvm::CodeGenOpt::None; - case 1: - return llvm::CodeGenOpt::Less; - case 2: - return llvm::CodeGenOpt::Default; - case 3: - return llvm::CodeGenOpt::Aggressive; - } -} - void CodeGenAction::setUpTargetMachine() { CompilerInstance &ci = this->getInstance(); @@ -603,7 +587,10 @@ // Create `TargetMachine` const auto &CGOpts = ci.getInvocation().getCodeGenOpts(); - llvm::CodeGenOpt::Level OptLevel = getCGOptLevel(CGOpts); + std::optional OptLevelOrNone = + CodeGenOpt::getLevel(CGOpts.OptimizationLevel); + assert(OptLevelOrNone); + llvm::CodeGenOpt::Level OptLevel = *OptLevelOrNone; std::string featuresStr = llvm::join(targetOpts.featuresAsWritten.begin(), targetOpts.featuresAsWritten.end(), ","); tm.reset(theTarget->createTargetMachine( diff --git a/llvm/include/llvm/Support/CodeGen.h b/llvm/include/llvm/Support/CodeGen.h --- a/llvm/include/llvm/Support/CodeGen.h +++ b/llvm/include/llvm/Support/CodeGen.h @@ -14,6 +14,9 @@ #ifndef LLVM_SUPPORT_CODEGEN_H #define LLVM_SUPPORT_CODEGEN_H +#include +#include + namespace llvm { // Relocation model types. @@ -47,15 +50,37 @@ }; } - // Code generation optimization level. namespace CodeGenOpt { - enum Level { - None = 0, // -O0 - Less = 1, // -O1 - Default = 2, // -O2, -Os - Aggressive = 3 // -O3 - }; + /// Type for the unique integer IDs of code generation optimization levels. + using IDType = uint8_t; + /// Code generation optimization level. + enum Level : IDType { + None = 0, ///< -O0 + Less = 1, ///< -O1 + Default = 2, ///< -O2, -Os + Aggressive = 3 ///< -O3 + }; + /// Get the \c Level identified by the integer \p ID. + /// + /// Returns std::nullopt if \p ID is invalid. + inline std::optional getLevel(IDType ID) { + if (ID < 0 || ID > 3) + return std::nullopt; + return static_cast(ID); + } + /// Get the integer \c ID of \p Level. + inline IDType getID(CodeGenOpt::Level Level) { + return static_cast(Level); + } + /// Parse \p C as a single digit integer ID and get matching \c Level. + /// + /// Returns std::nullopt if the input is not a valid digit or not a valid ID. + inline std::optional parseLevel(char C) { + if (C < '0') + return std::nullopt; + return getLevel(static_cast(C - '0')); } + } // namespace CodeGenOpt /// These enums are meant to be passed into addPassesToEmitFile to indicate /// what type of file to emit, and returned by it to indicate what type of diff --git a/llvm/lib/LTO/LTOCodeGenerator.cpp b/llvm/lib/LTO/LTOCodeGenerator.cpp --- a/llvm/lib/LTO/LTOCodeGenerator.cpp +++ b/llvm/lib/LTO/LTOCodeGenerator.cpp @@ -200,21 +200,10 @@ Config.OptLevel = Level; Config.PTO.LoopVectorization = Config.OptLevel > 1; Config.PTO.SLPVectorization = Config.OptLevel > 1; - switch (Config.OptLevel) { - case 0: - Config.CGOptLevel = CodeGenOpt::None; - return; - case 1: - Config.CGOptLevel = CodeGenOpt::Less; - return; - case 2: - Config.CGOptLevel = CodeGenOpt::Default; - return; - case 3: - Config.CGOptLevel = CodeGenOpt::Aggressive; - return; - } - llvm_unreachable("Unknown optimization level!"); + std::optional CGOptLevelOrNone = + CodeGenOpt::getLevel(Config.OptLevel); + assert(CGOptLevelOrNone); + Config.CGOptLevel = *CGOptLevelOrNone; } bool LTOCodeGenerator::writeMergedModules(StringRef Path) { diff --git a/llvm/tools/gold/gold-plugin.cpp b/llvm/tools/gold/gold-plugin.cpp --- a/llvm/tools/gold/gold-plugin.cpp +++ b/llvm/tools/gold/gold-plugin.cpp @@ -846,20 +846,6 @@ return FD; } -static CodeGenOpt::Level getCGOptLevel() { - switch (options::OptLevel) { - case 0: - return CodeGenOpt::None; - case 1: - return CodeGenOpt::Less; - case 2: - return CodeGenOpt::Default; - case 3: - return CodeGenOpt::Aggressive; - } - llvm_unreachable("Invalid optimization level"); -} - /// Parse the thinlto_prefix_replace option into the \p OldPrefix and /// \p NewPrefix strings, if it was specified. static void getThinLTOOldAndNewPrefix(std::string &OldPrefix, @@ -896,7 +882,10 @@ Conf.MAttrs = codegen::getMAttrs(); Conf.RelocModel = RelocationModel; Conf.CodeModel = codegen::getExplicitCodeModel(); - Conf.CGOptLevel = getCGOptLevel(); + std::optional CGOptLevelOrNone = + CodeGenOpt::getLevel(options::OptLevel); + assert(CGOptLevelOrNone); + Conf.CGOptLevel = *CGOptLevelOrNone; Conf.DisableVerify = options::DisableVerify; Conf.OptLevel = options::OptLevel; Conf.PTO.LoopVectorization = options::OptLevel > 1; diff --git a/llvm/tools/llc/llc.cpp b/llvm/tools/llc/llc.cpp --- a/llvm/tools/llc/llc.cpp +++ b/llvm/tools/llc/llc.cpp @@ -120,7 +120,7 @@ OptLevel("O", cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] " "(default = '-O2')"), - cl::Prefix, cl::init(' ')); + cl::Prefix, cl::init('2')); static cl::opt TargetTriple("mtriple", cl::desc("Override target triple for module")); @@ -472,16 +472,12 @@ bool SkipModule = CPUStr == "help" || (!MAttrs.empty() && MAttrs.front() == "help"); - CodeGenOpt::Level OLvl = CodeGenOpt::Default; - switch (OptLevel) { - default: + CodeGenOpt::Level OLvl; + if (auto Level = CodeGenOpt::parseLevel(OptLevel)) { + OLvl = *Level; + } else { WithColor::error(errs(), argv[0]) << "invalid optimization level.\n"; return 1; - case ' ': break; - case '0': OLvl = CodeGenOpt::None; break; - case '1': OLvl = CodeGenOpt::Less; break; - case '2': OLvl = CodeGenOpt::Default; break; - case '3': OLvl = CodeGenOpt::Aggressive; break; } // Parse 'none' or '$major.$minor'. Disallow -binutils-version=0 because we diff --git a/llvm/tools/lli/lli.cpp b/llvm/tools/lli/lli.cpp --- a/llvm/tools/lli/lli.cpp +++ b/llvm/tools/lli/lli.cpp @@ -174,7 +174,7 @@ cl::opt OptLevel("O", cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] " "(default = '-O2')"), - cl::Prefix, cl::init(' ')); + cl::Prefix, cl::init('2')); cl::opt TargetTriple("mtriple", cl::desc("Override target triple for module")); @@ -408,17 +408,10 @@ } CodeGenOpt::Level getOptLevel() { - switch (OptLevel) { - default: - WithColor::error(errs(), "lli") << "invalid optimization level.\n"; - exit(1); - case '0': return CodeGenOpt::None; - case '1': return CodeGenOpt::Less; - case ' ': - case '2': return CodeGenOpt::Default; - case '3': return CodeGenOpt::Aggressive; - } - llvm_unreachable("Unrecognized opt level."); + if (auto Level = CodeGenOpt::parseLevel(OptLevel)) + return *Level; + WithColor::error(errs(), "lli") << "invalid optimization level.\n"; + exit(1); } [[noreturn]] static void reportError(SMDiagnostic Err, const char *ProgName) { diff --git a/llvm/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp b/llvm/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp --- a/llvm/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp +++ b/llvm/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp @@ -42,7 +42,7 @@ OptLevel("O", cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] " "(default = '-O2')"), - cl::Prefix, cl::init(' ')); + cl::Prefix, cl::init('2')); static cl::opt TargetTriple("mtriple", cl::desc("Override target triple for module")); @@ -144,16 +144,12 @@ std::string CPUStr = codegen::getCPUStr(), FeaturesStr = codegen::getFeaturesStr(); - CodeGenOpt::Level OLvl = CodeGenOpt::Default; - switch (OptLevel) { - default: + CodeGenOpt::Level OLvl; + if (auto Level = CodeGenOpt::parseLevel(OptLevel)) { + OLvl = *Level; + } else { errs() << argv[0] << ": invalid optimization level.\n"; return 1; - case ' ': break; - case '0': OLvl = CodeGenOpt::None; break; - case '1': OLvl = CodeGenOpt::Less; break; - case '2': OLvl = CodeGenOpt::Default; break; - case '3': OLvl = CodeGenOpt::Aggressive; break; } TargetOptions Options = codegen::InitTargetOptionsFromCodeGenFlags(TheTriple); diff --git a/llvm/tools/llvm-lto2/llvm-lto2.cpp b/llvm/tools/llvm-lto2/llvm-lto2.cpp --- a/llvm/tools/llvm-lto2/llvm-lto2.cpp +++ b/llvm/tools/llvm-lto2/llvm-lto2.cpp @@ -306,20 +306,9 @@ Conf.Freestanding = EnableFreestanding; for (auto &PluginFN : PassPlugins) Conf.PassPlugins.push_back(PluginFN); - switch (CGOptLevel) { - case '0': - Conf.CGOptLevel = CodeGenOpt::None; - break; - case '1': - Conf.CGOptLevel = CodeGenOpt::Less; - break; - case '2': - Conf.CGOptLevel = CodeGenOpt::Default; - break; - case '3': - Conf.CGOptLevel = CodeGenOpt::Aggressive; - break; - default: + if (auto Level = CodeGenOpt::parseLevel(CGOptLevel)) { + Conf.CGOptLevel = *Level; + } else { llvm::errs() << "invalid cg optimization level: " << CGOptLevel << '\n'; return 1; } diff --git a/llvm/tools/lto/lto.cpp b/llvm/tools/lto/lto.cpp --- a/llvm/tools/lto/lto.cpp +++ b/llvm/tools/lto/lto.cpp @@ -528,20 +528,10 @@ if (OptLevel < '0' || OptLevel > '3') report_fatal_error("Optimization level must be between 0 and 3"); CodeGen->setOptLevel(OptLevel - '0'); - switch (OptLevel) { - case '0': - CodeGen->setCodeGenOptLevel(CodeGenOpt::None); - break; - case '1': - CodeGen->setCodeGenOptLevel(CodeGenOpt::Less); - break; - case '2': - CodeGen->setCodeGenOptLevel(CodeGenOpt::Default); - break; - case '3': - CodeGen->setCodeGenOptLevel(CodeGenOpt::Aggressive); - break; - } + std::optional CGOptLevelOrNone = + CodeGenOpt::getLevel(OptLevel - '0'); + assert(CGOptLevelOrNone); + CodeGen->setCodeGenOptLevel(*CGOptLevelOrNone); } return wrap(CodeGen); } diff --git a/openmp/libomptarget/plugins-nextgen/common/PluginInterface/JIT.cpp b/openmp/libomptarget/plugins-nextgen/common/PluginInterface/JIT.cpp --- a/openmp/libomptarget/plugins-nextgen/common/PluginInterface/JIT.cpp +++ b/openmp/libomptarget/plugins-nextgen/common/PluginInterface/JIT.cpp @@ -138,20 +138,6 @@ return createModuleFromMemoryBuffer(MB, Context); } -CodeGenOpt::Level getCGOptLevel(unsigned OptLevel) { - switch (OptLevel) { - case 0: - return CodeGenOpt::None; - case 1: - return CodeGenOpt::Less; - case 2: - return CodeGenOpt::Default; - case 3: - return CodeGenOpt::Aggressive; - } - llvm_unreachable("Invalid optimization level"); -} - OptimizationLevel getOptLevel(unsigned OptLevel) { switch (OptLevel) { case 0: @@ -169,7 +155,10 @@ Expected> createTargetMachine(Module &M, std::string CPU, unsigned OptLevel) { Triple TT(M.getTargetTriple()); - CodeGenOpt::Level CGOptLevel = getCGOptLevel(OptLevel); + std::optional CGOptLevelOrNone = + CodeGenOpt::getLevel(OptLevel); + assert(CGOptLevelOrNone); + CodeGenOpt::Level CGOptLevel = *CGOptLevelOrNone; std::string Msg; const Target *T = TargetRegistry::lookupTarget(M.getTargetTriple(), Msg);