[Polly] Sanitize optimization levels.

The description of the -polly switch stated that it was only enabled
with -O3. This was a lie, the optimization level was ignored. Only at
-O0 Polly was not added to the pass pipeline because the pass builder,
but only because the extension points were not triggered.

In the NewPM, the VectorizerStart extensions point is actually trigger
even with -O0 which leads to the following crash:

   Assertion `Level != OptimizationLevel::O0 && "Must request optimizations!"' failed.

We sanitize the optimization levels using the following rules for both
pass mangers:

 1. Only enable Polly if optimizing at all (-O1, -O2 or -O3).
 2. Do not enable Polly when optimizing for size.
 3. Ignore the optimization level for diagnostic passes (printer, viewer
    or JScop-exporter).
 4. If only diagnostic passes enabled, skip the code-generation.
 5. Fix the description of the -polly command line option.

GitOrigin-RevId: 9b123cde6340449669b88afc540d560080b4113b
diff --git a/lib/Support/RegisterPasses.cpp b/lib/Support/RegisterPasses.cpp
index 6d28b21..ebbce7c 100644
--- a/lib/Support/RegisterPasses.cpp
+++ b/lib/Support/RegisterPasses.cpp
@@ -53,7 +53,8 @@
                                  "Configure the polly loop optimizer");
 
 static cl::opt<bool>
-    PollyEnabled("polly", cl::desc("Enable the polly optimizer (only at -O3)"),
+    PollyEnabled("polly",
+                 cl::desc("Enable the polly optimizer (with -O1, -O2 or -O3)"),
                  cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
 
 static cl::opt<bool> PollyDetectOnly(
@@ -297,7 +298,8 @@
 /// scheduling optimizer.
 ///
 /// Polly supports the isl internal code generator.
-void registerPollyPasses(llvm::legacy::PassManagerBase &PM) {
+static void registerPollyPasses(llvm::legacy::PassManagerBase &PM,
+                                bool EnableForOpt) {
   if (DumpBefore)
     PM.add(polly::createDumpModulePass("-before", true));
   for (auto &Filename : DumpBeforeFile)
@@ -360,6 +362,9 @@
   if (ExportJScop)
     PM.add(polly::createJSONExporterPass());
 
+  if (!EnableForOpt)
+    return;
+
   if (Target == TARGET_CPU || Target == TARGET_HYBRID)
     switch (CodeGeneration) {
     case CODEGEN_AST:
@@ -399,62 +404,74 @@
     PM.add(llvm::createCFGPrinterLegacyPassPass());
 }
 
-static bool shouldEnablePolly() {
+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;
 
-  if (PollyOnlyPrinter || PollyPrinter || PollyOnlyViewer || PollyViewer ||
-      ExportJScop || ImportJScop)
-    PollyEnabled = true;
-
-  return PollyEnabled;
+  return PollyOnlyPrinter || PollyPrinter || PollyOnlyViewer || PollyViewer ||
+         ExportJScop;
 }
 
 static void
 registerPollyEarlyAsPossiblePasses(const llvm::PassManagerBuilder &Builder,
                                    llvm::legacy::PassManagerBase &PM) {
-  if (!polly::shouldEnablePolly())
-    return;
-
   if (PassPosition != POSITION_EARLY)
     return;
 
+  bool EnableForOpt = shouldEnablePollyForOptimization() &&
+                      Builder.OptLevel >= 1 && Builder.SizeLevel == 0;
+  if (!shouldEnablePollyForDiagnostic() && !EnableForOpt)
+    return;
+
   registerCanonicalicationPasses(PM);
-  polly::registerPollyPasses(PM);
+  registerPollyPasses(PM, EnableForOpt);
 }
 
 static void
 registerPollyLoopOptimizerEndPasses(const llvm::PassManagerBuilder &Builder,
                                     llvm::legacy::PassManagerBase &PM) {
-  if (!polly::shouldEnablePolly())
-    return;
-
   if (PassPosition != POSITION_AFTER_LOOPOPT)
     return;
 
+  bool EnableForOpt = shouldEnablePollyForOptimization() &&
+                      Builder.OptLevel >= 1 && Builder.SizeLevel == 0;
+  if (!shouldEnablePollyForDiagnostic() && !EnableForOpt)
+    return;
+
   PM.add(polly::createCodePreparationPass());
-  polly::registerPollyPasses(PM);
-  PM.add(createCodegenCleanupPass());
+  registerPollyPasses(PM, EnableForOpt);
+  if (EnableForOpt)
+    PM.add(createCodegenCleanupPass());
 }
 
 static void
 registerPollyScalarOptimizerLatePasses(const llvm::PassManagerBuilder &Builder,
                                        llvm::legacy::PassManagerBase &PM) {
-  if (!polly::shouldEnablePolly())
-    return;
-
   if (PassPosition != POSITION_BEFORE_VECTORIZER)
     return;
 
+  bool EnableForOpt = shouldEnablePollyForOptimization() &&
+                      Builder.OptLevel >= 1 && Builder.SizeLevel == 0;
+  if (!shouldEnablePollyForDiagnostic() && !EnableForOpt)
+    return;
+
   PM.add(polly::createCodePreparationPass());
-  polly::registerPollyPasses(PM);
-  PM.add(createCodegenCleanupPass());
+  polly::registerPollyPasses(PM, EnableForOpt);
+  if (EnableForOpt)
+    PM.add(createCodegenCleanupPass());
 }
 
 static void buildDefaultPollyPipeline(FunctionPassManager &PM,
                                       PassBuilder::OptimizationLevel Level) {
-  if (!polly::shouldEnablePolly())
+  bool EnableForOpt =
+      shouldEnablePollyForOptimization() && Level.isOptimizingForSpeed();
+  if (!shouldEnablePollyForDiagnostic() && !EnableForOpt)
     return;
+
   PassBuilder PB;
   ScopPassManager SPM;
 
@@ -522,6 +539,9 @@
   if (ExportJScop)
     report_fatal_error("Option -polly-export not supported with NPM", false);
 
+  if (!EnableForOpt)
+    return;
+
   if (Target == TARGET_CPU || Target == TARGET_HYBRID) {
     switch (CodeGeneration) {
     case CODEGEN_AST: