Index: include/llvm/LTO/Config.h =================================================================== --- include/llvm/LTO/Config.h +++ include/llvm/LTO/Config.h @@ -78,6 +78,11 @@ /// Disable entirely the optimizer, including importing for ThinLTO bool CodeGenOnly = false; + /// If this field is set, the set of passes run in the middle-end optimizer + /// will be the one specified by the string. Only works with the new pass + /// manager as the old one doesn't have this ability. + std::string OptPipeline; + /// Setting this field will replace target triples in input files with this /// triple. std::string OverrideTriple; @@ -164,6 +169,7 @@ RelocModel(std::move(X.RelocModel)), CodeModel(std::move(X.CodeModel)), CGOptLevel(std::move(X.CGOptLevel)), OptLevel(std::move(X.OptLevel)), DisableVerify(std::move(X.DisableVerify)), + OptPipeline(std::move(X.OptPipeline)), OverrideTriple(std::move(X.OverrideTriple)), DefaultTriple(std::move(X.DefaultTriple)), ShouldDiscardValueNames(std::move(X.ShouldDiscardValueNames)), @@ -187,6 +193,7 @@ CGOptLevel = std::move(X.CGOptLevel); OptLevel = std::move(X.OptLevel); DisableVerify = std::move(X.DisableVerify); + OptPipeline = std::move(X.OptPipeline); OverrideTriple = std::move(X.OverrideTriple); DefaultTriple = std::move(X.DefaultTriple); ShouldDiscardValueNames = std::move(X.ShouldDiscardValueNames); Index: lib/LTO/LLVMBuild.txt =================================================================== --- lib/LTO/LLVMBuild.txt +++ lib/LTO/LLVMBuild.txt @@ -31,6 +31,7 @@ MC ObjCARC Object + Passes Scalar Support Target Index: lib/LTO/LTOBackend.cpp =================================================================== --- lib/LTO/LTOBackend.cpp +++ lib/LTO/LTOBackend.cpp @@ -15,12 +15,18 @@ //===----------------------------------------------------------------------===// #include "llvm/LTO/LTOBackend.h" +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/CGSCCPassManager.h" +#include "llvm/Analysis/LoopPassManager.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/IR/LegacyPassManager.h" +#include "llvm/IR/PassManager.h" +#include "llvm/IR/Verifier.h" #include "llvm/LTO/LTO.h" #include "llvm/MC/SubtargetFeature.h" +#include "llvm/Passes/PassBuilder.h" #include "llvm/Support/Error.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/TargetRegistry.h" @@ -136,10 +142,45 @@ passes.run(M); } +static void runNewPMCustomPasses(Config &C, Module &M, TargetMachine *TM) { + PassBuilder PB(TM); + AAManager AA; + LoopAnalysisManager LAM; + FunctionAnalysisManager FAM; + CGSCCAnalysisManager CGAM; + ModuleAnalysisManager MAM; + + // 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; + if (!C.DisableVerify) + MPM.addPass(VerifierPass()); + + // Now, add all the passes we've been requested to. + if (!PB.parsePassPipeline(MPM, C.OptPipeline)) + report_fatal_error("unable to parse pass pipeline description: " + + C.OptPipeline); + + if (!C.DisableVerify) + MPM.addPass(VerifierPass()); + MPM.run(M, MAM); +} + bool opt(Config &C, TargetMachine *TM, unsigned Task, Module &M, bool IsThinLto) { M.setDataLayout(TM->createDataLayout()); - runOldPMPasses(C, M, TM, IsThinLto); + if (C.OptPipeline.empty()) + runOldPMPasses(C, M, TM, IsThinLto); + else + runNewPMCustomPasses(C, M, TM); if (C.PostOptModuleHook && !C.PostOptModuleHook(Task, M)) return false;