aeubanks updated this revision to Diff 386882.
aeubanks added a comment.

add more tests


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D113738/new/

https://reviews.llvm.org/D113738

Files:
  clang/lib/CodeGen/BackendUtil.cpp
  lld/COFF/Config.h
  lld/COFF/Driver.cpp
  lld/Common/Args.cpp
  lld/Common/CMakeLists.txt
  lld/ELF/Config.h
  lld/ELF/Driver.cpp
  lld/ELF/LTO.cpp
  lld/MachO/Config.h
  lld/MachO/Driver.cpp
  lld/include/lld/Common/Args.h
  lld/test/COFF/lto-opt-level.ll
  lld/test/ELF/lto/opt-level.ll
  lld/test/MachO/lto-opt-level.ll
  lld/test/wasm/lto/opt-level.ll
  lld/wasm/Config.h
  lld/wasm/Driver.cpp
  llvm/include/llvm/LTO/Config.h
  llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h
  llvm/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h
  llvm/include/llvm/Passes/OptimizationLevel.h
  llvm/lib/LTO/LTO.cpp
  llvm/lib/LTO/LTOBackend.cpp
  llvm/lib/LTO/LTOCodeGenerator.cpp
  llvm/lib/LTO/ThinLTOCodeGenerator.cpp
  llvm/test/tools/llvm-lto2/X86/opt-levels.ll
  llvm/test/tools/llvm-lto2/X86/slp-vectorize-pm.ll
  llvm/test/tools/lto/opt-level.ll
  llvm/tools/llvm-lto/llvm-lto.cpp
  llvm/tools/llvm-lto2/llvm-lto2.cpp
  llvm/tools/lto/lto.cpp
  llvm/utils/gn/secondary/lld/Common/BUILD.gn

Index: llvm/utils/gn/secondary/lld/Common/BUILD.gn
===================================================================
--- llvm/utils/gn/secondary/lld/Common/BUILD.gn
+++ llvm/utils/gn/secondary/lld/Common/BUILD.gn
@@ -27,6 +27,7 @@
     "//llvm/lib/IR",
     "//llvm/lib/MC",
     "//llvm/lib/Option",
+    "//llvm/lib/Passes",
     "//llvm/lib/Support",
     "//llvm/lib/Target",
   ]
Index: llvm/tools/lto/lto.cpp
===================================================================
--- llvm/tools/lto/lto.cpp
+++ llvm/tools/lto/lto.cpp
@@ -23,6 +23,7 @@
 #include "llvm/LTO/legacy/LTOCodeGenerator.h"
 #include "llvm/LTO/legacy/LTOModule.h"
 #include "llvm/LTO/legacy/ThinLTOCodeGenerator.h"
+#include "llvm/Passes/OptimizationLevel.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/TargetSelect.h"
@@ -34,12 +35,10 @@
 
 // extra command-line flags needed for LTOCodeGenerator
 static cl::opt<char>
-OptLevel("O",
-         cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
-                  "(default = '-O2')"),
-         cl::Prefix,
-         cl::ZeroOrMore,
-         cl::init('2'));
+    OptLevel("O",
+             cl::desc("Optimization level. [-O0, -O1, -O2, -O3, -Os, or -Oz] "
+                      "(default = '-O2')"),
+             cl::Prefix, cl::ZeroOrMore, cl::init('2'));
 
 static cl::opt<bool> EnableFreestanding(
     "lto-freestanding", cl::init(false),
@@ -152,9 +151,10 @@
   LTOCodeGenerator *CG = unwrap(cg);
   CG->setAttrs(codegen::getMAttrs());
 
-  if (OptLevel < '0' || OptLevel > '3')
-    report_fatal_error("Optimization level must be between 0 and 3");
-  CG->setOptLevel(OptLevel - '0');
+  Optional<OptimizationLevel> OL = OptimizationLevel::forChar(OptLevel);
+  if (!OL)
+    report_fatal_error("invalid optimization level: -O" + Twine(OptLevel));
+  CG->setOptLevel(*OL);
   CG->setFreestanding(EnableFreestanding);
   CG->setDisableVerify(DisableVerify);
 }
@@ -525,20 +525,21 @@
   CodeGen->setFreestanding(EnableFreestanding);
 
   if (OptLevel.getNumOccurrences()) {
-    if (OptLevel < '0' || OptLevel > '3')
-      report_fatal_error("Optimization level must be between 0 and 3");
-    CodeGen->setOptLevel(OptLevel - '0');
-    switch (OptLevel) {
-    case '0':
+    Optional<OptimizationLevel> OL = OptimizationLevel::forChar(OptLevel);
+    if (!OL)
+      report_fatal_error("Invalid optimization level: " + Twine(OptLevel));
+    CodeGen->setOptLevel(*OL);
+    switch (OL->getSpeedupLevel()) {
+    case 0:
       CodeGen->setCodeGenOptLevel(CodeGenOpt::None);
       break;
-    case '1':
+    case 1:
       CodeGen->setCodeGenOptLevel(CodeGenOpt::Less);
       break;
-    case '2':
+    case 2:
       CodeGen->setCodeGenOptLevel(CodeGenOpt::Default);
       break;
-    case '3':
+    case 3:
       CodeGen->setCodeGenOptLevel(CodeGenOpt::Aggressive);
       break;
     }
Index: llvm/tools/llvm-lto2/llvm-lto2.cpp
===================================================================
--- llvm/tools/llvm-lto2/llvm-lto2.cpp
+++ llvm/tools/llvm-lto2/llvm-lto2.cpp
@@ -20,6 +20,7 @@
 #include "llvm/Config/llvm-config.h"
 #include "llvm/IR/DiagnosticPrinter.h"
 #include "llvm/LTO/LTO.h"
+#include "llvm/Passes/OptimizationLevel.h"
 #include "llvm/Passes/PassPlugin.h"
 #include "llvm/Remarks/HotnessThresholdParser.h"
 #include "llvm/Support/Caching.h"
@@ -36,8 +37,9 @@
 static codegen::RegisterCodeGenFlags CGF;
 
 static cl::opt<char>
-    OptLevel("O", cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
-                           "(default = '-O2')"),
+    OptLevel("O",
+             cl::desc("Optimization level. [-O0, -O1, -O2, -O3, -Os, or -Oz] "
+                      "(default = '-O2')"),
              cl::Prefix, cl::ZeroOrMore, cl::init('2'));
 
 static cl::opt<char> CGOptLevel(
@@ -272,7 +274,12 @@
   Conf.OptPipeline = OptPipeline;
   Conf.AAPipeline = AAPipeline;
 
-  Conf.OptLevel = OptLevel - '0';
+  if (auto OL = OptimizationLevel::forChar(OptLevel)) {
+    Conf.OptLevel = *OL;
+  } else {
+    llvm::errs() << "invalid -O level: -O" << OptLevel << "\n";
+    return 1;
+  }
   Conf.UseNewPM = UseNewPM;
   Conf.Freestanding = EnableFreestanding;
   for (auto &PluginFN : PassPlugins)
@@ -301,8 +308,8 @@
   Conf.OverrideTriple = OverrideTriple;
   Conf.DefaultTriple = DefaultTriple;
   Conf.StatsFile = StatsFile;
-  Conf.PTO.LoopVectorization = Conf.OptLevel > 1;
-  Conf.PTO.SLPVectorization = Conf.OptLevel > 1;
+  Conf.PTO.LoopVectorization = Conf.OptLevel.getSpeedupLevel() > 1;
+  Conf.PTO.SLPVectorization = Conf.OptLevel.getSpeedupLevel() > 1;
 
   ThinBackend Backend;
   if (ThinLTODistributedIndexes)
Index: llvm/tools/llvm-lto/llvm-lto.cpp
===================================================================
--- llvm/tools/llvm-lto/llvm-lto.cpp
+++ llvm/tools/llvm-lto/llvm-lto.cpp
@@ -68,7 +68,7 @@
 
 static cl::opt<char>
     OptLevel("O",
-             cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
+             cl::desc("Optimization level. [-O0, -O1, -O2, -O3, -Os, or -Oz] "
                       "(default = '-O2')"),
              cl::Prefix, cl::ZeroOrMore, cl::init('2'), cl::cat(LTOCategory));
 
@@ -940,9 +940,6 @@
   cl::HideUnrelatedOptions({&LTOCategory, &getColorCategory()});
   cl::ParseCommandLineOptions(argc, argv, "llvm LTO linker\n");
 
-  if (OptLevel < '0' || OptLevel > '3')
-    error("optimization level must be between 0 and 3");
-
   // Initialize the configured targets.
   InitializeAllTargets();
   InitializeAllTargetMCs();
@@ -1065,7 +1062,11 @@
   // Set cpu and attrs strings for the default target/subtarget.
   CodeGen.setCpu(codegen::getMCPU());
 
-  CodeGen.setOptLevel(OptLevel - '0');
+  Optional<OptimizationLevel> OL = OptimizationLevel::forChar(OptLevel);
+  if (!OL)
+    error("invalid optimization level: -O" + Twine(OptLevel));
+  CodeGen.setOptLevel(*OL);
+
   CodeGen.setAttrs(codegen::getMAttrs());
 
   CodeGen.setUseNewPM(UseNewPM);
Index: llvm/test/tools/lto/opt-level.ll
===================================================================
--- llvm/test/tools/lto/opt-level.ll
+++ 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 -lSystem
 ; 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 -lSystem
+; 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 -lSystem
+; RUN: llvm-nm --no-llvm-bc %t.dylib | FileCheck --check-prefix=CHECK-O2 %s
 
 target triple = "x86_64-apple-macosx10.8.0"
 
Index: llvm/test/tools/llvm-lto2/X86/slp-vectorize-pm.ll
===================================================================
--- llvm/test/tools/llvm-lto2/X86/slp-vectorize-pm.ll
+++ llvm/test/tools/llvm-lto2/X86/slp-vectorize-pm.ll
@@ -17,6 +17,14 @@
 ; RUN:  -use-new-pm -save-temps 2>&1 | FileCheck %s --check-prefix=CHECK-O3-SLP
 ; RUN: llvm-dis %t5.o.1.4.opt.bc -o - | FileCheck %s --check-prefix=CHECK-O3-LPV
 
+; RUN: llvm-lto2 run %t1.bc -o %t5.o -Os -r %t1.bc,foo,plx -debug-pass-manager \
+; RUN:  -use-new-pm -save-temps 2>&1 | FileCheck %s --check-prefix=CHECK-O3-SLP
+; RUN: llvm-dis %t5.o.1.4.opt.bc -o - | FileCheck %s --check-prefix=CHECK-O3-LPV
+
+; RUN: llvm-lto2 run %t1.bc -o %t5.o -Oz -r %t1.bc,foo,plx -debug-pass-manager \
+; RUN:  -use-new-pm -save-temps 2>&1 | FileCheck %s --check-prefix=CHECK-O3-SLP
+; RUN: llvm-dis %t5.o.1.4.opt.bc -o - | FileCheck %s --check-prefix=CHECK-O3-LPV
+
 ; CHECK-O0-SLP-NOT: Running pass: SLPVectorizerPass
 ; CHECK-O1-SLP-NOT: Running pass: SLPVectorizerPass
 ; CHECK-O2-SLP: Running pass: SLPVectorizerPass
Index: llvm/test/tools/llvm-lto2/X86/opt-levels.ll
===================================================================
--- /dev/null
+++ llvm/test/tools/llvm-lto2/X86/opt-levels.ll
@@ -0,0 +1,42 @@
+; RUN: opt -module-summary %s -o %t1.bc
+
+; RUN: llvm-lto2 run %t1.bc -o %t5.o -O3 -r %t1.bc,c,plx -r %t1.bc,d,plx -r %t1.bc,f,plx -r %t1.bc,foo,plx \
+; RUN:  -use-new-pm -save-temps
+; RUN: llvm-dis %t5.o.1.4.opt.bc -o - | FileCheck %s --check-prefixes=O3,CHECK
+
+; RUN: llvm-lto2 run %t1.bc -o %t5.o -Os -r %t1.bc,c,plx -r %t1.bc,d,plx -r %t1.bc,f,plx -r %t1.bc,foo,plx \
+; RUN:  -use-new-pm -save-temps
+; RUN: llvm-dis %t5.o.1.4.opt.bc -o - | FileCheck %s --check-prefixes=OS,CHECK
+
+; RUN: llvm-lto2 run %t1.bc -o %t5.o -Oz -r %t1.bc,c,plx -r %t1.bc,d,plx -r %t1.bc,f,plx -r %t1.bc,foo,plx \
+; RUN:  -use-new-pm -save-temps
+; RUN: llvm-dis %t5.o.1.4.opt.bc -o - | FileCheck %s --check-prefixes=OZ,CHECK
+
+; CHECK-LABEL: define {{.*}}@foo
+; O3-NOT: call void @c
+; O3-NOT: call void @d
+; OS-NOT: call void @c
+; OS: call void @d
+; OZ: call void @c
+; OZ: call void @d
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @f()
+
+define void @c() "function-inline-cost"="10" {
+  call void @f()
+  ret void
+}
+
+define void @d() "function-inline-cost"="100" {
+  call void @f()
+  ret void
+}
+
+define void @foo(i32* %a) {
+  call void @c()
+  call void @d()
+  ret void
+}
\ No newline at end of file
Index: llvm/lib/LTO/ThinLTOCodeGenerator.cpp
===================================================================
--- llvm/lib/LTO/ThinLTOCodeGenerator.cpp
+++ llvm/lib/LTO/ThinLTOCodeGenerator.cpp
@@ -40,6 +40,7 @@
 #include "llvm/MC/SubtargetFeature.h"
 #include "llvm/MC/TargetRegistry.h"
 #include "llvm/Object/IRObjectFile.h"
+#include "llvm/Passes/OptimizationLevel.h"
 #include "llvm/Passes/PassBuilder.h"
 #include "llvm/Passes/StandardInstrumentations.h"
 #include "llvm/Remarks/HotnessThresholdParser.h"
@@ -238,7 +239,7 @@
 }
 
 static void optimizeModule(Module &TheModule, TargetMachine &TM,
-                           unsigned OptLevel, bool Freestanding,
+                           OptimizationLevel OptLevel, bool Freestanding,
                            ModuleSummaryIndex *Index) {
   // Populate the PassManager
   PassManagerBuilder PMB;
@@ -247,7 +248,8 @@
     PMB.LibraryInfo->disableAllFunctions();
   PMB.Inliner = createFunctionInliningPass();
   // FIXME: should get it from the bitcode?
-  PMB.OptLevel = OptLevel;
+  PMB.OptLevel = OptLevel.getSpeedupLevel();
+  PMB.SizeLevel = OptLevel.getSizeLevel();
   PMB.LoopVectorize = true;
   PMB.SLPVectorize = true;
   // Already did this in verifyLoadedModule().
@@ -268,7 +270,7 @@
 }
 
 static void optimizeModuleNewPM(Module &TheModule, TargetMachine &TM,
-                                unsigned OptLevel, bool Freestanding,
+                                OptimizationLevel OptLevel, bool Freestanding,
                                 bool DebugPassManager,
                                 ModuleSummaryIndex *Index) {
   Optional<PGOOptions> PGOOpt;
@@ -300,26 +302,7 @@
 
   ModulePassManager MPM;
 
-  OptimizationLevel OL;
-
-  switch (OptLevel) {
-  default:
-    llvm_unreachable("Invalid optimization level");
-  case 0:
-    OL = OptimizationLevel::O0;
-    break;
-  case 1:
-    OL = OptimizationLevel::O1;
-    break;
-  case 2:
-    OL = OptimizationLevel::O2;
-    break;
-  case 3:
-    OL = OptimizationLevel::O3;
-    break;
-  }
-
-  MPM.addPass(PB.buildThinLTODefaultPipeline(OL, Index));
+  MPM.addPass(PB.buildThinLTODefaultPipeline(OptLevel, Index));
 
   MPM.run(TheModule, MAM);
 }
@@ -394,7 +377,7 @@
       const FunctionImporter::ImportMapTy &ImportList,
       const FunctionImporter::ExportSetTy &ExportList,
       const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
-      const GVSummaryMapTy &DefinedGVSummaries, unsigned OptLevel,
+      const GVSummaryMapTy &DefinedGVSummaries, OptimizationLevel OptLevel,
       bool Freestanding, const TargetMachineBuilder &TMBuilder) {
     if (CachePath.empty())
       return;
@@ -483,8 +466,8 @@
                      const GVSummaryMapTy &DefinedGlobals,
                      const ThinLTOCodeGenerator::CachingOptions &CacheOptions,
                      bool DisableCodeGen, StringRef SaveTempsDir,
-                     bool Freestanding, unsigned OptLevel, unsigned count,
-                     bool UseNewPM, bool DebugPassManager) {
+                     bool Freestanding, OptimizationLevel OptLevel,
+                     unsigned count, bool UseNewPM, bool DebugPassManager) {
 
   // "Benchmark"-like optimization: single-source case
   bool SingleModule = (ModuleMap.size() == 1);
Index: llvm/lib/LTO/LTOCodeGenerator.cpp
===================================================================
--- llvm/lib/LTO/LTOCodeGenerator.cpp
+++ llvm/lib/LTO/LTOCodeGenerator.cpp
@@ -45,6 +45,7 @@
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/SubtargetFeature.h"
 #include "llvm/MC/TargetRegistry.h"
+#include "llvm/Passes/OptimizationLevel.h"
 #include "llvm/Remarks/HotnessThresholdParser.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
@@ -184,11 +185,11 @@
   llvm_unreachable("Unknown debug format!");
 }
 
-void LTOCodeGenerator::setOptLevel(unsigned Level) {
+void LTOCodeGenerator::setOptLevel(OptimizationLevel Level) {
   Config.OptLevel = Level;
-  Config.PTO.LoopVectorization = Config.OptLevel > 1;
-  Config.PTO.SLPVectorization = Config.OptLevel > 1;
-  switch (Config.OptLevel) {
+  Config.PTO.LoopVectorization = Config.OptLevel.getSpeedupLevel() > 1;
+  Config.PTO.SLPVectorization = Config.OptLevel.getSpeedupLevel() > 1;
+  switch (Config.OptLevel.getSpeedupLevel()) {
   case 0:
     Config.CGOptLevel = CodeGenOpt::None;
     return;
Index: llvm/lib/LTO/LTOBackend.cpp
===================================================================
--- llvm/lib/LTO/LTOBackend.cpp
+++ llvm/lib/LTO/LTOBackend.cpp
@@ -210,8 +210,7 @@
 }
 
 static void runNewPMPasses(const Config &Conf, Module &Mod, TargetMachine *TM,
-                           unsigned OptLevel, bool IsThinLTO,
-                           ModuleSummaryIndex *ExportSummary,
+                           bool IsThinLTO, ModuleSummaryIndex *ExportSummary,
                            const ModuleSummaryIndex *ImportSummary) {
   Optional<PGOOptions> PGOOpt;
   if (!Conf.SampleProfile.empty())
@@ -274,25 +273,6 @@
   if (!Conf.DisableVerify)
     MPM.addPass(VerifierPass());
 
-  OptimizationLevel OL;
-
-  switch (OptLevel) {
-  default:
-    llvm_unreachable("Invalid optimization level");
-  case 0:
-    OL = OptimizationLevel::O0;
-    break;
-  case 1:
-    OL = OptimizationLevel::O1;
-    break;
-  case 2:
-    OL = OptimizationLevel::O2;
-    break;
-  case 3:
-    OL = OptimizationLevel::O3;
-    break;
-  }
-
   // Parse a custom pipeline if asked to.
   if (!Conf.OptPipeline.empty()) {
     if (auto Err = PB.parsePassPipeline(MPM, Conf.OptPipeline)) {
@@ -300,9 +280,9 @@
                          Conf.OptPipeline + "': " + toString(std::move(Err)));
     }
   } else if (IsThinLTO) {
-    MPM.addPass(PB.buildThinLTODefaultPipeline(OL, ImportSummary));
+    MPM.addPass(PB.buildThinLTODefaultPipeline(Conf.OptLevel, ImportSummary));
   } else {
-    MPM.addPass(PB.buildLTODefaultPipeline(OL, ExportSummary));
+    MPM.addPass(PB.buildLTODefaultPipeline(Conf.OptLevel, ExportSummary));
   }
 
   if (!Conf.DisableVerify)
@@ -330,7 +310,8 @@
   PMB.VerifyOutput = !Conf.DisableVerify;
   PMB.LoopVectorize = true;
   PMB.SLPVectorize = true;
-  PMB.OptLevel = Conf.OptLevel;
+  PMB.OptLevel = Conf.OptLevel.getSpeedupLevel();
+  PMB.SizeLevel = Conf.OptLevel.getSizeLevel();
   PMB.PGOSampleUse = Conf.SampleProfile;
   PMB.EnablePGOCSInstrGen = Conf.RunCSIRInstr;
   if (!Conf.RunCSIRInstr && !Conf.CSIRProfile.empty()) {
@@ -367,8 +348,7 @@
   }
   // FIXME: Plumb the combined index into the new pass manager.
   if (Conf.UseNewPM || !Conf.OptPipeline.empty()) {
-    runNewPMPasses(Conf, Mod, TM, Conf.OptLevel, IsThinLTO, ExportSummary,
-                   ImportSummary);
+    runNewPMPasses(Conf, Mod, TM, IsThinLTO, ExportSummary, ImportSummary);
   } else {
     runOldPMPasses(Conf, Mod, TM, IsThinLTO, ExportSummary, ImportSummary);
   }
Index: llvm/lib/LTO/LTO.cpp
===================================================================
--- llvm/lib/LTO/LTO.cpp
+++ llvm/lib/LTO/LTO.cpp
@@ -132,7 +132,8 @@
     AddUnsigned(-1);
   AddUnsigned(Conf.CGOptLevel);
   AddUnsigned(Conf.CGFileType);
-  AddUnsigned(Conf.OptLevel);
+  AddUnsigned(Conf.OptLevel.getSizeLevel());
+  AddUnsigned(Conf.OptLevel.getSpeedupLevel());
   AddUnsigned(Conf.UseNewPM);
   AddUnsigned(Conf.Freestanding);
   AddString(Conf.OptPipeline);
@@ -1027,7 +1028,8 @@
     return It->second;
   };
   computeDeadSymbolsWithConstProp(ThinLTO.CombinedIndex, GUIDPreservedSymbols,
-                                  isPrevailing, Conf.OptLevel > 0);
+                                  isPrevailing,
+                                  Conf.OptLevel.getSpeedupLevel() > 0);
 
   // Setup output file to emit statistics.
   auto StatsFileOrErr = setupStatsFile(Conf.StatsFile);
@@ -1469,7 +1471,7 @@
   runWholeProgramDevirtOnIndex(ThinLTO.CombinedIndex, ExportedGUIDs,
                                LocalWPDTargetsMap);
 
-  if (Conf.OptLevel > 0)
+  if (Conf.OptLevel.getSpeedupLevel() > 0)
     ComputeCrossModuleImport(ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,
                              ImportLists, ExportLists);
 
Index: llvm/include/llvm/Passes/OptimizationLevel.h
===================================================================
--- llvm/include/llvm/Passes/OptimizationLevel.h
+++ llvm/include/llvm/Passes/OptimizationLevel.h
@@ -15,6 +15,7 @@
 #ifndef LLVM_PASSES_OPTIMIZATIONLEVEL_H
 #define LLVM_PASSES_OPTIMIZATIONLEVEL_H
 
+#include "llvm/ADT/Optional.h"
 #include <assert.h>
 
 namespace llvm {
@@ -35,6 +36,26 @@
 
 public:
   OptimizationLevel() = default;
+
+  static Optional<OptimizationLevel> forChar(char c) {
+    switch (c) {
+    case '0':
+      return O0;
+    case '1':
+      return O1;
+    case '2':
+      return O2;
+    case '3':
+      return O3;
+    case 's':
+      return Os;
+    case 'z':
+      return Oz;
+    default:
+      return Optional<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.
Index: llvm/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h
===================================================================
--- llvm/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h
+++ llvm/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h
@@ -20,6 +20,7 @@
 #include "llvm/ADT/Triple.h"
 #include "llvm/IR/ModuleSummaryIndex.h"
 #include "llvm/LTO/LTO.h"
+#include "llvm/Passes/OptimizationLevel.h"
 #include "llvm/Support/CachePruning.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -222,9 +223,7 @@
   }
 
   /// IR optimization level: from 0 to 3.
-  void setOptLevel(unsigned NewOptLevel) {
-    OptLevel = (NewOptLevel > 3) ? 3 : NewOptLevel;
-  }
+  void setOptLevel(OptimizationLevel NewOptLevel) { OptLevel = NewOptLevel; }
 
   /// Enable or disable the new pass manager.
   void setUseNewPM(unsigned Enabled) { UseNewPM = Enabled; }
@@ -346,7 +345,7 @@
   bool Freestanding = false;
 
   /// IR Optimization Level [0-3].
-  unsigned OptLevel = 3;
+  OptimizationLevel OptLevel = OptimizationLevel::O3;
 
   /// Flag to indicate whether the new pass manager should be used for IR
   /// optimizations.
Index: llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h
===================================================================
--- llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h
+++ llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h
@@ -43,6 +43,7 @@
 #include "llvm/IR/Module.h"
 #include "llvm/LTO/Config.h"
 #include "llvm/LTO/LTO.h"
+#include "llvm/Passes/OptimizationLevel.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/ToolOutputFile.h"
@@ -98,7 +99,7 @@
 
   void setCpu(StringRef MCpu) { Config.CPU = std::string(MCpu); }
   void setAttrs(std::vector<std::string> MAttrs) { Config.MAttrs = MAttrs; }
-  void setOptLevel(unsigned OptLevel);
+  void setOptLevel(OptimizationLevel OptLevel);
 
   void setShouldInternalize(bool Value) { ShouldInternalize = Value; }
   void setShouldEmbedUselists(bool Value) { ShouldEmbedUselists = Value; }
Index: llvm/include/llvm/LTO/Config.h
===================================================================
--- llvm/include/llvm/LTO/Config.h
+++ llvm/include/llvm/LTO/Config.h
@@ -20,6 +20,7 @@
 #include "llvm/IR/GlobalValue.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/LegacyPassManager.h"
+#include "llvm/Passes/OptimizationLevel.h"
 #include "llvm/Passes/PassBuilder.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Target/TargetOptions.h"
@@ -54,7 +55,7 @@
   Optional<CodeModel::Model> CodeModel = None;
   CodeGenOpt::Level CGOptLevel = CodeGenOpt::Default;
   CodeGenFileType CGFileType = CGFT_ObjectFile;
-  unsigned OptLevel = 2;
+  OptimizationLevel OptLevel = OptimizationLevel::O2;
   bool DisableVerify = false;
 
   /// Use the new pass manager
Index: lld/wasm/Driver.cpp
===================================================================
--- lld/wasm/Driver.cpp
+++ lld/wasm/Driver.cpp
@@ -372,7 +372,8 @@
   config->sharedMemory = args.hasArg(OPT_shared_memory);
   config->importTable = args.hasArg(OPT_import_table);
   config->importUndefined = args.hasArg(OPT_import_undefined);
-  config->ltoo = args::getInteger(args, OPT_lto_O, 2);
+  config->ltoo =
+      args::getOptLevel(args, OPT_lto_O, llvm::OptimizationLevel::O2);
   config->ltoPartitions = args::getInteger(args, OPT_lto_partitions, 1);
   config->ltoNewPassManager =
       args.hasFlag(OPT_no_lto_legacy_pass_manager, OPT_lto_legacy_pass_manager,
@@ -494,8 +495,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 (!get_threadpool_strategy(config->thinLTOJobs))
Index: lld/wasm/Config.h
===================================================================
--- lld/wasm/Config.h
+++ lld/wasm/Config.h
@@ -12,6 +12,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringSet.h"
 #include "llvm/BinaryFormat/Wasm.h"
+#include "llvm/Passes/OptimizationLevel.h"
 #include "llvm/Support/CachePruning.h"
 
 namespace lld {
@@ -57,7 +58,7 @@
   uint64_t maxMemory;
   uint64_t zStackSize;
   unsigned ltoPartitions;
-  unsigned ltoo;
+  llvm::OptimizationLevel ltoo = llvm::OptimizationLevel::O2;
   unsigned optimize;
   llvm::StringRef thinLTOJobs;
   bool ltoNewPassManager;
Index: lld/test/wasm/lto/opt-level.ll
===================================================================
--- lld/test/wasm/lto/opt-level.ll
+++ 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 %t2 -e main --lto-Os %t.o
+; RUN: obj2yaml %t2 | FileCheck --check-prefix=CHECK-O2 %s
+; RUN: wasm-ld -o %t2 -e main --lto-Oz %t.o
+; RUN: obj2yaml %t2 | FileCheck --check-prefix=CHECK-O2 %s
 ; RUN: wasm-ld -o %t2a -e main %t.o
 ; RUN: obj2yaml %t2a | FileCheck --check-prefix=CHECK-O2 %s
 
@@ -13,7 +17,7 @@
 
 ; RUN: not wasm-ld -o %t3 -e main --lto-O-1 %t.o 2>&1 | \
 ; RUN:   FileCheck --check-prefix=INVALIDNEGATIVE %s
-; INVALIDNEGATIVE: invalid optimization level for LTO: 4294967295
+; INVALIDNEGATIVE: invalid optimization level for LTO: -1
 
 target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128"
 target triple = "wasm32-unknown-unknown-wasm"
Index: lld/test/MachO/lto-opt-level.ll
===================================================================
--- lld/test/MachO/lto-opt-level.ll
+++ lld/test/MachO/lto-opt-level.ll
@@ -9,6 +9,12 @@
 ; RUN: %lld %t/test.o --lto-O2 -o %t/test
 ; RUN: llvm-nm -pa %t/test | FileCheck %s --check-prefixes=CHECK-O2
 
+; RUN: %lld %t/test.o --lto-Os -o %t/test
+; RUN: llvm-nm -pa %t/test | FileCheck %s --check-prefixes=CHECK-O2
+
+; RUN: %lld %t/test.o --lto-Oz -o %t/test
+; RUN: llvm-nm -pa %t/test | FileCheck %s --check-prefixes=CHECK-O2
+
 ; RUN: %lld %t/test.o -o %t/test
 ; RUN: llvm-nm -pa %t/test | FileCheck %s --check-prefixes=CHECK-O2
 
Index: lld/test/ELF/lto/opt-level.ll
===================================================================
--- lld/test/ELF/lto/opt-level.ll
+++ lld/test/ELF/lto/opt-level.ll
@@ -10,6 +10,10 @@
 ; RUN: llvm-nm %t2a | FileCheck --check-prefix=CHECK-O2 %s
 ; RUN: ld.lld -o %t2 -e main %t.o --plugin-opt O2
 ; RUN: llvm-nm %t2 | FileCheck --check-prefix=CHECK-O2 %s
+; RUN: ld.lld -o %t2 -e main --lto-Os %t.o
+; RUN: llvm-nm %t2 | FileCheck --check-prefix=CHECK-O2 %s
+; RUN: ld.lld -o %t2 -e main --lto-Oz %t.o
+; RUN: llvm-nm %t2 | FileCheck --check-prefix=CHECK-O2 %s
 
 ; Reject invalid optimization levels.
 ; RUN: not ld.lld -o /dev/null -e main --lto-O6 %t.o 2>&1 | \
@@ -19,14 +23,14 @@
 ; RUN:   FileCheck --check-prefix=INVALID1 %s
 ; RUN: not ld.lld -o /dev/null -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 /dev/null -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 /dev/null -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"
Index: lld/test/COFF/lto-opt-level.ll
===================================================================
--- lld/test/COFF/lto-opt-level.ll
+++ lld/test/COFF/lto-opt-level.ll
@@ -4,8 +4,17 @@
 ; 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:%t2.exe /entry:main /subsystem:console /opt:lldlto=s /lldmap:%t2.map %t.obj
+; RUN: FileCheck --check-prefix=CHECK-O2 %s < %t2.map
+; RUN: lld-link /out:%t2.exe /entry:main /subsystem:console /opt:lldlto=z /lldmap:%t2.map %t.obj
+; RUN: FileCheck --check-prefix=CHECK-O2 %s < %t2.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
+; RUN: not lld-link /out:%t2.exe /entry:main /subsystem:console /opt:lldlto=a /lldmap:%t2.map %t.obj 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR-A
+; RUN: not lld-link /out:%t2.exe /entry:main /subsystem:console /opt:lldlto=abc /lldmap:%t2.map %t.obj 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR-ABC
+
+; CHECK-ERROR-A: invalid optimization level: a
+; CHECK-ERROR-ABC: invalid optimization level: abc
 
 target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-pc-windows-msvc"
Index: lld/include/lld/Common/Args.h
===================================================================
--- lld/include/lld/Common/Args.h
+++ lld/include/lld/Common/Args.h
@@ -10,6 +10,7 @@
 #define LLD_ARGS_H
 
 #include "lld/Common/LLVM.h"
+#include "llvm/Passes/OptimizationLevel.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include <vector>
@@ -23,7 +24,9 @@
 namespace lld {
 namespace args {
 
-llvm::CodeGenOpt::Level getCGOptLevel(int optLevelLTO);
+llvm::CodeGenOpt::Level getCGOptLevel(llvm::OptimizationLevel optLevelLTO);
+llvm::OptimizationLevel getOptLevel(llvm::opt::InputArgList &args, unsigned key,
+                                    llvm::OptimizationLevel Default);
 
 int64_t getInteger(llvm::opt::InputArgList &args, unsigned key,
                    int64_t Default);
Index: lld/MachO/Driver.cpp
===================================================================
--- lld/MachO/Driver.cpp
+++ lld/MachO/Driver.cpp
@@ -1234,9 +1234,8 @@
   config->ltoNewPassManager =
       args.hasFlag(OPT_no_lto_legacy_pass_manager, OPT_lto_legacy_pass_manager,
                    LLVM_ENABLE_NEW_PASS_MANAGER);
-  config->ltoo = args::getInteger(args, OPT_lto_O, 2);
-  if (config->ltoo > 3)
-    error("--lto-O: invalid optimization level: " + Twine(config->ltoo));
+  config->ltoo =
+      args::getOptLevel(args, OPT_lto_O, llvm::OptimizationLevel::O2);
   config->thinLTOCacheDir = args.getLastArgValue(OPT_cache_path_lto);
   config->thinLTOCachePolicy = getLTOCachePolicy(args);
   config->runtimePaths = args::getStrings(args, OPT_rpath);
Index: lld/MachO/Config.h
===================================================================
--- lld/MachO/Config.h
+++ lld/MachO/Config.h
@@ -15,6 +15,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringSet.h"
 #include "llvm/BinaryFormat/MachO.h"
+#include "llvm/Passes/OptimizationLevel.h"
 #include "llvm/Support/CachePruning.h"
 #include "llvm/Support/GlobPattern.h"
 #include "llvm/Support/VersionTuple.h"
@@ -142,7 +143,7 @@
   llvm::StringRef ltoObjPath;
   llvm::StringRef thinLTOJobs;
   llvm::StringRef umbrella;
-  uint32_t ltoo = 2;
+  llvm::OptimizationLevel ltoo = llvm::OptimizationLevel::O2;
   llvm::CachePruningPolicy thinLTOCachePolicy;
   llvm::StringRef thinLTOCacheDir;
   bool deadStripDylibs = false;
Index: lld/ELF/LTO.cpp
===================================================================
--- lld/ELF/LTO.cpp
+++ lld/ELF/LTO.cpp
@@ -132,8 +132,8 @@
   c.MAttrs = getMAttrs();
   c.CGOptLevel = args::getCGOptLevel(config->ltoo);
 
-  c.PTO.LoopVectorization = c.OptLevel > 1;
-  c.PTO.SLPVectorization = c.OptLevel > 1;
+  c.PTO.LoopVectorization = c.OptLevel.getSpeedupLevel() > 1;
+  c.PTO.SLPVectorization = c.OptLevel.getSpeedupLevel() > 1;
 
   // Set up a custom pipeline if we've been asked to.
   c.OptPipeline = std::string(config->ltoNewPmPasses);
Index: lld/ELF/Driver.cpp
===================================================================
--- lld/ELF/Driver.cpp
+++ lld/ELF/Driver.cpp
@@ -49,6 +49,7 @@
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Config/llvm-config.h"
 #include "llvm/LTO/LTO.h"
+#include "llvm/Passes/OptimizationLevel.h"
 #include "llvm/Remarks/HotnessThresholdParser.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Compression.h"
@@ -1069,7 +1070,8 @@
   config->ltoWholeProgramVisibility =
       args.hasFlag(OPT_lto_whole_program_visibility,
                    OPT_no_lto_whole_program_visibility, false);
-  config->ltoo = args::getInteger(args, OPT_lto_O, 2);
+  config->ltoo =
+      args::getOptLevel(args, OPT_lto_O, llvm::OptimizationLevel::O2);
   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);
@@ -1274,8 +1276,6 @@
   if (auto *arg = args.getLastArg(OPT_thinlto_jobs))
     config->thinLTOJobs = arg->getValue();
 
-  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 (!get_threadpool_strategy(config->thinLTOJobs))
Index: lld/ELF/Config.h
===================================================================
--- lld/ELF/Config.h
+++ lld/ELF/Config.h
@@ -16,6 +16,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringSet.h"
 #include "llvm/BinaryFormat/ELF.h"
+#include "llvm/Passes/OptimizationLevel.h"
 #include "llvm/Support/CachePruning.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/Endian.h"
@@ -273,7 +274,7 @@
   uint64_t mipsGotSize;
   uint64_t zStackSize;
   unsigned ltoPartitions;
-  unsigned ltoo;
+  llvm::OptimizationLevel ltoo;
   unsigned optimize;
   StringRef thinLTOJobs;
   unsigned timeTraceGranularity;
Index: lld/Common/CMakeLists.txt
===================================================================
--- lld/Common/CMakeLists.txt
+++ lld/Common/CMakeLists.txt
@@ -49,6 +49,7 @@
   Demangle
   MC
   Option
+  Passes
   Support
   Target
 
Index: lld/Common/Args.cpp
===================================================================
--- lld/Common/Args.cpp
+++ lld/Common/Args.cpp
@@ -12,6 +12,7 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Option/ArgList.h"
+#include "llvm/Passes/OptimizationLevel.h"
 #include "llvm/Support/Path.h"
 
 using namespace llvm;
@@ -19,13 +20,27 @@
 
 // TODO(sbc): Remove this once CGOptLevel can be set completely based on bitcode
 // function metadata.
-CodeGenOpt::Level lld::args::getCGOptLevel(int optLevelLTO) {
-  if (optLevelLTO == 3)
+CodeGenOpt::Level lld::args::getCGOptLevel(OptimizationLevel optLevelLTO) {
+  if (optLevelLTO.getSpeedupLevel() == 3)
     return CodeGenOpt::Aggressive;
-  assert(optLevelLTO < 3);
   return CodeGenOpt::Default;
 }
 
+OptimizationLevel args::getOptLevel(llvm::opt::InputArgList &args,
+                                    unsigned int key,
+                                    llvm::OptimizationLevel Default) {
+  Optional<OptimizationLevel> OL;
+  if (opt::Arg *arg = args.getLastArg(key)) {
+    std::string lto = arg->getValue();
+    if (lto.size() == 1)
+      OL = llvm::OptimizationLevel::forChar(lto[0]);
+    if (!OL)
+      error("invalid optimization level for LTO: " + lto);
+    return OL.getValueOr(Default);
+  }
+  return Default;
+}
+
 static int64_t getInteger(opt::InputArgList &args, unsigned key,
                           int64_t Default, unsigned base) {
   auto *a = args.getLastArg(key);
Index: lld/COFF/Driver.cpp
===================================================================
--- lld/COFF/Driver.cpp
+++ lld/COFF/Driver.cpp
@@ -36,6 +36,7 @@
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Option/Option.h"
+#include "llvm/Passes/OptimizationLevel.h"
 #include "llvm/Support/BinaryStreamReader.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
@@ -1613,7 +1614,12 @@
         ltoDebugPM = false;
       } else if (s.startswith("lldlto=")) {
         StringRef optLevel = s.substr(7);
-        if (optLevel.getAsInteger(10, config->ltoo) || config->ltoo > 3)
+        Optional<OptimizationLevel> OL;
+        if (optLevel.size() == 1)
+          OL = OptimizationLevel::forChar(optLevel[0]);
+        if (OL)
+          config->ltoo = *OL;
+        else
           error("/opt:lldlto: invalid optimization level: " + optLevel);
       } else if (s.startswith("lldltojobs=")) {
         StringRef jobs = s.substr(11);
Index: lld/COFF/Config.h
===================================================================
--- lld/COFF/Config.h
+++ lld/COFF/Config.h
@@ -14,6 +14,7 @@
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Object/COFF.h"
+#include "llvm/Passes/OptimizationLevel.h"
 #include "llvm/Support/CachePruning.h"
 #include <cstdint>
 #include <map>
@@ -156,7 +157,7 @@
   bool noSEH = false;
 
   // Used for /opt:lldlto=N
-  unsigned ltoo = 2;
+  llvm::OptimizationLevel ltoo = llvm::OptimizationLevel::O2;
 
   // Used for /opt:lldltojobs=N
   std::string thinLTOJobs;
Index: clang/lib/CodeGen/BackendUtil.cpp
===================================================================
--- clang/lib/CodeGen/BackendUtil.cpp
+++ clang/lib/CodeGen/BackendUtil.cpp
@@ -1590,7 +1590,7 @@
   Conf.MAttrs = TOpts.Features;
   Conf.RelocModel = CGOpts.RelocationModel;
   Conf.CGOptLevel = getCGOptLevel(CGOpts);
-  Conf.OptLevel = CGOpts.OptimizationLevel;
+  Conf.OptLevel = mapToLevel(CGOpts);
   initTargetOptions(Diags, Conf.Options, CGOpts, TOpts, LOpts, HeaderOpts);
   Conf.SampleProfile = std::move(SampleProfile);
   Conf.PTO.LoopUnrolling = CGOpts.UnrollLoops;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to