diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h --- a/lld/COFF/Config.h +++ b/lld/COFF/Config.h @@ -142,6 +142,7 @@ // Used for /opt:lldlto=N unsigned ltoo = 2; + unsigned ltoos = 0; // Used for /opt:lldltojobs=N unsigned thinLTOJobs = 0; diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -1406,8 +1406,8 @@ tailMerge = 0; } else if (s.startswith("lldlto=")) { StringRef optLevel = s.substr(7); - if (optLevel.getAsInteger(10, config->ltoo) || config->ltoo > 3) - error("/opt:lldlto: invalid optimization level: " + optLevel); + config->ltoo = CHECK(llvm::lto::getOptLevel(optLevel), "/opt:lldlto: "); + config->ltoos = check(llvm::lto::getSizeLevel(optLevel)); } else if (s.startswith("lldltojobs=")) { StringRef jobs = s.substr(11); if (jobs.getAsInteger(10, config->thinLTOJobs) || diff --git a/lld/COFF/LTO.cpp b/lld/COFF/LTO.cpp --- a/lld/COFF/LTO.cpp +++ b/lld/COFF/LTO.cpp @@ -79,6 +79,7 @@ c.DisableVerify = true; c.DiagHandler = diagnosticHandler; c.OptLevel = config->ltoo; + c.SizeLevel = config->ltoos; c.CPU = getCPUStr(); c.MAttrs = getMAttrs(); c.CGOptLevel = args::getCGOptLevel(config->ltoo); diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -238,6 +238,7 @@ uint64_t zStackSize; unsigned ltoPartitions; unsigned ltoo; + unsigned ltoos; unsigned optimize; unsigned thinLTOJobs; int32_t splitStackAdjustSize; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -895,7 +895,8 @@ config->ltoDebugPassManager = args.hasArg(OPT_lto_debug_pass_manager); config->ltoNewPassManager = args.hasArg(OPT_lto_new_pass_manager); config->ltoNewPmPasses = args.getLastArgValue(OPT_lto_newpm_passes); - config->ltoo = args::getInteger(args, OPT_lto_O, 2); + config->ltoo = check(llvm::lto::getOptLevel(args.getLastArg(OPT_lto_O), 2)); + config->ltoos = check(llvm::lto::getSizeLevel(args.getLastArg(OPT_lto_O), 0)); config->ltoObjPath = args.getLastArgValue(OPT_lto_obj_path_eq); config->ltoPartitions = args::getInteger(args, OPT_lto_partitions, 1); config->ltoSampleProfile = args.getLastArgValue(OPT_lto_sample_profile); @@ -1001,8 +1002,6 @@ for (auto *arg : args.filtered(OPT_mllvm)) parseClangOption(arg->getValue(), arg->getSpelling()); - if (config->ltoo > 3) - error("invalid optimization level for LTO: " + Twine(config->ltoo)); if (config->ltoPartitions == 0) error("--lto-partitions: number of threads must be > 0"); if (config->thinLTOJobs == 0) diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp --- a/lld/ELF/LTO.cpp +++ b/lld/ELF/LTO.cpp @@ -89,6 +89,7 @@ c.DisableVerify = config->disableVerify; c.DiagHandler = diagnosticHandler; c.OptLevel = config->ltoo; + c.SizeLevel = config->ltoos; c.CPU = getCPUStr(); c.MAttrs = getMAttrs(); c.CGOptLevel = args::getCGOptLevel(config->ltoo); diff --git a/lld/test/COFF/lto-opt-level.ll b/lld/test/COFF/lto-opt-level.ll --- a/lld/test/COFF/lto-opt-level.ll +++ b/lld/test/COFF/lto-opt-level.ll @@ -4,6 +4,10 @@ ; RUN: FileCheck --check-prefix=CHECK-O0 %s < %t0.map ; RUN: lld-link /out:%t2.exe /entry:main /subsystem:console /opt:lldlto=2 /lldmap:%t2.map %t.obj ; RUN: FileCheck --check-prefix=CHECK-O2 %s < %t2.map +; RUN: lld-link /out:%ts.exe /entry:main /subsystem:console /opt:lldlto=s /lldmap:%ts.map %t.obj +; RUN: FileCheck --check-prefix=CHECK-O2 %s < %ts.map +; RUN: lld-link /out:%tz.exe /entry:main /subsystem:console /opt:lldlto=z /lldmap:%tz.map %t.obj +; RUN: FileCheck --check-prefix=CHECK-O2 %s < %tz.map ; RUN: lld-link /out:%t2a.exe /entry:main /subsystem:console /lldmap:%t2a.map %t.obj ; RUN: FileCheck --check-prefix=CHECK-O2 %s < %t2a.map diff --git a/lld/test/ELF/lto/opt-level.ll b/lld/test/ELF/lto/opt-level.ll --- a/lld/test/ELF/lto/opt-level.ll +++ b/lld/test/ELF/lto/opt-level.ll @@ -6,6 +6,10 @@ ; RUN: llvm-nm %t0 | FileCheck --check-prefix=CHECK-O0 %s ; RUN: ld.lld -o %t2 -e main --lto-O2 %t.o ; RUN: llvm-nm %t2 | FileCheck --check-prefix=CHECK-O2 %s +; RUN: ld.lld -o %ts -e main --lto-Os %t.o +; RUN: llvm-nm %ts | FileCheck --check-prefix=CHECK-O2 %s +; RUN: ld.lld -o %tz -e main --lto-Oz %t.o +; RUN: llvm-nm %tz | FileCheck --check-prefix=CHECK-O2 %s ; RUN: ld.lld -o %t2a -e main %t.o ; RUN: llvm-nm %t2a | FileCheck --check-prefix=CHECK-O2 %s ; RUN: ld.lld -o %t2 -e main %t.o --plugin-opt O2 @@ -19,14 +23,14 @@ ; RUN: FileCheck --check-prefix=INVALID1 %s ; RUN: not ld.lld -o %t3 -e main --plugin-opt=Ofoo %t.o 2>&1 | \ ; RUN: FileCheck --check-prefix=INVALID2 %s -; INVALID2: --plugin-opt=Ofoo: number expected, but got 'foo' +; INVALID2: invalid optimization level for LTO: foo ; RUN: not ld.lld -o %t3 -e main --lto-O-1 %t.o 2>&1 | \ ; RUN: FileCheck --check-prefix=INVALIDNEGATIVE1 %s -; INVALIDNEGATIVE1: invalid optimization level for LTO: 4294967295 +; INVALIDNEGATIVE1: invalid optimization level for LTO: -1 ; RUN: not ld.lld -o %t3 -e main --plugin-opt=O-1 %t.o 2>&1 | \ ; RUN: FileCheck --check-prefix=INVALIDNEGATIVE2 %s -; INVALIDNEGATIVE2: invalid optimization level for LTO: 4294967295 +; INVALIDNEGATIVE2: invalid optimization level for LTO: -1 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/lld/test/wasm/lto/opt-level.ll b/lld/test/wasm/lto/opt-level.ll --- a/lld/test/wasm/lto/opt-level.ll +++ b/lld/test/wasm/lto/opt-level.ll @@ -3,6 +3,10 @@ ; RUN: obj2yaml %t0 | FileCheck --check-prefix=CHECK-O0 %s ; RUN: wasm-ld -o %t2 -e main --lto-O2 %t.o ; RUN: obj2yaml %t2 | FileCheck --check-prefix=CHECK-O2 %s +; RUN: wasm-ld -o %ts -e main --lto-Os %t.o +; RUN: obj2yaml %ts | FileCheck --check-prefix=CHECK-O2 %s +; RUN: wasm-ld -o %tz -e main --lto-Oz %t.o +; RUN: obj2yaml %tz | FileCheck --check-prefix=CHECK-O2 %s ; RUN: wasm-ld -o %t2a -e main %t.o ; RUN: obj2yaml %t2a | FileCheck --check-prefix=CHECK-O2 %s diff --git a/lld/wasm/Config.h b/lld/wasm/Config.h --- a/lld/wasm/Config.h +++ b/lld/wasm/Config.h @@ -52,6 +52,7 @@ uint32_t zStackSize; unsigned ltoPartitions; unsigned ltoo; + unsigned ltoos; unsigned optimize; unsigned thinLTOJobs; diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp --- a/lld/wasm/Driver.cpp +++ b/lld/wasm/Driver.cpp @@ -321,7 +321,8 @@ config->importMemory = args.hasArg(OPT_import_memory); config->sharedMemory = args.hasArg(OPT_shared_memory); config->importTable = args.hasArg(OPT_import_table); - config->ltoo = args::getInteger(args, OPT_lto_O, 2); + config->ltoo = check(llvm::lto::getOptLevel(args.getLastArg(OPT_lto_O), 2)); + config->ltoos = check(llvm::lto::getSizeLevel(args.getLastArg(OPT_lto_O), 0)); config->ltoPartitions = args::getInteger(args, OPT_lto_partitions, 1); config->optimize = args::getInteger(args, OPT_O, 0); config->outputFile = args.getLastArgValue(OPT_o); @@ -394,8 +395,6 @@ error("--compress-relocations is incompatible with output debug" " information. Please pass --strip-debug or --strip-all"); - if (config->ltoo > 3) - error("invalid optimization level for LTO: " + Twine(config->ltoo)); if (config->ltoPartitions == 0) error("--lto-partitions: number of threads must be > 0"); if (config->thinLTOJobs == 0) diff --git a/lld/wasm/LTO.cpp b/lld/wasm/LTO.cpp --- a/lld/wasm/LTO.cpp +++ b/lld/wasm/LTO.cpp @@ -50,6 +50,7 @@ c.DisableVerify = config->disableVerify; c.DiagHandler = diagnosticHandler; c.OptLevel = config->ltoo; + c.SizeLevel = config->ltoos; c.MAttrs = getMAttrs(); c.CGOptLevel = args::getCGOptLevel(config->ltoo); diff --git a/llvm/include/llvm/LTO/Config.h b/llvm/include/llvm/LTO/Config.h --- a/llvm/include/llvm/LTO/Config.h +++ b/llvm/include/llvm/LTO/Config.h @@ -43,6 +43,7 @@ CodeGenOpt::Level CGOptLevel = CodeGenOpt::Default; CodeGenFileType CGFileType = CGFT_ObjectFile; unsigned OptLevel = 2; + unsigned SizeLevel = 0; bool DisableVerify = false; /// Use the new pass manager diff --git a/llvm/include/llvm/LTO/LTO.h b/llvm/include/llvm/LTO/LTO.h --- a/llvm/include/llvm/LTO/LTO.h +++ b/llvm/include/llvm/LTO/LTO.h @@ -39,6 +39,9 @@ class Module; class Target; class raw_pwrite_stream; +namespace opt { +class Arg; +} /// Resolve linkage for prevailing symbols in the \p Index. Linkage changes /// recorded in the index and the ThinLTO backends must apply the changes to @@ -450,6 +453,27 @@ unsigned LinkerRedefined : 1; }; +class LTOOLevelError : public ErrorInfo { +public: + static char ID; + StringRef Level; + + LTOOLevelError(StringRef Level) : Level(Level) {} + + void log(raw_ostream &OS) const override { + OS << "invalid optimization level for LTO: " << Level; + } + + std::error_code convertToErrorCode() const override { + return llvm::inconvertibleErrorCode(); + } +}; + +Expected getOptLevel(StringRef OArg); +Expected getOptLevel(llvm::opt::Arg *OArg, unsigned Default); +Expected getSizeLevel(StringRef OArg); +Expected getSizeLevel(llvm::opt::Arg *OArg, unsigned Default); + } // namespace lto } // namespace llvm diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp --- a/llvm/lib/LTO/LTO.cpp +++ b/llvm/lib/LTO/LTO.cpp @@ -29,6 +29,7 @@ #include "llvm/LTO/SummaryBasedOptimizations.h" #include "llvm/Linker/IRMover.h" #include "llvm/Object/IRObjectFile.h" +#include "llvm/Option/Arg.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Error.h" #include "llvm/Support/ManagedStatic.h" @@ -136,6 +137,7 @@ AddUnsigned(Conf.CGOptLevel); AddUnsigned(Conf.CGFileType); AddUnsigned(Conf.OptLevel); + AddUnsigned(Conf.SizeLevel); AddUnsigned(Conf.UseNewPM); AddUnsigned(Conf.Freestanding); AddString(Conf.OptPipeline); @@ -1415,3 +1417,40 @@ StatsFile->keep(); return std::move(StatsFile); } + +char LTOOLevelError::ID; + +Expected lto::getOptLevel(StringRef S) { + if (S == "s" || S == "z" || S.empty()) + return 2; + + if (S == "g") + return 1; + + int Res; + if (S.getAsInteger(10, Res) || Res < 0 || Res > 3) + return make_error(S); + return Res; +} + +Expected lto::getOptLevel(opt::Arg *OArg, unsigned Default) { + if (!OArg) + return Default; + return lto::getOptLevel(OArg->getValue()); +} + +Expected lto::getSizeLevel(StringRef S) { + if (S[0] == 's') + return 1; + if (S[0] == 'z') + return 2; + if (S[0] >= '0' || S[0] <= '3' ) + return 0; + return make_error(S); +} + +Expected lto::getSizeLevel(opt::Arg *OArg, unsigned Default) { + if (!OArg) + return Default; + return lto::getSizeLevel(OArg->getValue()); +} diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp --- a/llvm/lib/LTO/LTOBackend.cpp +++ b/llvm/lib/LTO/LTOBackend.cpp @@ -150,9 +150,39 @@ CodeModel, Conf.CGOptLevel)); } +static PassBuilder::OptimizationLevel mapToLevel(const Config &Conf) { + switch (Conf.OptLevel) { + default: + llvm_unreachable("Invalid optimization level!"); + + case 0: + return PassBuilder::O0; + + case 1: + return PassBuilder::O1; + + case 2: + switch (Conf.SizeLevel) { + default: + llvm_unreachable("Invalid optimization level for size!"); + + case 0: + return PassBuilder::O2; + + case 1: + return PassBuilder::Os; + + case 2: + return PassBuilder::Oz; + } + + case 3: + return PassBuilder::O3; + } +} + static void runNewPMPasses(Config &Conf, Module &Mod, TargetMachine *TM, - unsigned OptLevel, bool IsThinLTO, - ModuleSummaryIndex *ExportSummary, + bool IsThinLTO, ModuleSummaryIndex *ExportSummary, const ModuleSummaryIndex *ImportSummary) { Optional PGOOpt; if (!Conf.SampleProfile.empty()) @@ -194,24 +224,7 @@ ModulePassManager MPM(Conf.DebugPassManager); // FIXME (davide): verify the input. - PassBuilder::OptimizationLevel OL; - - switch (OptLevel) { - default: - llvm_unreachable("Invalid optimization level"); - case 0: - OL = PassBuilder::O0; - break; - case 1: - OL = PassBuilder::O1; - break; - case 2: - OL = PassBuilder::O2; - break; - case 3: - OL = PassBuilder::O3; - break; - } + PassBuilder::OptimizationLevel OL = mapToLevel(Conf); if (IsThinLTO) MPM = PB.buildThinLTODefaultPipeline(OL, Conf.DebugPassManager, @@ -284,6 +297,7 @@ PMB.LoopVectorize = true; PMB.SLPVectorize = true; PMB.OptLevel = Conf.OptLevel; + PMB.SizeLevel = Conf.SizeLevel; PMB.PGOSampleUse = Conf.SampleProfile; PMB.EnablePGOCSInstrGen = Conf.RunCSIRInstr; if (!Conf.RunCSIRInstr && !Conf.CSIRProfile.empty()) { @@ -297,18 +311,17 @@ passes.run(Mod); } -bool opt(Config &Conf, TargetMachine *TM, unsigned Task, Module &Mod, +bool optimize(Config &Conf, TargetMachine *TM, unsigned Task, Module &Mod, bool IsThinLTO, ModuleSummaryIndex *ExportSummary, const ModuleSummaryIndex *ImportSummary) { // FIXME: Plumb the combined index into the new pass manager. if (!Conf.OptPipeline.empty()) runNewPMCustomPasses(Mod, TM, Conf.OptPipeline, Conf.AAPipeline, Conf.DisableVerify); - else if (Conf.UseNewPM) - runNewPMPasses(Conf, Mod, TM, Conf.OptLevel, IsThinLTO, ExportSummary, - ImportSummary); - else - runOldPMPasses(Conf, Mod, TM, IsThinLTO, ExportSummary, ImportSummary); + else { + auto runPasses = Conf.UseNewPM ? runNewPMPasses : runOldPMPasses; + runPasses(Conf, Mod, TM, IsThinLTO, ExportSummary, ImportSummary); + } return !Conf.PostOptModuleHook || Conf.PostOptModuleHook(Task, Mod); } @@ -443,7 +456,7 @@ auto DiagnosticOutputFile = std::move(*DiagFileOrErr); if (!C.CodeGenOnly) { - if (!opt(C, TM.get(), 0, *Mod, /*IsThinLTO=*/false, + if (!optimize(C, TM.get(), 0, *Mod, /*IsThinLTO=*/false, /*ExportSummary=*/&CombinedIndex, /*ImportSummary=*/nullptr)) return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); } @@ -538,7 +551,7 @@ if (Conf.PostImportModuleHook && !Conf.PostImportModuleHook(Task, Mod)) return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); - if (!opt(Conf, TM.get(), Task, Mod, /*IsThinLTO=*/true, + if (!optimize(Conf, TM.get(), Task, Mod, /*IsThinLTO=*/true, /*ExportSummary=*/nullptr, /*ImportSummary=*/&CombinedIndex)) return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); diff --git a/llvm/test/tools/gold/X86/opt-level.ll b/llvm/test/tools/gold/X86/opt-level.ll --- a/llvm/test/tools/gold/X86/opt-level.ll +++ b/llvm/test/tools/gold/X86/opt-level.ll @@ -11,6 +11,14 @@ ; RUN: -m elf_x86_64 \ ; RUN: -plugin-opt=O2 -r -o %t.o %t.bc ; RUN: llvm-dis < %t.o.0.4.opt.bc -o - | FileCheck --check-prefix=CHECK-O2 %s +; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext -plugin-opt=save-temps \ +; RUN: -m elf_x86_64 \ +; RUN: -plugin-opt=Os -r -o %t.o %t.bc +; RUN: llvm-dis < %t.o.0.4.opt.bc -o - | FileCheck --check-prefix=CHECK-O2 %s +; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext -plugin-opt=save-temps \ +; RUN: -m elf_x86_64 \ +; RUN: -plugin-opt=Oz -r -o %t.o %t.bc +; RUN: llvm-dis < %t.o.0.4.opt.bc -o - | FileCheck --check-prefix=CHECK-O2 %s ; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext -plugin-opt=save-temps \ ; RUN: -m elf_x86_64 --plugin-opt=new-pass-manager \ @@ -24,6 +32,14 @@ ; RUN: -m elf_x86_64 --plugin-opt=new-pass-manager \ ; RUN: -plugin-opt=O2 -r -o %t.o %t.bc ; RUN: llvm-dis < %t.o.0.4.opt.bc -o - | FileCheck --check-prefix=CHECK-O2 %s +; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext -plugin-opt=save-temps \ +; RUN: -m elf_x86_64 --plugin-opt=new-pass-manager \ +; RUN: -plugin-opt=Os -r -o %t.o %t.bc +; RUN: llvm-dis < %t.o.0.4.opt.bc -o - | FileCheck --check-prefix=CHECK-O2 %s +; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext -plugin-opt=save-temps \ +; RUN: -m elf_x86_64 --plugin-opt=new-pass-manager \ +; RUN: -plugin-opt=Oz -r -o %t.o %t.bc +; RUN: llvm-dis < %t.o.0.4.opt.bc -o - | FileCheck --check-prefix=CHECK-O2 %s ; CHECK-O0: define internal void @foo( ; CHECK-O1: define internal void @foo( diff --git a/llvm/test/tools/lto/opt-level.ll b/llvm/test/tools/lto/opt-level.ll --- a/llvm/test/tools/lto/opt-level.ll +++ b/llvm/test/tools/lto/opt-level.ll @@ -3,6 +3,10 @@ ; RUN: llvm-nm --no-llvm-bc %t.dylib | FileCheck --check-prefix=CHECK-O0 %s ; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -mllvm -O2 -o %t.dylib %t.o ; RUN: llvm-nm --no-llvm-bc %t.dylib | FileCheck --check-prefix=CHECK-O2 %s +; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -mllvm -Os -o %t.dylib %t.o +; RUN: llvm-nm --no-llvm-bc %t.dylib | FileCheck --check-prefix=CHECK-O2 %s +; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -mllvm -Oz -o %t.dylib %t.o +; RUN: llvm-nm --no-llvm-bc %t.dylib | FileCheck --check-prefix=CHECK-O2 %s target triple = "x86_64-apple-macosx10.8.0" 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 @@ -132,6 +132,7 @@ }; static OutputType TheOutputType = OT_NORMAL; static unsigned OptLevel = 2; + static unsigned SizeLevel = 0; // Default parallelism of 0 used to indicate that user did not specify. // Actual parallelism default value depends on implementation. // Currently only affects ThinLTO, where the default is @@ -261,9 +262,15 @@ } else if (opt.startswith("cache-policy=")) { cache_policy = opt.substr(strlen("cache-policy=")); } else if (opt.size() == 2 && opt[0] == 'O') { - if (opt[1] < '0' || opt[1] > '3') - message(LDPL_FATAL, "Optimization level must be between 0 and 3"); - OptLevel = opt[1] - '0'; + if (auto LevelOrErr = llvm::lto::getOptLevel(opt.substr(1, 1))) + OptLevel = *LevelOrErr; + else + message(LDPL_FATAL, toString(LevelOrErr.takeError()).c_str()); + + if (auto LevelOrErr = llvm::lto::getSizeLevel(opt.substr(1, 1))) + SizeLevel = *LevelOrErr; + else + message(LDPL_FATAL, toString(LevelOrErr.takeError()).c_str()); } else if (opt.startswith("jobs=")) { if (StringRef(opt_ + 5).getAsInteger(10, Parallelism)) message(LDPL_FATAL, "Invalid parallelism level: %s", opt_ + 5); @@ -860,6 +867,7 @@ Conf.CGOptLevel = getCGOptLevel(); Conf.DisableVerify = options::DisableVerify; Conf.OptLevel = options::OptLevel; + Conf.SizeLevel = options::SizeLevel; if (options::Parallelism) Backend = createInProcessThinBackend(options::Parallelism); if (options::thinlto_index_only) { 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 @@ -29,10 +29,11 @@ using namespace llvm; using namespace lto; -static cl::opt - OptLevel("O", cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] " - "(default = '-O2')"), - cl::Prefix, cl::ZeroOrMore, cl::init('2')); +static cl::opt + OptLevel("O", + cl::desc("Optimization level. [-O0, -O1, -O2, -Os, -Oz, or " + "-O3] (default = '-O2')"), + cl::Prefix, cl::ZeroOrMore, cl::init("2")); static cl::opt CGOptLevel( "cg-opt-level", @@ -244,7 +245,10 @@ Conf.OptPipeline = OptPipeline; Conf.AAPipeline = AAPipeline; - Conf.OptLevel = OptLevel - '0'; + Conf.OptLevel = + check(llvm::lto::getOptLevel(OptLevel), "invalid optimization level"); + Conf.SizeLevel = + check(llvm::lto::getSizeLevel(OptLevel), "invalid optimization level"); Conf.UseNewPM = UseNewPM; switch (CGOptLevel) { case '0':