diff options
Diffstat (limited to 'lib/Passes')
-rw-r--r-- | lib/Passes/LLVMBuild.txt | 2 | ||||
-rw-r--r-- | lib/Passes/Makefile | 14 | ||||
-rw-r--r-- | lib/Passes/PassBuilder.cpp | 423 | ||||
-rw-r--r-- | lib/Passes/PassRegistry.def | 123 |
4 files changed, 502 insertions, 60 deletions
diff --git a/lib/Passes/LLVMBuild.txt b/lib/Passes/LLVMBuild.txt index a752f42dcedd..4d8c7f85d3aa 100644 --- a/lib/Passes/LLVMBuild.txt +++ b/lib/Passes/LLVMBuild.txt @@ -19,4 +19,4 @@ type = Library name = Passes parent = Libraries -required_libraries = Analysis Core IPO InstCombine Scalar Support TransformUtils Vectorize +required_libraries = Analysis CodeGen Core IPO InstCombine Scalar Support TransformUtils Vectorize Instrumentation diff --git a/lib/Passes/Makefile b/lib/Passes/Makefile deleted file mode 100644 index 413dc5cf485b..000000000000 --- a/lib/Passes/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -##===- lib/Passes/Makefile ---------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../.. -LIBRARYNAME = LLVMPasses -BUILD_ARCHIVE := 1 - -include $(LEVEL)/Makefile.common diff --git a/lib/Passes/PassBuilder.cpp b/lib/Passes/PassBuilder.cpp index 8ba81f72a717..0e64df80f91f 100644 --- a/lib/Passes/PassBuilder.cpp +++ b/lib/Passes/PassBuilder.cpp @@ -16,112 +16,265 @@ //===----------------------------------------------------------------------===// #include "llvm/Passes/PassBuilder.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/AliasAnalysisEvaluator.h" #include "llvm/Analysis/AssumptionCache.h" +#include "llvm/Analysis/BasicAliasAnalysis.h" +#include "llvm/Analysis/BlockFrequencyInfo.h" +#include "llvm/Analysis/BlockFrequencyInfoImpl.h" +#include "llvm/Analysis/BranchProbabilityInfo.h" +#include "llvm/Analysis/CFLAndersAliasAnalysis.h" +#include "llvm/Analysis/CFLSteensAliasAnalysis.h" #include "llvm/Analysis/CGSCCPassManager.h" +#include "llvm/Analysis/CallGraph.h" +#include "llvm/Analysis/DemandedBits.h" +#include "llvm/Analysis/DependenceAnalysis.h" +#include "llvm/Analysis/DominanceFrontier.h" +#include "llvm/Analysis/GlobalsModRef.h" +#include "llvm/Analysis/IVUsers.h" #include "llvm/Analysis/LazyCallGraph.h" +#include "llvm/Analysis/LazyValueInfo.h" +#include "llvm/Analysis/LoopAccessAnalysis.h" #include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/MemoryDependenceAnalysis.h" +#include "llvm/Analysis/OptimizationDiagnosticInfo.h" +#include "llvm/Analysis/PostDominators.h" +#include "llvm/Analysis/ProfileSummaryInfo.h" +#include "llvm/Analysis/RegionInfo.h" #include "llvm/Analysis/ScalarEvolution.h" +#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" +#include "llvm/Analysis/ScopedNoAliasAA.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/Analysis/TypeBasedAliasAnalysis.h" +#include "llvm/CodeGen/PreISelIntrinsicLowering.h" +#include "llvm/CodeGen/UnreachableBlockElim.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/PassManager.h" #include "llvm/IR/Verifier.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/Regex.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Transforms/GCOVProfiler.h" +#include "llvm/Transforms/IPO/ConstantMerge.h" +#include "llvm/Transforms/IPO/CrossDSOCFI.h" +#include "llvm/Transforms/IPO/DeadArgumentElimination.h" +#include "llvm/Transforms/IPO/ElimAvailExtern.h" #include "llvm/Transforms/IPO/ForceFunctionAttrs.h" +#include "llvm/Transforms/IPO/FunctionAttrs.h" +#include "llvm/Transforms/IPO/GlobalDCE.h" +#include "llvm/Transforms/IPO/GlobalOpt.h" #include "llvm/Transforms/IPO/InferFunctionAttrs.h" +#include "llvm/Transforms/IPO/Internalize.h" +#include "llvm/Transforms/IPO/LowerTypeTests.h" +#include "llvm/Transforms/IPO/PartialInlining.h" +#include "llvm/Transforms/IPO/SCCP.h" #include "llvm/Transforms/IPO/StripDeadPrototypes.h" +#include "llvm/Transforms/IPO/WholeProgramDevirt.h" #include "llvm/Transforms/InstCombine/InstCombine.h" +#include "llvm/Transforms/InstrProfiling.h" +#include "llvm/Transforms/PGOInstrumentation.h" +#include "llvm/Transforms/SampleProfile.h" #include "llvm/Transforms/Scalar/ADCE.h" +#include "llvm/Transforms/Scalar/AlignmentFromAssumptions.h" +#include "llvm/Transforms/Scalar/BDCE.h" +#include "llvm/Transforms/Scalar/ConstantHoisting.h" +#include "llvm/Transforms/Scalar/CorrelatedValuePropagation.h" +#include "llvm/Transforms/Scalar/DCE.h" +#include "llvm/Transforms/Scalar/DeadStoreElimination.h" #include "llvm/Transforms/Scalar/EarlyCSE.h" +#include "llvm/Transforms/Scalar/Float2Int.h" +#include "llvm/Transforms/Scalar/GVN.h" +#include "llvm/Transforms/Scalar/GuardWidening.h" +#include "llvm/Transforms/Scalar/IndVarSimplify.h" +#include "llvm/Transforms/Scalar/JumpThreading.h" +#include "llvm/Transforms/Scalar/LICM.h" +#include "llvm/Transforms/Scalar/LoopDeletion.h" +#include "llvm/Transforms/Scalar/LoopDistribute.h" +#include "llvm/Transforms/Scalar/LoopIdiomRecognize.h" +#include "llvm/Transforms/Scalar/LoopInstSimplify.h" +#include "llvm/Transforms/Scalar/LoopRotation.h" +#include "llvm/Transforms/Scalar/LoopSimplifyCFG.h" +#include "llvm/Transforms/Scalar/LowerAtomic.h" #include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h" +#include "llvm/Transforms/Scalar/MemCpyOptimizer.h" +#include "llvm/Transforms/Scalar/MergedLoadStoreMotion.h" +#include "llvm/Transforms/Scalar/PartiallyInlineLibCalls.h" +#include "llvm/Transforms/Scalar/Reassociate.h" +#include "llvm/Transforms/Scalar/SCCP.h" #include "llvm/Transforms/Scalar/SROA.h" #include "llvm/Transforms/Scalar/SimplifyCFG.h" +#include "llvm/Transforms/Scalar/Sink.h" +#include "llvm/Transforms/Scalar/TailRecursionElimination.h" +#include "llvm/Transforms/Utils/AddDiscriminators.h" +#include "llvm/Transforms/Utils/LCSSA.h" +#include "llvm/Transforms/Utils/LoopSimplify.h" +#include "llvm/Transforms/Utils/Mem2Reg.h" +#include "llvm/Transforms/Utils/MemorySSA.h" +#include "llvm/Transforms/Utils/SimplifyInstructions.h" +#include "llvm/Transforms/Vectorize/LoopVectorize.h" +#include "llvm/Transforms/Vectorize/SLPVectorizer.h" + +#include <type_traits> using namespace llvm; +static Regex DefaultAliasRegex("^(default|lto-pre-link|lto)<(O[0123sz])>$"); + namespace { /// \brief No-op module pass which does nothing. struct NoOpModulePass { - PreservedAnalyses run(Module &M) { return PreservedAnalyses::all(); } + PreservedAnalyses run(Module &M, AnalysisManager<Module> &) { + return PreservedAnalyses::all(); + } static StringRef name() { return "NoOpModulePass"; } }; /// \brief No-op module analysis. -struct NoOpModuleAnalysis { +class NoOpModuleAnalysis : public AnalysisInfoMixin<NoOpModuleAnalysis> { + friend AnalysisInfoMixin<NoOpModuleAnalysis>; + static char PassID; + +public: struct Result {}; - Result run(Module &) { return Result(); } + Result run(Module &, AnalysisManager<Module> &) { return Result(); } static StringRef name() { return "NoOpModuleAnalysis"; } - static void *ID() { return (void *)&PassID; } -private: - static char PassID; }; -char NoOpModuleAnalysis::PassID; - /// \brief No-op CGSCC pass which does nothing. struct NoOpCGSCCPass { - PreservedAnalyses run(LazyCallGraph::SCC &C) { + PreservedAnalyses run(LazyCallGraph::SCC &C, + AnalysisManager<LazyCallGraph::SCC> &) { return PreservedAnalyses::all(); } static StringRef name() { return "NoOpCGSCCPass"; } }; /// \brief No-op CGSCC analysis. -struct NoOpCGSCCAnalysis { +class NoOpCGSCCAnalysis : public AnalysisInfoMixin<NoOpCGSCCAnalysis> { + friend AnalysisInfoMixin<NoOpCGSCCAnalysis>; + static char PassID; + +public: struct Result {}; - Result run(LazyCallGraph::SCC &) { return Result(); } + Result run(LazyCallGraph::SCC &, AnalysisManager<LazyCallGraph::SCC> &) { + return Result(); + } static StringRef name() { return "NoOpCGSCCAnalysis"; } - static void *ID() { return (void *)&PassID; } -private: - static char PassID; }; -char NoOpCGSCCAnalysis::PassID; - /// \brief No-op function pass which does nothing. struct NoOpFunctionPass { - PreservedAnalyses run(Function &F) { return PreservedAnalyses::all(); } + PreservedAnalyses run(Function &F, AnalysisManager<Function> &) { + return PreservedAnalyses::all(); + } static StringRef name() { return "NoOpFunctionPass"; } }; /// \brief No-op function analysis. -struct NoOpFunctionAnalysis { +class NoOpFunctionAnalysis : public AnalysisInfoMixin<NoOpFunctionAnalysis> { + friend AnalysisInfoMixin<NoOpFunctionAnalysis>; + static char PassID; + +public: struct Result {}; - Result run(Function &) { return Result(); } + Result run(Function &, AnalysisManager<Function> &) { return Result(); } static StringRef name() { return "NoOpFunctionAnalysis"; } - static void *ID() { return (void *)&PassID; } -private: +}; + +/// \brief No-op loop pass which does nothing. +struct NoOpLoopPass { + PreservedAnalyses run(Loop &L, AnalysisManager<Loop> &) { + return PreservedAnalyses::all(); + } + static StringRef name() { return "NoOpLoopPass"; } +}; + +/// \brief No-op loop analysis. +class NoOpLoopAnalysis : public AnalysisInfoMixin<NoOpLoopAnalysis> { + friend AnalysisInfoMixin<NoOpLoopAnalysis>; static char PassID; + +public: + struct Result {}; + Result run(Loop &, AnalysisManager<Loop> &) { return Result(); } + static StringRef name() { return "NoOpLoopAnalysis"; } }; +char NoOpModuleAnalysis::PassID; +char NoOpCGSCCAnalysis::PassID; char NoOpFunctionAnalysis::PassID; +char NoOpLoopAnalysis::PassID; } // End anonymous namespace. void PassBuilder::registerModuleAnalyses(ModuleAnalysisManager &MAM) { -#define MODULE_ANALYSIS(NAME, CREATE_PASS) \ - MAM.registerPass(CREATE_PASS); +#define MODULE_ANALYSIS(NAME, CREATE_PASS) \ + MAM.registerPass([&] { return CREATE_PASS; }); #include "PassRegistry.def" } void PassBuilder::registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM) { -#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \ - CGAM.registerPass(CREATE_PASS); +#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \ + CGAM.registerPass([&] { return CREATE_PASS; }); #include "PassRegistry.def" } void PassBuilder::registerFunctionAnalyses(FunctionAnalysisManager &FAM) { -#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \ - FAM.registerPass(CREATE_PASS); +#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \ + FAM.registerPass([&] { return CREATE_PASS; }); +#include "PassRegistry.def" +} + +void PassBuilder::registerLoopAnalyses(LoopAnalysisManager &LAM) { +#define LOOP_ANALYSIS(NAME, CREATE_PASS) \ + LAM.registerPass([&] { return CREATE_PASS; }); #include "PassRegistry.def" } +void PassBuilder::addPerModuleDefaultPipeline(ModulePassManager &MPM, + OptimizationLevel Level, + bool DebugLogging) { + // FIXME: Finish fleshing this out to match the legacy pipelines. + FunctionPassManager EarlyFPM(DebugLogging); + EarlyFPM.addPass(SimplifyCFGPass()); + EarlyFPM.addPass(SROA()); + EarlyFPM.addPass(EarlyCSEPass()); + EarlyFPM.addPass(LowerExpectIntrinsicPass()); + + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(EarlyFPM))); +} + +void PassBuilder::addLTOPreLinkDefaultPipeline(ModulePassManager &MPM, + OptimizationLevel Level, + bool DebugLogging) { + // FIXME: We should use a customized pre-link pipeline! + addPerModuleDefaultPipeline(MPM, Level, DebugLogging); +} + +void PassBuilder::addLTODefaultPipeline(ModulePassManager &MPM, + OptimizationLevel Level, + bool DebugLogging) { + // FIXME: Finish fleshing this out to match the legacy LTO pipelines. + FunctionPassManager LateFPM(DebugLogging); + LateFPM.addPass(InstCombinePass()); + LateFPM.addPass(SimplifyCFGPass()); + + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(LateFPM))); +} + #ifndef NDEBUG static bool isModulePassName(StringRef Name) { -#define MODULE_PASS(NAME, CREATE_PASS) if (Name == NAME) return true; + // Manually handle aliases for pre-configured pipeline fragments. + if (Name.startswith("default") || Name.startswith("lto")) + return DefaultAliasRegex.match(Name); + +#define MODULE_PASS(NAME, CREATE_PASS) \ + if (Name == NAME) \ + return true; #define MODULE_ANALYSIS(NAME, CREATE_PASS) \ if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \ return true; @@ -132,7 +285,9 @@ static bool isModulePassName(StringRef Name) { #endif static bool isCGSCCPassName(StringRef Name) { -#define CGSCC_PASS(NAME, CREATE_PASS) if (Name == NAME) return true; +#define CGSCC_PASS(NAME, CREATE_PASS) \ + if (Name == NAME) \ + return true; #define CGSCC_ANALYSIS(NAME, CREATE_PASS) \ if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \ return true; @@ -142,7 +297,9 @@ static bool isCGSCCPassName(StringRef Name) { } static bool isFunctionPassName(StringRef Name) { -#define FUNCTION_PASS(NAME, CREATE_PASS) if (Name == NAME) return true; +#define FUNCTION_PASS(NAME, CREATE_PASS) \ + if (Name == NAME) \ + return true; #define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \ if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \ return true; @@ -151,7 +308,46 @@ static bool isFunctionPassName(StringRef Name) { return false; } -bool PassBuilder::parseModulePassName(ModulePassManager &MPM, StringRef Name) { +static bool isLoopPassName(StringRef Name) { +#define LOOP_PASS(NAME, CREATE_PASS) \ + if (Name == NAME) \ + return true; +#define LOOP_ANALYSIS(NAME, CREATE_PASS) \ + if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \ + return true; +#include "PassRegistry.def" + + return false; +} + +bool PassBuilder::parseModulePassName(ModulePassManager &MPM, StringRef Name, + bool DebugLogging) { + // Manually handle aliases for pre-configured pipeline fragments. + if (Name.startswith("default") || Name.startswith("lto")) { + SmallVector<StringRef, 3> Matches; + if (!DefaultAliasRegex.match(Name, &Matches)) + return false; + assert(Matches.size() == 3 && "Must capture two matched strings!"); + + auto L = StringSwitch<OptimizationLevel>(Matches[2]) + .Case("O0", O0) + .Case("O1", O1) + .Case("O2", O2) + .Case("O3", O3) + .Case("Os", Os) + .Case("Oz", Oz); + + if (Matches[1] == "default") { + addPerModuleDefaultPipeline(MPM, L, DebugLogging); + } else if (Matches[1] == "lto-pre-link") { + addLTOPreLinkDefaultPipeline(MPM, L, DebugLogging); + } else { + assert(Matches[1] == "lto" && "Not one of the matched options!"); + addLTODefaultPipeline(MPM, L, DebugLogging); + } + return true; + } + #define MODULE_PASS(NAME, CREATE_PASS) \ if (Name == NAME) { \ MPM.addPass(CREATE_PASS); \ @@ -159,11 +355,13 @@ bool PassBuilder::parseModulePassName(ModulePassManager &MPM, StringRef Name) { } #define MODULE_ANALYSIS(NAME, CREATE_PASS) \ if (Name == "require<" NAME ">") { \ - MPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \ + MPM.addPass(RequireAnalysisPass< \ + std::remove_reference<decltype(CREATE_PASS)>::type>()); \ return true; \ } \ if (Name == "invalidate<" NAME ">") { \ - MPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \ + MPM.addPass(InvalidateAnalysisPass< \ + std::remove_reference<decltype(CREATE_PASS)>::type>()); \ return true; \ } #include "PassRegistry.def" @@ -179,11 +377,13 @@ bool PassBuilder::parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name) { } #define CGSCC_ANALYSIS(NAME, CREATE_PASS) \ if (Name == "require<" NAME ">") { \ - CGPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \ + CGPM.addPass(RequireAnalysisPass< \ + std::remove_reference<decltype(CREATE_PASS)>::type>()); \ return true; \ } \ if (Name == "invalidate<" NAME ">") { \ - CGPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \ + CGPM.addPass(InvalidateAnalysisPass< \ + std::remove_reference<decltype(CREATE_PASS)>::type>()); \ return true; \ } #include "PassRegistry.def" @@ -200,11 +400,53 @@ bool PassBuilder::parseFunctionPassName(FunctionPassManager &FPM, } #define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \ if (Name == "require<" NAME ">") { \ - FPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \ + FPM.addPass(RequireAnalysisPass< \ + std::remove_reference<decltype(CREATE_PASS)>::type>()); \ + return true; \ + } \ + if (Name == "invalidate<" NAME ">") { \ + FPM.addPass(InvalidateAnalysisPass< \ + std::remove_reference<decltype(CREATE_PASS)>::type>()); \ + return true; \ + } +#include "PassRegistry.def" + + return false; +} + +bool PassBuilder::parseLoopPassName(LoopPassManager &FPM, StringRef Name) { +#define LOOP_PASS(NAME, CREATE_PASS) \ + if (Name == NAME) { \ + FPM.addPass(CREATE_PASS); \ + return true; \ + } +#define LOOP_ANALYSIS(NAME, CREATE_PASS) \ + if (Name == "require<" NAME ">") { \ + FPM.addPass(RequireAnalysisPass< \ + std::remove_reference<decltype(CREATE_PASS)>::type>()); \ return true; \ } \ if (Name == "invalidate<" NAME ">") { \ - FPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \ + FPM.addPass(InvalidateAnalysisPass< \ + std::remove_reference<decltype(CREATE_PASS)>::type>()); \ + return true; \ + } +#include "PassRegistry.def" + + return false; +} + +bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) { +#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \ + if (Name == NAME) { \ + AA.registerModuleAnalysis< \ + std::remove_reference<decltype(CREATE_PASS)>::type>(); \ + return true; \ + } +#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \ + if (Name == NAME) { \ + AA.registerFunctionAnalysis< \ + std::remove_reference<decltype(CREATE_PASS)>::type>(); \ return true; \ } #include "PassRegistry.def" @@ -212,6 +454,45 @@ bool PassBuilder::parseFunctionPassName(FunctionPassManager &FPM, return false; } +bool PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM, + StringRef &PipelineText, + bool VerifyEachPass, + bool DebugLogging) { + for (;;) { + // Parse nested pass managers by recursing. + if (PipelineText.startswith("loop(")) { + LoopPassManager NestedLPM(DebugLogging); + + // Parse the inner pipeline inte the nested manager. + PipelineText = PipelineText.substr(strlen("loop(")); + if (!parseLoopPassPipeline(NestedLPM, PipelineText, VerifyEachPass, + DebugLogging) || + PipelineText.empty()) + return false; + assert(PipelineText[0] == ')'); + PipelineText = PipelineText.substr(1); + + // Add the nested pass manager with the appropriate adaptor. + LPM.addPass(std::move(NestedLPM)); + } else { + // Otherwise try to parse a pass name. + size_t End = PipelineText.find_first_of(",)"); + if (!parseLoopPassName(LPM, PipelineText.substr(0, End))) + return false; + // TODO: Ideally, we would run a LoopVerifierPass() here in the + // VerifyEachPass case, but we don't have such a verifier yet. + + PipelineText = PipelineText.substr(End); + } + + if (PipelineText.empty() || PipelineText[0] == ')') + return true; + + assert(PipelineText[0] == ','); + PipelineText = PipelineText.substr(1); + } +} + bool PassBuilder::parseFunctionPassPipeline(FunctionPassManager &FPM, StringRef &PipelineText, bool VerifyEachPass, @@ -232,6 +513,20 @@ bool PassBuilder::parseFunctionPassPipeline(FunctionPassManager &FPM, // Add the nested pass manager with the appropriate adaptor. FPM.addPass(std::move(NestedFPM)); + } else if (PipelineText.startswith("loop(")) { + LoopPassManager NestedLPM(DebugLogging); + + // Parse the inner pipeline inte the nested manager. + PipelineText = PipelineText.substr(strlen("loop(")); + if (!parseLoopPassPipeline(NestedLPM, PipelineText, VerifyEachPass, + DebugLogging) || + PipelineText.empty()) + return false; + assert(PipelineText[0] == ')'); + PipelineText = PipelineText.substr(1); + + // Add the nested pass manager with the appropriate adaptor. + FPM.addPass(createFunctionToLoopPassAdaptor(std::move(NestedLPM))); } else { // Otherwise try to parse a pass name. size_t End = PipelineText.find_first_of(",)"); @@ -284,7 +579,8 @@ bool PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM, PipelineText = PipelineText.substr(1); // Add the nested pass manager with the appropriate adaptor. - CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(NestedFPM))); + CGPM.addPass( + createCGSCCToFunctionPassAdaptor(std::move(NestedFPM), DebugLogging)); } else { // Otherwise try to parse a pass name. size_t End = PipelineText.find_first_of(",)"); @@ -303,6 +599,20 @@ bool PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM, } } +void PassBuilder::crossRegisterProxies(LoopAnalysisManager &LAM, + FunctionAnalysisManager &FAM, + CGSCCAnalysisManager &CGAM, + ModuleAnalysisManager &MAM) { + MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); }); + MAM.registerPass([&] { return CGSCCAnalysisManagerModuleProxy(CGAM); }); + CGAM.registerPass([&] { return FunctionAnalysisManagerCGSCCProxy(FAM); }); + CGAM.registerPass([&] { return ModuleAnalysisManagerCGSCCProxy(MAM); }); + FAM.registerPass([&] { return CGSCCAnalysisManagerFunctionProxy(CGAM); }); + FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); }); + FAM.registerPass([&] { return LoopAnalysisManagerFunctionProxy(LAM); }); + LAM.registerPass([&] { return FunctionAnalysisManagerLoopProxy(FAM); }); +} + bool PassBuilder::parseModulePassPipeline(ModulePassManager &MPM, StringRef &PipelineText, bool VerifyEachPass, @@ -336,8 +646,8 @@ bool PassBuilder::parseModulePassPipeline(ModulePassManager &MPM, PipelineText = PipelineText.substr(1); // Add the nested pass manager with the appropriate adaptor. - MPM.addPass( - createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM))); + MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM), + DebugLogging)); } else if (PipelineText.startswith("function(")) { FunctionPassManager NestedFPM(DebugLogging); @@ -355,7 +665,7 @@ bool PassBuilder::parseModulePassPipeline(ModulePassManager &MPM, } else { // Otherwise try to parse a pass name. size_t End = PipelineText.find_first_of(",)"); - if (!parseModulePassName(MPM, PipelineText.substr(0, End))) + if (!parseModulePassName(MPM, PipelineText.substr(0, End), DebugLogging)) return false; if (VerifyEachPass) MPM.addPass(VerifierPass()); @@ -392,19 +702,20 @@ bool PassBuilder::parsePassPipeline(ModulePassManager &MPM, // If this looks like a CGSCC pass, parse the whole thing as a CGSCC // pipeline. - if (isCGSCCPassName(FirstName)) { + if (PipelineText.startswith("cgscc(") || isCGSCCPassName(FirstName)) { CGSCCPassManager CGPM(DebugLogging); if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass, DebugLogging) || !PipelineText.empty()) return false; - MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM))); + MPM.addPass( + createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM), DebugLogging)); return true; } // Similarly, if this looks like a Function pass, parse the whole thing as // a Function pipelien. - if (isFunctionPassName(FirstName)) { + if (PipelineText.startswith("function(") || isFunctionPassName(FirstName)) { FunctionPassManager FPM(DebugLogging); if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass, DebugLogging) || @@ -414,5 +725,29 @@ bool PassBuilder::parsePassPipeline(ModulePassManager &MPM, return true; } + // If this looks like a Loop pass, parse the whole thing as a Loop pipeline. + if (PipelineText.startswith("loop(") || isLoopPassName(FirstName)) { + LoopPassManager LPM(DebugLogging); + if (!parseLoopPassPipeline(LPM, PipelineText, VerifyEachPass, + DebugLogging) || + !PipelineText.empty()) + return false; + FunctionPassManager FPM(DebugLogging); + FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM))); + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); + return true; + } + return false; } + +bool PassBuilder::parseAAPipeline(AAManager &AA, StringRef PipelineText) { + while (!PipelineText.empty()) { + StringRef Name; + std::tie(Name, PipelineText) = PipelineText.split(','); + if (!parseAAPassName(AA, Name)) + return false; + } + + return true; +} diff --git a/lib/Passes/PassRegistry.def b/lib/Passes/PassRegistry.def index 241a78927c77..b717057632b4 100644 --- a/lib/Passes/PassRegistry.def +++ b/lib/Passes/PassRegistry.def @@ -19,21 +19,53 @@ #ifndef MODULE_ANALYSIS #define MODULE_ANALYSIS(NAME, CREATE_PASS) #endif +MODULE_ANALYSIS("callgraph", CallGraphAnalysis()) MODULE_ANALYSIS("lcg", LazyCallGraphAnalysis()) MODULE_ANALYSIS("no-op-module", NoOpModuleAnalysis()) +MODULE_ANALYSIS("profile-summary", ProfileSummaryAnalysis()) MODULE_ANALYSIS("targetlibinfo", TargetLibraryAnalysis()) +MODULE_ANALYSIS("verify", VerifierAnalysis()) + +#ifndef MODULE_ALIAS_ANALYSIS +#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \ + MODULE_ANALYSIS(NAME, CREATE_PASS) +#endif +MODULE_ALIAS_ANALYSIS("globals-aa", GlobalsAA()) +#undef MODULE_ALIAS_ANALYSIS #undef MODULE_ANALYSIS #ifndef MODULE_PASS #define MODULE_PASS(NAME, CREATE_PASS) #endif +MODULE_PASS("constmerge", ConstantMergePass()) +MODULE_PASS("cross-dso-cfi", CrossDSOCFIPass()) +MODULE_PASS("deadargelim", DeadArgumentEliminationPass()) +MODULE_PASS("elim-avail-extern", EliminateAvailableExternallyPass()) MODULE_PASS("forceattrs", ForceFunctionAttrsPass()) +MODULE_PASS("globaldce", GlobalDCEPass()) +MODULE_PASS("globalopt", GlobalOptPass()) MODULE_PASS("inferattrs", InferFunctionAttrsPass()) +MODULE_PASS("insert-gcov-profiling", GCOVProfilerPass()) +MODULE_PASS("instrprof", InstrProfiling()) +MODULE_PASS("internalize", InternalizePass()) MODULE_PASS("invalidate<all>", InvalidateAllAnalysesPass()) +MODULE_PASS("ipsccp", IPSCCPPass()) +MODULE_PASS("lowertypetests", LowerTypeTestsPass()) MODULE_PASS("no-op-module", NoOpModulePass()) +MODULE_PASS("partial-inliner", PartialInlinerPass()) +MODULE_PASS("pgo-icall-prom", PGOIndirectCallPromotion()) +MODULE_PASS("pgo-instr-gen", PGOInstrumentationGen()) +MODULE_PASS("pgo-instr-use", PGOInstrumentationUse()) +MODULE_PASS("pre-isel-intrinsic-lowering", PreISelIntrinsicLoweringPass()) +MODULE_PASS("print-profile-summary", ProfileSummaryPrinterPass(dbgs())) +MODULE_PASS("print-callgraph", CallGraphPrinterPass(dbgs())) MODULE_PASS("print", PrintModulePass(dbgs())) -MODULE_PASS("print-cg", LazyCallGraphPrinterPass(dbgs())) +MODULE_PASS("print-lcg", LazyCallGraphPrinterPass(dbgs())) +MODULE_PASS("print-lcg-dot", LazyCallGraphDOTPrinterPass(dbgs())) +MODULE_PASS("rpo-functionattrs", ReversePostOrderFunctionAttrsPass()) +MODULE_PASS("sample-profile", SampleProfileLoaderPass()) MODULE_PASS("strip-dead-prototypes", StripDeadPrototypesPass()) +MODULE_PASS("wholeprogramdevirt", WholeProgramDevirtPass()) MODULE_PASS("verify", VerifierPass()) #undef MODULE_PASS @@ -47,38 +79,127 @@ CGSCC_ANALYSIS("no-op-cgscc", NoOpCGSCCAnalysis()) #define CGSCC_PASS(NAME, CREATE_PASS) #endif CGSCC_PASS("invalidate<all>", InvalidateAllAnalysesPass()) +CGSCC_PASS("function-attrs", PostOrderFunctionAttrsPass()) CGSCC_PASS("no-op-cgscc", NoOpCGSCCPass()) #undef CGSCC_PASS #ifndef FUNCTION_ANALYSIS #define FUNCTION_ANALYSIS(NAME, CREATE_PASS) #endif +FUNCTION_ANALYSIS("aa", AAManager()) FUNCTION_ANALYSIS("assumptions", AssumptionAnalysis()) +FUNCTION_ANALYSIS("block-freq", BlockFrequencyAnalysis()) +FUNCTION_ANALYSIS("branch-prob", BranchProbabilityAnalysis()) FUNCTION_ANALYSIS("domtree", DominatorTreeAnalysis()) +FUNCTION_ANALYSIS("postdomtree", PostDominatorTreeAnalysis()) +FUNCTION_ANALYSIS("demanded-bits", DemandedBitsAnalysis()) +FUNCTION_ANALYSIS("domfrontier", DominanceFrontierAnalysis()) FUNCTION_ANALYSIS("loops", LoopAnalysis()) +FUNCTION_ANALYSIS("lazy-value-info", LazyValueAnalysis()) +FUNCTION_ANALYSIS("da", DependenceAnalysis()) +FUNCTION_ANALYSIS("memdep", MemoryDependenceAnalysis()) +FUNCTION_ANALYSIS("memoryssa", MemorySSAAnalysis()) +FUNCTION_ANALYSIS("regions", RegionInfoAnalysis()) FUNCTION_ANALYSIS("no-op-function", NoOpFunctionAnalysis()) +FUNCTION_ANALYSIS("opt-remark-emit", OptimizationRemarkEmitterAnalysis()) FUNCTION_ANALYSIS("scalar-evolution", ScalarEvolutionAnalysis()) FUNCTION_ANALYSIS("targetlibinfo", TargetLibraryAnalysis()) FUNCTION_ANALYSIS("targetir", TM ? TM->getTargetIRAnalysis() : TargetIRAnalysis()) +FUNCTION_ANALYSIS("verify", VerifierAnalysis()) + +#ifndef FUNCTION_ALIAS_ANALYSIS +#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \ + FUNCTION_ANALYSIS(NAME, CREATE_PASS) +#endif +FUNCTION_ALIAS_ANALYSIS("basic-aa", BasicAA()) +FUNCTION_ALIAS_ANALYSIS("cfl-anders-aa", CFLAndersAA()) +FUNCTION_ALIAS_ANALYSIS("cfl-steens-aa", CFLSteensAA()) +FUNCTION_ALIAS_ANALYSIS("scev-aa", SCEVAA()) +FUNCTION_ALIAS_ANALYSIS("scoped-noalias-aa", ScopedNoAliasAA()) +FUNCTION_ALIAS_ANALYSIS("type-based-aa", TypeBasedAA()) +#undef FUNCTION_ALIAS_ANALYSIS #undef FUNCTION_ANALYSIS #ifndef FUNCTION_PASS #define FUNCTION_PASS(NAME, CREATE_PASS) #endif +FUNCTION_PASS("aa-eval", AAEvaluator()) FUNCTION_PASS("adce", ADCEPass()) +FUNCTION_PASS("add-discriminators", AddDiscriminatorsPass()) +FUNCTION_PASS("alignment-from-assumptions", AlignmentFromAssumptionsPass()) +FUNCTION_PASS("bdce", BDCEPass()) +FUNCTION_PASS("consthoist", ConstantHoistingPass()) +FUNCTION_PASS("correlated-propagation", CorrelatedValuePropagationPass()) +FUNCTION_PASS("dce", DCEPass()) +FUNCTION_PASS("dse", DSEPass()) FUNCTION_PASS("early-cse", EarlyCSEPass()) +FUNCTION_PASS("gvn-hoist", GVNHoistPass()) FUNCTION_PASS("instcombine", InstCombinePass()) +FUNCTION_PASS("instsimplify", InstSimplifierPass()) FUNCTION_PASS("invalidate<all>", InvalidateAllAnalysesPass()) +FUNCTION_PASS("float2int", Float2IntPass()) FUNCTION_PASS("no-op-function", NoOpFunctionPass()) +FUNCTION_PASS("loweratomic", LowerAtomicPass()) FUNCTION_PASS("lower-expect", LowerExpectIntrinsicPass()) +FUNCTION_PASS("guard-widening", GuardWideningPass()) +FUNCTION_PASS("gvn", GVN()) +FUNCTION_PASS("loop-simplify", LoopSimplifyPass()) +FUNCTION_PASS("mem2reg", PromotePass()) +FUNCTION_PASS("memcpyopt", MemCpyOptPass()) +FUNCTION_PASS("mldst-motion", MergedLoadStoreMotionPass()) +FUNCTION_PASS("jump-threading", JumpThreadingPass()) +FUNCTION_PASS("partially-inline-libcalls", PartiallyInlineLibCallsPass()) +FUNCTION_PASS("lcssa", LCSSAPass()) +FUNCTION_PASS("loop-distribute", LoopDistributePass()) +FUNCTION_PASS("loop-vectorize", LoopVectorizePass()) FUNCTION_PASS("print", PrintFunctionPass(dbgs())) FUNCTION_PASS("print<assumptions>", AssumptionPrinterPass(dbgs())) +FUNCTION_PASS("print<block-freq>", BlockFrequencyPrinterPass(dbgs())) +FUNCTION_PASS("print<branch-prob>", BranchProbabilityPrinterPass(dbgs())) FUNCTION_PASS("print<domtree>", DominatorTreePrinterPass(dbgs())) +FUNCTION_PASS("print<postdomtree>", PostDominatorTreePrinterPass(dbgs())) +FUNCTION_PASS("print<demanded-bits>", DemandedBitsPrinterPass(dbgs())) +FUNCTION_PASS("print<domfrontier>", DominanceFrontierPrinterPass(dbgs())) FUNCTION_PASS("print<loops>", LoopPrinterPass(dbgs())) +FUNCTION_PASS("print<memoryssa>", MemorySSAPrinterPass(dbgs())) +FUNCTION_PASS("print<regions>", RegionInfoPrinterPass(dbgs())) FUNCTION_PASS("print<scalar-evolution>", ScalarEvolutionPrinterPass(dbgs())) +FUNCTION_PASS("reassociate", ReassociatePass()) +FUNCTION_PASS("sccp", SCCPPass()) FUNCTION_PASS("simplify-cfg", SimplifyCFGPass()) +FUNCTION_PASS("sink", SinkingPass()) +FUNCTION_PASS("slp-vectorizer", SLPVectorizerPass()) FUNCTION_PASS("sroa", SROA()) +FUNCTION_PASS("tailcallelim", TailCallElimPass()) +FUNCTION_PASS("unreachableblockelim", UnreachableBlockElimPass()) FUNCTION_PASS("verify", VerifierPass()) FUNCTION_PASS("verify<domtree>", DominatorTreeVerifierPass()) +FUNCTION_PASS("verify<memoryssa>", MemorySSAVerifierPass()) +FUNCTION_PASS("verify<regions>", RegionInfoVerifierPass()) #undef FUNCTION_PASS + +#ifndef LOOP_ANALYSIS +#define LOOP_ANALYSIS(NAME, CREATE_PASS) +#endif +LOOP_ANALYSIS("no-op-loop", NoOpLoopAnalysis()) +LOOP_ANALYSIS("access-info", LoopAccessAnalysis()) +LOOP_ANALYSIS("ivusers", IVUsersAnalysis()) +#undef LOOP_ANALYSIS + +#ifndef LOOP_PASS +#define LOOP_PASS(NAME, CREATE_PASS) +#endif +LOOP_PASS("invalidate<all>", InvalidateAllAnalysesPass()) +LOOP_PASS("licm", LICMPass()) +LOOP_PASS("loop-idiom", LoopIdiomRecognizePass()) +LOOP_PASS("loop-instsimplify", LoopInstSimplifyPass()) +LOOP_PASS("rotate", LoopRotatePass()) +LOOP_PASS("no-op-loop", NoOpLoopPass()) +LOOP_PASS("print", PrintLoopPass(dbgs())) +LOOP_PASS("loop-deletion", LoopDeletionPass()) +LOOP_PASS("simplify-cfg", LoopSimplifyCFGPass()) +LOOP_PASS("indvars", IndVarSimplifyPass()) +LOOP_PASS("print-access-info", LoopAccessInfoPrinterPass(dbgs())) +LOOP_PASS("print<ivusers>", IVUsersPrinterPass(dbgs())) +#undef LOOP_PASS |