Skip to content

Commit 25c0ea2

Browse files
committed
[NFC] Consolidate llvm::CodeGenOpt::Level handling
Add free functions llvm::CodeGenOpt::{getLevel,getID,parseLevel} to provide common implementations for functionality that has been duplicated in many places across the codebase. Differential Revision: https://reviews.llvm.org/D141968
1 parent 02fd002 commit 25c0ea2

File tree

13 files changed

+87
-167
lines changed

13 files changed

+87
-167
lines changed

clang/lib/CodeGen/BackendUtil.cpp

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -300,21 +300,6 @@ static TargetLibraryInfoImpl *createTLII(llvm::Triple &TargetTriple,
300300
return TLII;
301301
}
302302

303-
static CodeGenOpt::Level getCGOptLevel(const CodeGenOptions &CodeGenOpts) {
304-
switch (CodeGenOpts.OptimizationLevel) {
305-
default:
306-
llvm_unreachable("Invalid optimization level!");
307-
case 0:
308-
return CodeGenOpt::None;
309-
case 1:
310-
return CodeGenOpt::Less;
311-
case 2:
312-
return CodeGenOpt::Default; // O2/Os/Oz
313-
case 3:
314-
return CodeGenOpt::Aggressive;
315-
}
316-
}
317-
318303
static std::optional<llvm::CodeModel::Model>
319304
getCodeModel(const CodeGenOptions &CodeGenOpts) {
320305
unsigned CodeModel = llvm::StringSwitch<unsigned>(CodeGenOpts.CodeModel)
@@ -579,7 +564,10 @@ void EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {
579564
std::string FeaturesStr =
580565
llvm::join(TargetOpts.Features.begin(), TargetOpts.Features.end(), ",");
581566
llvm::Reloc::Model RM = CodeGenOpts.RelocationModel;
582-
CodeGenOpt::Level OptLevel = getCGOptLevel(CodeGenOpts);
567+
std::optional<CodeGenOpt::Level> OptLevelOrNone =
568+
CodeGenOpt::getLevel(CodeGenOpts.OptimizationLevel);
569+
assert(OptLevelOrNone && "Invalid optimization level!");
570+
CodeGenOpt::Level OptLevel = *OptLevelOrNone;
583571

584572
llvm::TargetOptions Options;
585573
if (!initTargetOptions(Diags, Options, CodeGenOpts, TargetOpts, LangOpts,
@@ -1161,7 +1149,10 @@ static void runThinLTOBackend(
11611149
Conf.CodeModel = getCodeModel(CGOpts);
11621150
Conf.MAttrs = TOpts.Features;
11631151
Conf.RelocModel = CGOpts.RelocationModel;
1164-
Conf.CGOptLevel = getCGOptLevel(CGOpts);
1152+
std::optional<CodeGenOpt::Level> OptLevelOrNone =
1153+
CodeGenOpt::getLevel(CGOpts.OptimizationLevel);
1154+
assert(OptLevelOrNone && "Invalid optimization level!");
1155+
Conf.CGOptLevel = *OptLevelOrNone;
11651156
Conf.OptLevel = CGOpts.OptimizationLevel;
11661157
initTargetOptions(Diags, Conf.Options, CGOpts, TOpts, LOpts, HeaderOpts);
11671158
Conf.SampleProfile = std::move(SampleProfile);

clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,11 @@ getOptLevel(const std::vector<const char *> &ExtraArgs) {
5454
CodeGenOpt::Level OLvl = CodeGenOpt::Default;
5555
for (auto &A : ExtraArgs) {
5656
if (A[0] == '-' && A[1] == 'O') {
57-
switch(A[2]) {
58-
case '0': OLvl = CodeGenOpt::None; break;
59-
case '1': OLvl = CodeGenOpt::Less; break;
60-
case '2': OLvl = CodeGenOpt::Default; break;
61-
case '3': OLvl = CodeGenOpt::Aggressive; break;
62-
default:
63-
errs() << "error: opt level must be between 0 and 3.\n";
64-
std::exit(1);
57+
if (auto Level = CodeGenOpt::parseLevel(A[2])) {
58+
OLvl = *Level;
59+
} else {
60+
errs() << "error: opt level must be between 0 and 3.\n";
61+
std::exit(1);
6562
}
6663
}
6764
}

clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -491,20 +491,6 @@ std::vector<std::string> getTargetFeatures(ArrayRef<OffloadFile> InputFiles) {
491491
return UnifiedFeatures;
492492
}
493493

494-
CodeGenOpt::Level getCGOptLevel(unsigned OptLevel) {
495-
switch (OptLevel) {
496-
case 0:
497-
return CodeGenOpt::None;
498-
case 1:
499-
return CodeGenOpt::Less;
500-
case 2:
501-
return CodeGenOpt::Default;
502-
case 3:
503-
return CodeGenOpt::Aggressive;
504-
}
505-
llvm_unreachable("Invalid optimization level");
506-
}
507-
508494
template <typename ModuleHook = function_ref<bool(size_t, const Module &)>>
509495
std::unique_ptr<lto::LTO> createLTO(
510496
const ArgList &Args, const std::vector<std::string> &Features,
@@ -522,7 +508,10 @@ std::unique_ptr<lto::LTO> createLTO(
522508

523509
StringRef OptLevel = Args.getLastArgValue(OPT_opt_level, "O2");
524510
Conf.MAttrs = Features;
525-
Conf.CGOptLevel = getCGOptLevel(OptLevel[1] - '0');
511+
std::optional<CodeGenOpt::Level> CGOptLevelOrNone =
512+
CodeGenOpt::parseLevel(OptLevel[1]);
513+
assert(CGOptLevelOrNone && "Invalid optimization level");
514+
Conf.CGOptLevel = *CGOptLevelOrNone;
526515
Conf.OptLevel = OptLevel[1] - '0';
527516
if (Conf.OptLevel > 0)
528517
Conf.UseDefaultPipeline = true;

flang/lib/Frontend/FrontendActions.cpp

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -572,22 +572,6 @@ void CodeGenAction::generateLLVMIR() {
572572
}
573573
}
574574

575-
static llvm::CodeGenOpt::Level
576-
getCGOptLevel(const Fortran::frontend::CodeGenOptions &opts) {
577-
switch (opts.OptimizationLevel) {
578-
default:
579-
llvm_unreachable("Invalid optimization level!");
580-
case 0:
581-
return llvm::CodeGenOpt::None;
582-
case 1:
583-
return llvm::CodeGenOpt::Less;
584-
case 2:
585-
return llvm::CodeGenOpt::Default;
586-
case 3:
587-
return llvm::CodeGenOpt::Aggressive;
588-
}
589-
}
590-
591575
void CodeGenAction::setUpTargetMachine() {
592576
CompilerInstance &ci = this->getInstance();
593577

@@ -602,7 +586,10 @@ void CodeGenAction::setUpTargetMachine() {
602586

603587
// Create `TargetMachine`
604588
const auto &CGOpts = ci.getInvocation().getCodeGenOpts();
605-
llvm::CodeGenOpt::Level OptLevel = getCGOptLevel(CGOpts);
589+
std::optional<llvm::CodeGenOpt::Level> OptLevelOrNone =
590+
CodeGenOpt::getLevel(CGOpts.OptimizationLevel);
591+
assert(OptLevelOrNone && "Invalid optimization level!");
592+
llvm::CodeGenOpt::Level OptLevel = *OptLevelOrNone;
606593
std::string featuresStr = llvm::join(targetOpts.featuresAsWritten.begin(),
607594
targetOpts.featuresAsWritten.end(), ",");
608595
tm.reset(theTarget->createTargetMachine(

llvm/include/llvm/Support/CodeGen.h

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
#ifndef LLVM_SUPPORT_CODEGEN_H
1515
#define LLVM_SUPPORT_CODEGEN_H
1616

17+
#include <cstdint>
18+
#include <optional>
19+
1720
namespace llvm {
1821

1922
// Relocation model types.
@@ -47,15 +50,37 @@ namespace llvm {
4750
};
4851
}
4952

50-
// Code generation optimization level.
5153
namespace CodeGenOpt {
52-
enum Level {
53-
None = 0, // -O0
54-
Less = 1, // -O1
55-
Default = 2, // -O2, -Os
56-
Aggressive = 3 // -O3
57-
};
54+
/// Type for the unique integer IDs of code generation optimization levels.
55+
using IDType = uint8_t;
56+
/// Code generation optimization level.
57+
enum Level : IDType {
58+
None = 0, ///< -O0
59+
Less = 1, ///< -O1
60+
Default = 2, ///< -O2, -Os
61+
Aggressive = 3 ///< -O3
62+
};
63+
/// Get the \c Level identified by the integer \p ID.
64+
///
65+
/// Returns std::nullopt if \p ID is invalid.
66+
inline std::optional<Level> getLevel(IDType ID) {
67+
if (ID < 0 || ID > 3)
68+
return std::nullopt;
69+
return static_cast<Level>(ID);
70+
}
71+
/// Get the integer \c ID of \p Level.
72+
inline IDType getID(CodeGenOpt::Level Level) {
73+
return static_cast<IDType>(Level);
74+
}
75+
/// Parse \p C as a single digit integer ID and get matching \c Level.
76+
///
77+
/// Returns std::nullopt if the input is not a valid digit or not a valid ID.
78+
inline std::optional<Level> parseLevel(char C) {
79+
if (C < '0')
80+
return std::nullopt;
81+
return getLevel(static_cast<IDType>(C - '0'));
5882
}
83+
} // namespace CodeGenOpt
5984

6085
/// These enums are meant to be passed into addPassesToEmitFile to indicate
6186
/// what type of file to emit, and returned by it to indicate what type of

llvm/lib/LTO/LTOCodeGenerator.cpp

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -200,21 +200,10 @@ void LTOCodeGenerator::setOptLevel(unsigned Level) {
200200
Config.OptLevel = Level;
201201
Config.PTO.LoopVectorization = Config.OptLevel > 1;
202202
Config.PTO.SLPVectorization = Config.OptLevel > 1;
203-
switch (Config.OptLevel) {
204-
case 0:
205-
Config.CGOptLevel = CodeGenOpt::None;
206-
return;
207-
case 1:
208-
Config.CGOptLevel = CodeGenOpt::Less;
209-
return;
210-
case 2:
211-
Config.CGOptLevel = CodeGenOpt::Default;
212-
return;
213-
case 3:
214-
Config.CGOptLevel = CodeGenOpt::Aggressive;
215-
return;
216-
}
217-
llvm_unreachable("Unknown optimization level!");
203+
std::optional<CodeGenOpt::Level> CGOptLevelOrNone =
204+
CodeGenOpt::getLevel(Config.OptLevel);
205+
assert(CGOptLevelOrNone && "Unknown optimization level!");
206+
Config.CGOptLevel = *CGOptLevelOrNone;
218207
}
219208

220209
bool LTOCodeGenerator::writeMergedModules(StringRef Path) {

llvm/tools/gold/gold-plugin.cpp

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -846,20 +846,6 @@ static int getOutputFileName(StringRef InFilename, bool TempOutFile,
846846
return FD;
847847
}
848848

849-
static CodeGenOpt::Level getCGOptLevel() {
850-
switch (options::OptLevel) {
851-
case 0:
852-
return CodeGenOpt::None;
853-
case 1:
854-
return CodeGenOpt::Less;
855-
case 2:
856-
return CodeGenOpt::Default;
857-
case 3:
858-
return CodeGenOpt::Aggressive;
859-
}
860-
llvm_unreachable("Invalid optimization level");
861-
}
862-
863849
/// Parse the thinlto_prefix_replace option into the \p OldPrefix and
864850
/// \p NewPrefix strings, if it was specified.
865851
static void getThinLTOOldAndNewPrefix(std::string &OldPrefix,
@@ -896,7 +882,10 @@ static std::unique_ptr<LTO> createLTO(IndexWriteCallback OnIndexWrite,
896882
Conf.MAttrs = codegen::getMAttrs();
897883
Conf.RelocModel = RelocationModel;
898884
Conf.CodeModel = codegen::getExplicitCodeModel();
899-
Conf.CGOptLevel = getCGOptLevel();
885+
std::optional<CodeGenOpt::Level> CGOptLevelOrNone =
886+
CodeGenOpt::getLevel(options::OptLevel);
887+
assert(CGOptLevelOrNone && "Invalid optimization level");
888+
Conf.CGOptLevel = *CGOptLevelOrNone;
900889
Conf.DisableVerify = options::DisableVerify;
901890
Conf.OptLevel = options::OptLevel;
902891
Conf.PTO.LoopVectorization = options::OptLevel > 1;

llvm/tools/llc/llc.cpp

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ static cl::opt<char>
120120
OptLevel("O",
121121
cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
122122
"(default = '-O2')"),
123-
cl::Prefix, cl::init(' '));
123+
cl::Prefix, cl::init('2'));
124124

125125
static cl::opt<std::string>
126126
TargetTriple("mtriple", cl::desc("Override target triple for module"));
@@ -472,16 +472,12 @@ static int compileModule(char **argv, LLVMContext &Context) {
472472
bool SkipModule =
473473
CPUStr == "help" || (!MAttrs.empty() && MAttrs.front() == "help");
474474

475-
CodeGenOpt::Level OLvl = CodeGenOpt::Default;
476-
switch (OptLevel) {
477-
default:
475+
CodeGenOpt::Level OLvl;
476+
if (auto Level = CodeGenOpt::parseLevel(OptLevel)) {
477+
OLvl = *Level;
478+
} else {
478479
WithColor::error(errs(), argv[0]) << "invalid optimization level.\n";
479480
return 1;
480-
case ' ': break;
481-
case '0': OLvl = CodeGenOpt::None; break;
482-
case '1': OLvl = CodeGenOpt::Less; break;
483-
case '2': OLvl = CodeGenOpt::Default; break;
484-
case '3': OLvl = CodeGenOpt::Aggressive; break;
485481
}
486482

487483
// Parse 'none' or '$major.$minor'. Disallow -binutils-version=0 because we

llvm/tools/lli/lli.cpp

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ namespace {
174174
cl::opt<char> OptLevel("O",
175175
cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
176176
"(default = '-O2')"),
177-
cl::Prefix, cl::init(' '));
177+
cl::Prefix, cl::init('2'));
178178

179179
cl::opt<std::string>
180180
TargetTriple("mtriple", cl::desc("Override target triple for module"));
@@ -408,17 +408,10 @@ static void addCygMingExtraModule(ExecutionEngine &EE, LLVMContext &Context,
408408
}
409409

410410
CodeGenOpt::Level getOptLevel() {
411-
switch (OptLevel) {
412-
default:
413-
WithColor::error(errs(), "lli") << "invalid optimization level.\n";
414-
exit(1);
415-
case '0': return CodeGenOpt::None;
416-
case '1': return CodeGenOpt::Less;
417-
case ' ':
418-
case '2': return CodeGenOpt::Default;
419-
case '3': return CodeGenOpt::Aggressive;
420-
}
421-
llvm_unreachable("Unrecognized opt level.");
411+
if (auto Level = CodeGenOpt::parseLevel(OptLevel))
412+
return *Level;
413+
WithColor::error(errs(), "lli") << "invalid optimization level.\n";
414+
exit(1);
422415
}
423416

424417
[[noreturn]] static void reportError(SMDiagnostic Err, const char *ProgName) {

llvm/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ static cl::opt<char>
4242
OptLevel("O",
4343
cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
4444
"(default = '-O2')"),
45-
cl::Prefix, cl::init(' '));
45+
cl::Prefix, cl::init('2'));
4646

4747
static cl::opt<std::string>
4848
TargetTriple("mtriple", cl::desc("Override target triple for module"));
@@ -144,16 +144,12 @@ extern "C" LLVM_ATTRIBUTE_USED int LLVMFuzzerInitialize(int *argc,
144144
std::string CPUStr = codegen::getCPUStr(),
145145
FeaturesStr = codegen::getFeaturesStr();
146146

147-
CodeGenOpt::Level OLvl = CodeGenOpt::Default;
148-
switch (OptLevel) {
149-
default:
147+
CodeGenOpt::Level OLvl;
148+
if (auto Level = CodeGenOpt::parseLevel(OptLevel)) {
149+
OLvl = *Level;
150+
} else {
150151
errs() << argv[0] << ": invalid optimization level.\n";
151152
return 1;
152-
case ' ': break;
153-
case '0': OLvl = CodeGenOpt::None; break;
154-
case '1': OLvl = CodeGenOpt::Less; break;
155-
case '2': OLvl = CodeGenOpt::Default; break;
156-
case '3': OLvl = CodeGenOpt::Aggressive; break;
157153
}
158154

159155
TargetOptions Options = codegen::InitTargetOptionsFromCodeGenFlags(TheTriple);

llvm/tools/llvm-lto2/llvm-lto2.cpp

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -306,20 +306,9 @@ static int run(int argc, char **argv) {
306306
Conf.Freestanding = EnableFreestanding;
307307
for (auto &PluginFN : PassPlugins)
308308
Conf.PassPlugins.push_back(PluginFN);
309-
switch (CGOptLevel) {
310-
case '0':
311-
Conf.CGOptLevel = CodeGenOpt::None;
312-
break;
313-
case '1':
314-
Conf.CGOptLevel = CodeGenOpt::Less;
315-
break;
316-
case '2':
317-
Conf.CGOptLevel = CodeGenOpt::Default;
318-
break;
319-
case '3':
320-
Conf.CGOptLevel = CodeGenOpt::Aggressive;
321-
break;
322-
default:
309+
if (auto Level = CodeGenOpt::parseLevel(CGOptLevel)) {
310+
Conf.CGOptLevel = *Level;
311+
} else {
323312
llvm::errs() << "invalid cg optimization level: " << CGOptLevel << '\n';
324313
return 1;
325314
}

llvm/tools/lto/lto.cpp

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -528,20 +528,10 @@ thinlto_code_gen_t thinlto_create_codegen(void) {
528528
if (OptLevel < '0' || OptLevel > '3')
529529
report_fatal_error("Optimization level must be between 0 and 3");
530530
CodeGen->setOptLevel(OptLevel - '0');
531-
switch (OptLevel) {
532-
case '0':
533-
CodeGen->setCodeGenOptLevel(CodeGenOpt::None);
534-
break;
535-
case '1':
536-
CodeGen->setCodeGenOptLevel(CodeGenOpt::Less);
537-
break;
538-
case '2':
539-
CodeGen->setCodeGenOptLevel(CodeGenOpt::Default);
540-
break;
541-
case '3':
542-
CodeGen->setCodeGenOptLevel(CodeGenOpt::Aggressive);
543-
break;
544-
}
531+
std::optional<CodeGenOpt::Level> CGOptLevelOrNone =
532+
CodeGenOpt::getLevel(OptLevel - '0');
533+
assert(CGOptLevelOrNone);
534+
CodeGen->setCodeGenOptLevel(*CGOptLevelOrNone);
545535
}
546536
return wrap(CodeGen);
547537
}

0 commit comments

Comments
 (0)