diff --git a/polly/lib/Support/RegisterPasses.cpp b/polly/lib/Support/RegisterPasses.cpp --- a/polly/lib/Support/RegisterPasses.cpp +++ b/polly/lib/Support/RegisterPasses.cpp @@ -74,7 +74,6 @@ enum PassPositionChoice { POSITION_EARLY, - POSITION_AFTER_LOOPOPT, POSITION_BEFORE_VECTORIZER }; @@ -84,8 +83,6 @@ "polly-position", cl::desc("Where to run polly in the pass pipeline"), cl::values( clEnumValN(POSITION_EARLY, "early", "Before everything"), - clEnumValN(POSITION_AFTER_LOOPOPT, "after-loopopt", - "After the loop optimizer (but within the inline cycle)"), clEnumValN(POSITION_BEFORE_VECTORIZER, "before-vectorizer", "Right before the vectorizer")), cl::Hidden, cl::init(POSITION_BEFORE_VECTORIZER), cl::cat(PollyCategory)); @@ -289,6 +286,18 @@ initializePruneUnprofitableWrapperPassPass(Registry); } +static bool shouldEnablePollyForOptimization() { return PollyEnabled; } + +static bool shouldEnablePollyForDiagnostic() { + // FIXME: PollyTrackFailures is user-controlled, should not be set + // programmatically. + if (PollyOnlyPrinter || PollyPrinter || PollyOnlyViewer || PollyViewer) + PollyTrackFailures = true; + + return PollyOnlyPrinter || PollyPrinter || PollyOnlyViewer || PollyViewer || + ExportJScop; +} + /// Register Polly passes such that they form a polyhedral optimizer. /// /// The individual Polly passes are registered in the pass manager such that @@ -315,170 +324,6 @@ /// scheduling optimizer. /// /// Polly supports the isl internal code generator. -static void registerPollyPasses(llvm::legacy::PassManagerBase &PM, - bool EnableForOpt) { - if (DumpBefore) - PM.add(polly::createDumpModuleWrapperPass("-before", true)); - for (auto &Filename : DumpBeforeFile) - PM.add(polly::createDumpModuleWrapperPass(Filename, false)); - - PM.add(polly::createCodePreparationPass()); - PM.add(polly::createScopDetectionWrapperPassPass()); - - if (PollyDetectOnly) - return; - - if (PollyViewer) - PM.add(polly::createDOTViewerWrapperPass()); - if (PollyOnlyViewer) - PM.add(polly::createDOTOnlyViewerWrapperPass()); - if (PollyPrinter) - PM.add(polly::createDOTPrinterWrapperPass()); - if (PollyOnlyPrinter) - PM.add(polly::createDOTOnlyPrinterWrapperPass()); - PM.add(polly::createScopInfoRegionPassPass()); - if (EnablePolyhedralInfo) - PM.add(polly::createPolyhedralInfoPass()); - - if (EnableSimplify) - PM.add(polly::createSimplifyWrapperPass(0)); - if (EnableForwardOpTree) - PM.add(polly::createForwardOpTreeWrapperPass()); - if (EnableDeLICM) - PM.add(polly::createDeLICMWrapperPass()); - if (EnableSimplify) - PM.add(polly::createSimplifyWrapperPass(1)); - - if (ImportJScop) - PM.add(polly::createJSONImporterPass()); - - if (DeadCodeElim) - PM.add(polly::createDeadCodeElimWrapperPass()); - - if (FullyIndexedStaticExpansion) - PM.add(polly::createMaximalStaticExpansionPass()); - - if (EnablePruneUnprofitable) - PM.add(polly::createPruneUnprofitableWrapperPass()); - -#ifdef GPU_CODEGEN - if (Target == TARGET_HYBRID) - PM.add( - polly::createPPCGCodeGenerationPass(GPUArchChoice, GPURuntimeChoice)); -#endif - if (Target == TARGET_CPU || Target == TARGET_HYBRID) - switch (Optimizer) { - case OPTIMIZER_NONE: - break; /* Do nothing */ - - case OPTIMIZER_ISL: - PM.add(polly::createIslScheduleOptimizerWrapperPass()); - break; - } - - if (ExportJScop) - PM.add(polly::createJSONExporterPass()); - - if (!EnableForOpt) - return; - - if (Target == TARGET_CPU || Target == TARGET_HYBRID) - switch (CodeGeneration) { - case CODEGEN_AST: - PM.add(polly::createIslAstInfoWrapperPassPass()); - break; - case CODEGEN_FULL: - PM.add(polly::createCodeGenerationPass()); - break; - case CODEGEN_NONE: - break; - } -#ifdef GPU_CODEGEN - else { - PM.add( - polly::createPPCGCodeGenerationPass(GPUArchChoice, GPURuntimeChoice)); - PM.add(polly::createManagedMemoryRewritePassPass()); - } -#endif - -#ifdef GPU_CODEGEN - if (Target == TARGET_HYBRID) - PM.add(polly::createManagedMemoryRewritePassPass(GPUArchChoice, - GPURuntimeChoice)); -#endif - - // FIXME: This dummy ModulePass keeps some programs from miscompiling, - // probably some not correctly preserved analyses. It acts as a barrier to - // force all analysis results to be recomputed. - PM.add(llvm::createBarrierNoopPass()); - - if (DumpAfter) - PM.add(polly::createDumpModuleWrapperPass("-after", true)); - for (auto &Filename : DumpAfterFile) - PM.add(polly::createDumpModuleWrapperPass(Filename, false)); - - if (CFGPrinter) - PM.add(llvm::createCFGPrinterLegacyPassPass()); -} - -static bool shouldEnablePollyForOptimization() { return PollyEnabled; } - -static bool shouldEnablePollyForDiagnostic() { - // FIXME: PollyTrackFailures is user-controlled, should not be set - // programmatically. - if (PollyOnlyPrinter || PollyPrinter || PollyOnlyViewer || PollyViewer) - PollyTrackFailures = true; - - return PollyOnlyPrinter || PollyPrinter || PollyOnlyViewer || PollyViewer || - ExportJScop; -} - -static void -registerPollyEarlyAsPossiblePasses(const llvm::PassManagerBuilder &Builder, - llvm::legacy::PassManagerBase &PM) { - if (PassPosition != POSITION_EARLY) - return; - - bool EnableForOpt = shouldEnablePollyForOptimization() && - Builder.OptLevel >= 1 && Builder.SizeLevel == 0; - if (!shouldEnablePollyForDiagnostic() && !EnableForOpt) - return; - - registerCanonicalicationPasses(PM); - registerPollyPasses(PM, EnableForOpt); -} - -static void -registerPollyLoopOptimizerEndPasses(const llvm::PassManagerBuilder &Builder, - llvm::legacy::PassManagerBase &PM) { - if (PassPosition != POSITION_AFTER_LOOPOPT) - return; - - bool EnableForOpt = shouldEnablePollyForOptimization() && - Builder.OptLevel >= 1 && Builder.SizeLevel == 0; - if (!shouldEnablePollyForDiagnostic() && !EnableForOpt) - return; - - registerPollyPasses(PM, EnableForOpt); - if (EnableForOpt) - PM.add(createCodegenCleanupPass()); -} - -static void -registerPollyScalarOptimizerLatePasses(const llvm::PassManagerBuilder &Builder, - llvm::legacy::PassManagerBase &PM) { - if (PassPosition != POSITION_BEFORE_VECTORIZER) - return; - - bool EnableForOpt = shouldEnablePollyForOptimization() && - Builder.OptLevel >= 1 && Builder.SizeLevel == 0; - if (!shouldEnablePollyForDiagnostic() && !EnableForOpt) - return; - - polly::registerPollyPasses(PM, EnableForOpt); - if (EnableForOpt) - PM.add(createCodegenCleanupPass()); -} /// Add the pass sequence required for Polly to the New Pass Manager. /// @@ -646,55 +491,6 @@ false); } -/// Register Polly to be available as an optimizer -/// -/// -/// We can currently run Polly at three different points int the pass manager. -/// a) very early, b) after the canonicalizing loop transformations and c) right -/// before the vectorizer. -/// -/// The default is currently a), to register Polly such that it runs as early as -/// possible. This has several implications: -/// -/// 1) We need to schedule more canonicalization passes -/// -/// As nothing is run before Polly, it is necessary to run a set of preparing -/// transformations before Polly to canonicalize the LLVM-IR and to allow -/// Polly to detect and understand the code. -/// -/// 2) LICM and LoopIdiom pass have not yet been run -/// -/// Loop invariant code motion as well as the loop idiom recognition pass make -/// it more difficult for Polly to transform code. LICM may introduce -/// additional data dependences that are hard to eliminate and the loop idiom -/// recognition pass may introduce calls to memset that we currently do not -/// understand. By running Polly early enough (meaning before these passes) we -/// avoid difficulties that may be introduced by these passes. -/// -/// 3) We get the full -O3 optimization sequence after Polly -/// -/// The LLVM-IR that is generated by Polly has been optimized on a high level, -/// but it may be rather inefficient on the lower/scalar level. By scheduling -/// Polly before all other passes, we have the full sequence of -O3 -/// optimizations behind us, such that inefficiencies on the low level can -/// be optimized away. -/// -/// We are currently evaluating the benefit or running Polly at position b) or -/// c). b) is likely too early as it interacts with the inliner. c) is nice -/// as everything is fully inlined and canonicalized, but we need to be able -/// to handle LICMed code to make it useful. -static llvm::RegisterStandardPasses RegisterPollyOptimizerEarly( - llvm::PassManagerBuilder::EP_ModuleOptimizerEarly, - registerPollyEarlyAsPossiblePasses); - -static llvm::RegisterStandardPasses - RegisterPollyOptimizerLoopEnd(llvm::PassManagerBuilder::EP_LoopOptimizerEnd, - registerPollyLoopOptimizerEndPasses); - -static llvm::RegisterStandardPasses RegisterPollyOptimizerScalarLate( - llvm::PassManagerBuilder::EP_VectorizerStart, - registerPollyScalarOptimizerLatePasses); - static OwningScopAnalysisManagerFunctionProxy createScopAnalyses(FunctionAnalysisManager &FAM, PassInstrumentationCallbacks *PIC) { @@ -823,6 +619,32 @@ return true; } +/// Register Polly to be available as an optimizer +/// +/// +/// We can currently run Polly at two different points int the pass manager. +/// a) very early, b) right before the vectorizer. +/// +/// The default is currently a), to register Polly such that it runs as early as +/// possible. This has several implications: +/// +/// 1) We need to schedule more canonicalization passes +/// +/// As nothing is run before Polly, it is necessary to run a set of preparing +/// transformations before Polly to canonicalize the LLVM-IR and to allow +/// Polly to detect and understand the code. +/// +/// 2) We get the full -O3 optimization sequence after Polly +/// +/// The LLVM-IR that is generated by Polly has been optimized on a high level, +/// but it may be rather inefficient on the lower/scalar level. By scheduling +/// Polly before all other passes, we have the full sequence of -O3 +/// optimizations behind us, such that inefficiencies on the low level can +/// be optimized away. +/// +/// We are currently evaluating the benefit or running Polly at b). b) is nice +/// as everything is fully inlined and canonicalized, but we need to be able to +/// handle LICMed code to make it useful. void registerPollyPasses(PassBuilder &PB) { PassInstrumentationCallbacks *PIC = PB.getPassInstrumentationCallbacks(); PB.registerAnalysisRegistrationCallback([PIC](FunctionAnalysisManager &FAM) { @@ -844,10 +666,6 @@ case POSITION_EARLY: PB.registerPipelineStartEPCallback(buildEarlyPollyPipeline); break; - case POSITION_AFTER_LOOPOPT: - llvm::report_fatal_error( - "Option -polly-position=after-loopopt not supported with NPM", false); - break; case POSITION_BEFORE_VECTORIZER: PB.registerVectorizerStartEPCallback(buildLatePollyPipeline); break; diff --git a/polly/test/Support/defaultpipelines.ll b/polly/test/Support/defaultpipelines.ll --- a/polly/test/Support/defaultpipelines.ll +++ b/polly/test/Support/defaultpipelines.ll @@ -1,18 +1,9 @@ -; Legacy pass manager -; RUN: opt %loadPolly -enable-new-pm=0 -polly -O0 -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=OFF -; RUN: opt %loadPolly -enable-new-pm=0 -polly -O1 -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ON -; RUN: opt %loadPolly -enable-new-pm=0 -polly -O2 -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ON -; RUN: opt %loadPolly -enable-new-pm=0 -polly -O3 -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ON -; RUN: opt %loadPolly -enable-new-pm=0 -polly -Os -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=OFF -; RUN: opt %loadPolly -enable-new-pm=0 -polly -Oz -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=OFF -; -; New pass manager -; RUN: opt %loadNPMPolly -enable-new-pm=1 -polly -O0 -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=OFF -; RUN: opt %loadNPMPolly -enable-new-pm=1 -polly -O1 -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ON -; RUN: opt %loadNPMPolly -enable-new-pm=1 -polly -O2 -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ON -; RUN: opt %loadNPMPolly -enable-new-pm=1 -polly -O3 -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ON -; RUN: opt %loadNPMPolly -enable-new-pm=1 -polly -Os -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=OFF -; RUN: opt %loadNPMPolly -enable-new-pm=1 -polly -Oz -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=OFF +; RUN: opt %loadNPMPolly -polly -O0 -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=OFF +; RUN: opt %loadNPMPolly -polly -O1 -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ON +; RUN: opt %loadNPMPolly -polly -O2 -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ON +; RUN: opt %loadNPMPolly -polly -O3 -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ON +; RUN: opt %loadNPMPolly -polly -Os -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=OFF +; RUN: opt %loadNPMPolly -polly -Oz -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=OFF ; ; Check that Polly's default pipeline works from detection to code generation ; with either pass manager. diff --git a/polly/test/Support/dumpmodule.ll b/polly/test/Support/dumpmodule.ll --- a/polly/test/Support/dumpmodule.ll +++ b/polly/test/Support/dumpmodule.ll @@ -1,12 +1,5 @@ -; Legacy pass manager -; RUN: opt %loadPolly -enable-new-pm=0 -O3 -polly -polly-position=early -polly-dump-before-file=%t-legacy-before-early.ll --disable-output < %s && FileCheck --input-file=%t-legacy-before-early.ll --check-prefix=EARLY %s -; RUN: opt %loadPolly -enable-new-pm=0 -O3 -polly -polly-position=before-vectorizer -polly-dump-before-file=%t-legacy-before-late.ll --disable-output < %s && FileCheck --input-file=%t-legacy-before-late.ll --check-prefix=LATE %s -; RUN: opt %loadPolly -enable-new-pm=0 -O3 -polly -polly-position=early -polly-dump-after-file=%t-legacy-after-early.ll --disable-output < %s && FileCheck --input-file=%t-legacy-after-early.ll --check-prefix=EARLY --check-prefix=AFTEREARLY %s -; RUN: opt %loadPolly -enable-new-pm=0 -O3 -polly -polly-position=before-vectorizer -polly-dump-after-file=%t-legacy-after-late.ll --disable-output < %s && FileCheck --input-file=%t-legacy-after-late.ll --check-prefix=LATE --check-prefix=AFTERLATE %s -; -; New pass manager -; RUN: opt %loadNPMPolly -enable-new-pm=1 -O3 -polly -polly-position=early -polly-dump-before-file=%t-npm-before-early.ll --disable-output < %s && FileCheck --input-file=%t-npm-before-early.ll --check-prefix=EARLY %s -; RUN: opt %loadNPMPolly -enable-new-pm=1 -O3 -polly -polly-position=early -polly-dump-after-file=%t-npm-after-early.ll --disable-output < %s && FileCheck --input-file=%t-npm-after-early.ll --check-prefix=EARLY --check-prefix=AFTEREARLY %s +; RUN: opt %loadNPMPolly -O3 -polly -polly-position=early -polly-dump-before-file=%t-npm-before-early.ll --disable-output < %s && FileCheck --input-file=%t-npm-before-early.ll --check-prefix=EARLY %s +; RUN: opt %loadNPMPolly -O3 -polly -polly-position=early -polly-dump-after-file=%t-npm-after-early.ll --disable-output < %s && FileCheck --input-file=%t-npm-after-early.ll --check-prefix=EARLY --check-prefix=AFTEREARLY %s ; ; Check the module dumping before Polly at specific positions in the ; pass pipeline. diff --git a/polly/test/Support/pipelineposition.ll b/polly/test/Support/pipelineposition.ll --- a/polly/test/Support/pipelineposition.ll +++ b/polly/test/Support/pipelineposition.ll @@ -1,13 +1,6 @@ -; Legacy pass manager -; RUN: opt %loadPolly -O3 -enable-new-pm=0 -polly -polly-position=early -disable-output -debug-only=polly-scops < %s 2>&1 | FileCheck %s --check-prefix=NOINLINE -; RUN: opt %loadPolly -O3 -enable-new-pm=0 -polly -polly-position=early -polly-run-inliner -disable-output -debug-only=polly-scops < %s 2>&1 | FileCheck %s --check-prefix=INLINED1 -; RUN: opt %loadPolly -O3 -enable-new-pm=0 -polly -polly-position=after-loopopt -disable-output -debug-only=polly-scops < %s 2>&1 | FileCheck %s --check-prefix=INLINED2 -; RUN: opt %loadPolly -O3 -enable-new-pm=0 -polly -polly-position=before-vectorizer -disable-output -debug-only=polly-scops < %s 2>&1 | FileCheck %s --check-prefix=INLINED3 -; -; New pass manager -; RUN: opt %loadNPMPolly -O3 -enable-new-pm=1 -polly -polly-position=early -disable-output -debug-only=polly-scops < %s 2>&1 | FileCheck %s --check-prefix=NOINLINE -; RUN: opt %loadNPMPolly -O3 -enable-new-pm=1 -polly -polly-position=early -polly-run-inliner -disable-output -debug-only=polly-scops < %s 2>&1 | FileCheck %s --check-prefix=INLINED1 -; RUN: opt %loadNPMPolly -O3 -enable-new-pm=1 -polly -polly-position=before-vectorizer -disable-output -debug-only=polly-scops < %s 2>&1 | FileCheck %s --check-prefix=INLINED3 +; RUN: opt %loadNPMPolly -O3 -polly -polly-position=early -disable-output -debug-only=polly-scops < %s 2>&1 | FileCheck %s --check-prefix=NOINLINE +; RUN: opt %loadNPMPolly -O3 -polly -polly-position=early -polly-run-inliner -disable-output -debug-only=polly-scops < %s 2>&1 | FileCheck %s --check-prefix=INLINED1 +; RUN: opt %loadNPMPolly -O3 -polly -polly-position=before-vectorizer -disable-output -debug-only=polly-scops < %s 2>&1 | FileCheck %s --check-prefix=INLINED3 ; ; REQUIRES: asserts ;