diff --git a/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h b/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h index 3a3600ecccf..cb4a16cb5b7 100644 --- a/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h +++ b/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h @@ -38,7 +38,7 @@ struct TargetMachineBuilder { std::string MAttr; TargetOptions Options; Optional RelocModel; - CodeGenOpt::Level CGOptLevel = CodeGenOpt::Default; + CodeGenOpt::Level CGOptLevel = CodeGenOpt::Aggressive; std::unique_ptr create() const; }; @@ -199,6 +199,11 @@ public: TMBuilder.CGOptLevel = CGOptLevel; } + /// IR optimization level: from 0 to 3. + void setOptLevel(unsigned NewOptLevel) { + OptLevel = (NewOptLevel > 3) ? 3 : NewOptLevel; + } + /// Disable CodeGen, only run the stages till codegen and stop. The output /// will be bitcode. void disableCodeGen(bool Disable) { DisableCodeGen = Disable; } @@ -300,6 +305,9 @@ private: /// Flag to indicate that only the CodeGen will be performed, no cross-module /// importing or optimization. bool CodeGenOnly = false; + + /// IR Optimization Level [0-3]. + unsigned OptLevel = 3; }; } #endif diff --git a/lib/LTO/ThinLTOCodeGenerator.cpp b/lib/LTO/ThinLTOCodeGenerator.cpp index 2791efc69cd..880dc3dfae9 100644 --- a/lib/LTO/ThinLTOCodeGenerator.cpp +++ b/lib/LTO/ThinLTOCodeGenerator.cpp @@ -200,13 +200,14 @@ crossImportIntoModule(Module &TheModule, const ModuleSummaryIndex &Index, report_fatal_error("importFunctions failed"); } -static void optimizeModule(Module &TheModule, TargetMachine &TM) { +static void optimizeModule(Module &TheModule, TargetMachine &TM, + unsigned OptLevel) { // Populate the PassManager PassManagerBuilder PMB; PMB.LibraryInfo = new TargetLibraryInfoImpl(TM.getTargetTriple()); PMB.Inliner = createFunctionInliningPass(); // FIXME: should get it from the bitcode? - PMB.OptLevel = 3; + PMB.OptLevel = OptLevel; PMB.LoopVectorize = true; PMB.SLPVectorize = true; PMB.VerifyInput = true; @@ -383,7 +384,7 @@ ProcessThinLTOModule(Module &TheModule, ModuleSummaryIndex &Index, const GVSummaryMapTy &DefinedGlobals, const ThinLTOCodeGenerator::CachingOptions &CacheOptions, bool DisableCodeGen, StringRef SaveTempsDir, - unsigned count) { + unsigned OptLevel, unsigned count) { // "Benchmark"-like optimization: single-source case bool SingleModule = (ModuleMap.size() == 1); @@ -415,7 +416,7 @@ ProcessThinLTOModule(Module &TheModule, ModuleSummaryIndex &Index, saveTempBitcode(TheModule, SaveTempsDir, count, ".3.imported.bc"); } - optimizeModule(TheModule, TM); + optimizeModule(TheModule, TM, OptLevel); saveTempBitcode(TheModule, SaveTempsDir, count, ".4.opt.bc"); @@ -534,6 +535,7 @@ std::unique_ptr TargetMachineBuilder::create() const { SubtargetFeatures Features(MAttr); Features.getDefaultSubtargetFeatures(TheTriple); std::string FeatureStr = Features.getString(); + return std::unique_ptr(TheTarget->createTargetMachine( TheTriple.str(), MCpu, FeatureStr, Options, RelocModel, CodeModel::Default, CGOptLevel)); @@ -726,7 +728,7 @@ void ThinLTOCodeGenerator::optimize(Module &TheModule) { initTMBuilder(TMBuilder, Triple(TheModule.getTargetTriple())); // Optimize now - optimizeModule(TheModule, *TMBuilder.create()); + optimizeModule(TheModule, *TMBuilder.create(), OptLevel); } /** @@ -947,7 +949,7 @@ void ThinLTOCodeGenerator::run() { *TheModule, *Index, ModuleMap, *TMBuilder.create(), ImportList, ExportList, GUIDPreservedSymbols, ModuleToDefinedGVSummaries[ModuleIdentifier], CacheOptions, - DisableCodeGen, SaveTempsDir, count); + DisableCodeGen, SaveTempsDir, OptLevel, count); // Commit to the cache (if enabled) CacheEntry.write(*OutputBuffer); diff --git a/tools/lto/lto.cpp b/tools/lto/lto.cpp index aa61f2ad2ff..a1dd4ebbccb 100644 --- a/tools/lto/lto.cpp +++ b/tools/lto/lto.cpp @@ -465,6 +465,25 @@ thinlto_code_gen_t thinlto_create_codegen(void) { ThinLTOCodeGenerator *CodeGen = new ThinLTOCodeGenerator(); CodeGen->setTargetOptions(InitTargetOptionsFromCodeGenFlags()); + 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': + 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; + } + } return wrap(CodeGen); }