Index: include/polly/ScopPass.h =================================================================== --- include/polly/ScopPass.h +++ include/polly/ScopPass.h @@ -77,6 +77,21 @@ ScopInfo *SI; }; +// A partial specialization of the require analysis template pass to handle +// extra parameters +template +struct RequireAnalysisPass + : PassInfoMixin< + RequireAnalysisPass> { + PreservedAnalyses run(Scop &L, ScopAnalysisManager &AM, + ScopStandardAnalysisResults &AR, SPMUpdater &) { + (void)AM.template getResult(L, AR); + return PreservedAnalyses::all(); + } +}; + template <> InnerAnalysisManagerProxy::Result InnerAnalysisManagerProxy::run( @@ -95,6 +110,40 @@ } // namespace llvm namespace polly { + +template +class OwningInnerAnalysisManagerProxy + : public InnerAnalysisManagerProxy { +public: + OwningInnerAnalysisManagerProxy() + : InnerAnalysisManagerProxy(InnerAM) {} + using Result = typename InnerAnalysisManagerProxy::Result; + Result run(IRUnitT &IR, AnalysisManager &AM, + ExtraArgTs...) { + return Result(InnerAM); + } + + AnalysisManagerT &getManager() { return InnerAM; } + +private: + friend AnalysisInfoMixin< + OwningInnerAnalysisManagerProxy>; + + static AnalysisKey Key; + + AnalysisManagerT InnerAM; +}; + +template <> +OwningInnerAnalysisManagerProxy::Result +OwningInnerAnalysisManagerProxy::run( + Function &F, FunctionAnalysisManager &FAM); +extern template class OwningInnerAnalysisManagerProxy; + +using OwningScopAnalysisManagerFunctionProxy = + OwningInnerAnalysisManagerProxy; using ScopPassManager = PassManager; Index: lib/Analysis/ScopPass.cpp =================================================================== --- lib/Analysis/ScopPass.cpp +++ lib/Analysis/ScopPass.cpp @@ -41,6 +41,8 @@ AU.setPreservesAll(); } +template class OwningInnerAnalysisManagerProxy; + namespace llvm { template class PassManager +OwningScopAnalysisManagerFunctionProxy::Result +OwningScopAnalysisManagerFunctionProxy::run(Function &F, + FunctionAnalysisManager &FAM) { + return Result(InnerAM, FAM.getResult(F)); +} +template <> ScopAnalysisManagerFunctionProxy::Result ScopAnalysisManagerFunctionProxy::run(Function &F, FunctionAnalysisManager &FAM) { Index: lib/Support/PollyPasses.def =================================================================== --- /dev/null +++ lib/Support/PollyPasses.def @@ -0,0 +1,28 @@ +#ifndef FUNCTION_ANALYSIS +#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) +#endif +FUNCTION_ANALYSIS("polly-detect", ScopAnalysis()) +FUNCTION_ANALYSIS("polly-function-scops", ScopInfoAnalysis()) +#undef FUNCTION_ANALYSIS + +#ifndef FUNCTION_PASS +#define FUNCTION_PASS(NAME, CREATE_PASS) +#endif +FUNCTION_PASS("print", ScopAnalysisPrinterPass(errs())) +FUNCTION_PASS("print", ScopInfoPrinterPass(errs())) +#undef FUNCTION_PASS + +#ifndef SCOP_ANALYSIS +#define SCOP_ANALYSIS(NAME, CREATE_PASS) +#endif +SCOP_ANALYSIS("polly-ast", IslAstAnalysis()) +SCOP_ANALYSIS("polly-dependences", DependenceAnalysis()) +#undef SCOP_ANALYSIS + +#ifndef SCOP_PASS +#define SCOP_PASS(NAME, CREATE_PASS) +#endif +SCOP_PASS("print", IslAstPrinterPass(outs())) +SCOP_PASS("print", DependenceInfoPrinterPass(outs())) +SCOP_PASS("polly-codegen", CodeGenerationPass()) +#undef SCOP_PASS Index: lib/Support/RegisterPasses.cpp =================================================================== --- lib/Support/RegisterPasses.cpp +++ lib/Support/RegisterPasses.cpp @@ -23,6 +23,7 @@ #include "polly/Canonicalization.h" #include "polly/CodeGen/CodeGeneration.h" #include "polly/CodeGen/CodegenCleanup.h" +#include "polly/CodeGen/IslAst.h" #include "polly/CodeGen/PPCGCodeGeneration.h" #include "polly/DeLICM.h" #include "polly/DependenceInfo.h" @@ -36,6 +37,8 @@ #include "polly/Support/DumpModulePass.h" #include "llvm/Analysis/CFGPrinter.h" #include "llvm/IR/LegacyPassManager.h" +#include "llvm/IR/Verifier.h" +#include "llvm/Passes/PassBuilder.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" @@ -417,6 +420,15 @@ PM.add(createCodegenCleanupPass()); } +static void +registerPollyExtensionPointPasses(FunctionPassManager &PM, + PassBuilder::OptimizationLevel Level) { + if (!polly::shouldEnablePolly()) + return; + + // TODO +} + /// Register Polly to be available as an optimizer /// /// @@ -465,4 +477,137 @@ static llvm::RegisterStandardPasses RegisterPollyOptimizerScalarLate( llvm::PassManagerBuilder::EP_VectorizerStart, registerPollyScalarOptimizerLatePasses); + +static OwningScopAnalysisManagerFunctionProxy createScopAnalyses() { + OwningScopAnalysisManagerFunctionProxy Proxy; +#define SCOP_ANALYSIS(NAME, CREATE_PASS) \ + Proxy.getManager().registerPass([] { return CREATE_PASS; }); + +#include "PollyPasses.def" + + return Proxy; +} + +static void registerFunctionAnalyses(FunctionAnalysisManager &FAM) { +#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \ + FAM.registerPass([] { return CREATE_PASS; }); + +#include "PollyPasses.def" + + FAM.registerPass(createScopAnalyses); +} + +static bool +parseFunctionPipeline(StringRef Name, FunctionPassManager &FPM, + ArrayRef Pipeline) { + if (parseAnalysisUtilityPasses( + "polly-scop-analyses", Name, FPM)) + return true; + +#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \ + if (parseAnalysisUtilityPasses< \ + std::remove_reference::type>(NAME, Name, \ + FPM)) \ + return true; + +#define FUNCTION_PASS(NAME, CREATE_PASS) \ + if (Name == NAME) { \ + FPM.addPass(CREATE_PASS); \ + return true; \ + } + +#include "PollyPasses.def" + return false; +} + +static bool parseScopPass(StringRef Name, ScopPassManager &SPM) { +#define SCOP_ANALYSIS(NAME, CREATE_PASS) \ + if (parseAnalysisUtilityPasses< \ + std::remove_reference::type>(NAME, Name, \ + SPM)) \ + return true; + +#define SCOP_PASS(NAME, CREATE_PASS) \ + if (Name == NAME) { \ + SPM.addPass(CREATE_PASS); \ + return true; \ + } + +#include "PollyPasses.def" + + return false; +} + +static bool parseScopPipeline(StringRef Name, FunctionPassManager &FPM, + ArrayRef Pipeline) { + if (!Pipeline.empty()) { + if (Name == "scop") { + ScopPassManager SPM; + for (const auto &E : Pipeline) + if (!parseScopPass(E.Name, SPM)) + return false; + FPM.addPass(createFunctionToScopPassAdaptor(std::move(SPM))); + return true; + } + } + return false; +} + +static bool isScopPassName(StringRef Name) { +#define SCOP_ANALYSIS(NAME, CREATE_PASS) \ + if (Name == "require<" NAME ">") \ + return true; \ + if (Name == "invalidate<" NAME ">") \ + return true; + +#define SCOP_PASS(NAME, CREATE_PASS) \ + if (Name == NAME) \ + return true; + +#include "PollyPasses.def" + + return false; +} + +static bool +parseTopLevelPipeline(ModulePassManager &MPM, + ArrayRef Pipeline, + bool VerifyEachPass, bool DebugLogging) { + std::vector FullPipeline; + StringRef FirstName = Pipeline.front().Name; + + if (!isScopPassName(FirstName)) + return false; + + FunctionPassManager FPM(DebugLogging); + ScopPassManager SPM(DebugLogging); + + for (auto &Element : Pipeline) { + auto &Name = Element.Name; + auto &InnerPipeline = Element.InnerPipeline; + if (!InnerPipeline.empty()) // Scop passes don't have inner pipelines + return false; + if (!parseScopPass(Name, SPM)) + return false; + } + + FPM.addPass(createFunctionToScopPassAdaptor(std::move(SPM))); + if (VerifyEachPass) + FPM.addPass(VerifierPass()); + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); + if (VerifyEachPass) + MPM.addPass(VerifierPass()); + + return true; +} + +void RegisterPollyPasses(PassBuilder &PB) { + PB.registerAnalysisRegistrationCallback(registerFunctionAnalyses); + PB.registerPipelineParsingCallback(parseFunctionPipeline); + PB.registerPipelineParsingCallback(parseScopPipeline); + PB.registerParseTopLevelPipelineCallback(parseTopLevelPipeline); + + if (PassPosition == POSITION_BEFORE_VECTORIZER) + PB.registerVectorizerStartEPCallback(registerPollyExtensionPointPasses); +} } // namespace polly