diff --git a/llvm/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h b/llvm/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h --- a/llvm/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h +++ b/llvm/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h @@ -226,6 +226,11 @@ OptLevel = (NewOptLevel > 3) ? 3 : NewOptLevel; } + // Enable or disable the new pass manager. + void setUseNewPM(unsigned Enabled) { + UseNewPM = Enabled; + } + /// Disable CodeGen, only run the stages till codegen and stop. The output /// will be bitcode. void disableCodeGen(bool Disable) { DisableCodeGen = Disable; } @@ -341,6 +346,9 @@ /// IR Optimization Level [0-3]. unsigned OptLevel = 3; + + /// Flag to indicate whether the new pass manager should be used for IR optimizations. + bool UseNewPM = LLVM_ENABLE_NEW_PASS_MANAGER; }; } #endif diff --git a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp --- a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp +++ b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp @@ -17,6 +17,7 @@ #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Analysis/ModuleSummaryAnalysis.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/ProfileSummaryInfo.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" @@ -41,6 +42,7 @@ #include "llvm/Support/CachePruning.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Error.h" +#include "llvm/Passes/PassBuilder.h" #include "llvm/Support/FileUtilities.h" #include "llvm/Support/Path.h" #include "llvm/Support/SHA1.h" @@ -262,6 +264,65 @@ PM.run(TheModule); } +static void optimizeModuleNewPM(Module &TheModule, TargetMachine &TM, + unsigned OptLevel, bool Freestanding, + ModuleSummaryIndex *Index) { + Optional PGOOpt; + LoopAnalysisManager LAM; + FunctionAnalysisManager FAM; + CGSCCAnalysisManager CGAM; + ModuleAnalysisManager MAM; + + PassInstrumentationCallbacks PIC; + PipelineTuningOptions PTO; + PTO.LoopVectorization = true; + PTO.SLPVectorization = true; + PassBuilder PB(&TM, PTO, PGOOpt, &PIC); + + std::unique_ptr TLII( + new TargetLibraryInfoImpl(Triple(TM.getTargetTriple()))); + if (Freestanding) + TLII->disableAllFunctions(); + FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); }); + + AAManager AA= PB.buildDefaultAAPipeline();; + // Register the AA manager first so that our version is the one used. + FAM.registerPass([&] { return std::move(AA); }); + + // Register all the basic analyses with the managers. + PB.registerModuleAnalyses(MAM); + PB.registerCGSCCAnalyses(CGAM); + PB.registerFunctionAnalyses(FAM); + PB.registerLoopAnalyses(LAM); + PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); + + ModulePassManager MPM; + + PassBuilder::OptimizationLevel OL; + + switch (OptLevel) { + default: + llvm_unreachable("Invalid optimization level"); + case 0: + OL = PassBuilder::OptimizationLevel::O0; + break; + case 1: + OL = PassBuilder::OptimizationLevel::O1; + break; + case 2: + OL = PassBuilder::OptimizationLevel::O2; + break; + case 3: + OL = PassBuilder::OptimizationLevel::O3; + break; + } + + MPM.addPass(PB.buildThinLTODefaultPipeline(OL, Index)); + + MPM.run(TheModule, MAM); +} + + static void addUsedSymbolToPreservedGUID(const lto::InputFile &File, DenseSet &PreservedGUID) { @@ -421,7 +482,7 @@ const GVSummaryMapTy &DefinedGlobals, const ThinLTOCodeGenerator::CachingOptions &CacheOptions, bool DisableCodeGen, StringRef SaveTempsDir, - bool Freestanding, unsigned OptLevel, unsigned count) { + bool Freestanding, unsigned OptLevel, unsigned count, bool UseNewPM) { // "Benchmark"-like optimization: single-source case bool SingleModule = (ModuleMap.size() == 1); @@ -461,7 +522,10 @@ saveTempBitcode(TheModule, SaveTempsDir, count, ".3.imported.bc"); } - optimizeModule(TheModule, TM, OptLevel, Freestanding, &Index); + if (UseNewPM) + optimizeModuleNewPM(TheModule, TM, OptLevel, Freestanding, &Index); + else + optimizeModule(TheModule, TM, OptLevel, Freestanding, &Index); saveTempBitcode(TheModule, SaveTempsDir, count, ".4.opt.bc"); @@ -1132,7 +1196,7 @@ *TheModule, *Index, ModuleMap, *TMBuilder.create(), ImportList, ExportList, GUIDPreservedSymbols, ModuleToDefinedGVSummaries[ModuleIdentifier], CacheOptions, - DisableCodeGen, SaveTempsDir, Freestanding, OptLevel, count); + DisableCodeGen, SaveTempsDir, Freestanding, OptLevel, count, UseNewPM); // Commit to the cache (if enabled) CacheEntry.write(*OutputBuffer); diff --git a/llvm/test/ThinLTO/X86/diagnostic-handler-remarks-with-hotness.ll b/llvm/test/ThinLTO/X86/diagnostic-handler-remarks-with-hotness.ll --- a/llvm/test/ThinLTO/X86/diagnostic-handler-remarks-with-hotness.ll +++ b/llvm/test/ThinLTO/X86/diagnostic-handler-remarks-with-hotness.ll @@ -5,6 +5,7 @@ ; with -lto-pass-remarks-with-hotness. ; RUN: llvm-lto -thinlto-action=run \ +; RUN -use-new-pm \ ; RUN: -lto-pass-remarks-output=%t.yaml \ ; RUN: -lto-pass-remarks-with-hotness \ ; RUN: -exported-symbol _func2 \ @@ -19,6 +20,21 @@ ; YAML1: --- !Passed ; YAML1-NEXT: Pass: inline ; YAML1-NEXT: Name: Inlined +; YAML1-NEXT: Function: foo +; YAML1-NEXT: Args: +; YAML1-NEXT: - Callee: bar +; YAML1-NEXT: - String: ' inlined into ' +; YAML1-NEXT: - Caller: foo +; YAML1-NEXT: - String: ' with ' +; YAML1-NEXT: - String: '(cost=' +; YAML1-NEXT: - Cost: '-30' +; YAML1-NEXT: - String: ', threshold=' +; YAML1-NEXT: - Threshold: '375' +; YAML1-NEXT: - String: ')' +; YAML1-NEXT: ... +; YAML1-NEXT: --- !Passed +; YAML1-NEXT: Pass: inline +; YAML1-NEXT: Name: Inlined ; YAML1-NEXT: Function: main ; YAML1-NEXT: Hotness: 50 ; YAML1-NEXT: Args: @@ -29,7 +45,7 @@ ; YAML1-NEXT: - String: '(cost=' ; YAML1-NEXT: - Cost: '-30' ; YAML1-NEXT: - String: ', threshold=' -; YAML1-NEXT: - Threshold: '337' +; YAML1-NEXT: - Threshold: '375' ; YAML1-NEXT: - String: ')' ; YAML1-NEXT: ... @@ -48,7 +64,7 @@ ; YAML2-NEXT: - String: '(cost=' ; YAML2-NEXT: - Cost: '-30' ; YAML2-NEXT: - String: ', threshold=' -; YAML2-NEXT: - Threshold: '337' +; YAML2-NEXT: - Threshold: '375' ; YAML2-NEXT: - String: ')' ; YAML2-NEXT: ... diff --git a/llvm/test/ThinLTO/X86/diagnostic-handler-remarks.ll b/llvm/test/ThinLTO/X86/diagnostic-handler-remarks.ll --- a/llvm/test/ThinLTO/X86/diagnostic-handler-remarks.ll +++ b/llvm/test/ThinLTO/X86/diagnostic-handler-remarks.ll @@ -4,6 +4,7 @@ ; Optimization records are collected regardless of the diagnostic handler ; RUN: rm -f %t.yaml.thin.0.yaml %t.yaml.thin.1.yaml ; RUN: llvm-lto -thinlto-action=run \ +; RUN: -use-new-pm \ ; RUN: -lto-pass-remarks-output=%t.yaml \ ; RUN: -lto-pass-remarks-filter=inline \ ; RUN: -lto-pass-remarks-format=yaml \ @@ -16,19 +17,19 @@ ; Verify that bar is imported and inlined into foo ; RUN: cat %t.yaml.thin.0.yaml | FileCheck %s -check-prefix=YAML1 -; YAML1: --- !Passed +; YAML1: --- !Passed ; YAML1-NEXT: Pass: inline ; YAML1-NEXT: Name: Inlined -; YAML1-NEXT: Function: main +; YAML1-NEXT: Function: foo ; YAML1-NEXT: Args: -; YAML1-NEXT: - Callee: foo +; YAML1-NEXT: - Callee: bar ; YAML1-NEXT: - String: ' inlined into ' -; YAML1-NEXT: - Caller: main +; YAML1-NEXT: - Caller: foo ; YAML1-NEXT: - String: ' with ' ; YAML1-NEXT: - String: '(cost=' ; YAML1-NEXT: - Cost: '-30' ; YAML1-NEXT: - String: ', threshold=' -; YAML1-NEXT: - Threshold: '337' +; YAML1-NEXT: - Threshold: '375' ; YAML1-NEXT: - String: ')' ; YAML1-NEXT: ... @@ -47,13 +48,14 @@ ; YAML2-NEXT: - String: '(cost=' ; YAML2-NEXT: - Cost: '-30' ; YAML2-NEXT: - String: ', threshold=' -; YAML2-NEXT: - Threshold: '337' +; YAML2-NEXT: - Threshold: '375' ; YAML2-NEXT: - String: ')' ; YAML2-NEXT: ... ; The file extension depends on the format of the remarks ; RUN: rm -f %t.bitstream.thin.0.bitstream %t.bitstream.thin.1.bitstream ; RUN: llvm-lto -thinlto-action=run \ +; RUN: -use-new-pm \ ; RUN: -lto-pass-remarks-output=%t.bitstream \ ; RUN: -lto-pass-remarks-filter=inline \ ; RUN: -lto-pass-remarks-format=bitstream \ diff --git a/llvm/tools/llvm-lto/llvm-lto.cpp b/llvm/tools/llvm-lto/llvm-lto.cpp --- a/llvm/tools/llvm-lto/llvm-lto.cpp +++ b/llvm/tools/llvm-lto/llvm-lto.cpp @@ -557,6 +557,7 @@ ThinGenerator.setCacheMaxSizeFiles(ThinLTOCacheMaxSizeFiles); ThinGenerator.setCacheMaxSizeBytes(ThinLTOCacheMaxSizeBytes); ThinGenerator.setFreestanding(EnableFreestanding); + ThinGenerator.setUseNewPM(UseNewPM); // Add all the exported symbols to the table of symbols to preserve. for (unsigned i = 0; i < ExportedSymbols.size(); ++i)