[polly] 29bef8e - [Polly] Add support for -polly-dump-before(-file) with the NPM.

Michael Kruse via llvm-commits llvm-commits at lists.llvm.org
Mon May 17 19:00:24 PDT 2021


Author: Michael Kruse
Date: 2021-05-17T20:58:37-05:00
New Revision: 29bef8e4e3593ab37c4d3b6289dcdec961c3fb52

URL: https://github.com/llvm/llvm-project/commit/29bef8e4e3593ab37c4d3b6289dcdec961c3fb52
DIFF: https://github.com/llvm/llvm-project/commit/29bef8e4e3593ab37c4d3b6289dcdec961c3fb52.diff

LOG: [Polly] Add support for -polly-dump-before(-file) with the NPM.

Only supported with -polly-position=early. Unfortunately, the
extension point callpack for VectorizerStart only passes a
FunctionPassManager, making it impossible to add a module pass.

Added: 
    polly/test/Support/dumpmodule.ll

Modified: 
    polly/include/polly/LinkAllPasses.h
    polly/include/polly/Support/DumpModulePass.h
    polly/lib/Support/DumpModulePass.cpp
    polly/lib/Support/RegisterPasses.cpp

Removed: 
    


################################################################################
diff  --git a/polly/include/polly/LinkAllPasses.h b/polly/include/polly/LinkAllPasses.h
index 78843690a3dad..7960b4a95cd20 100644
--- a/polly/include/polly/LinkAllPasses.h
+++ b/polly/include/polly/LinkAllPasses.h
@@ -99,7 +99,7 @@ struct PollyForcePassLinking {
     polly::createFlattenSchedulePass();
     polly::createForwardOpTreeWrapperPass();
     polly::createDeLICMWrapperPass();
-    polly::createDumpModulePass("", true);
+    polly::createDumpModuleWrapperPass("", true);
     polly::createSimplifyWrapperPass(0);
     polly::createPruneUnprofitableWrapperPass();
   }

diff  --git a/polly/include/polly/Support/DumpModulePass.h b/polly/include/polly/Support/DumpModulePass.h
index 8299cfde28b9f..851ba6401d03c 100644
--- a/polly/include/polly/Support/DumpModulePass.h
+++ b/polly/include/polly/Support/DumpModulePass.h
@@ -13,8 +13,10 @@
 #ifndef POLLY_SUPPORT_DUMPMODULEPASS_H
 #define POLLY_SUPPORT_DUMPMODULEPASS_H
 
+#include "llvm/IR/PassManager.h"
+#include <string>
+
 namespace llvm {
-class StringRef;
 class ModulePass;
 } // namespace llvm
 
@@ -28,12 +30,25 @@ namespace polly {
 /// The intent of IsSuffix is to avoid the file being overwritten when
 /// processing multiple modules and/or with multiple dump passes in the
 /// pipeline.
-llvm::ModulePass *createDumpModulePass(llvm::StringRef Filename, bool IsSuffix);
+llvm::ModulePass *createDumpModuleWrapperPass(std::string Filename,
+                                              bool IsSuffix);
+
+/// A pass that prints the module into a file.
+struct DumpModulePass : llvm::PassInfoMixin<DumpModulePass> {
+  std::string Filename;
+  bool IsSuffix;
+
+  DumpModulePass(std::string Filename, bool IsSuffix)
+      : Filename(std::move(Filename)), IsSuffix(IsSuffix) {}
+
+  llvm::PreservedAnalyses run(llvm::Module &M, llvm::ModuleAnalysisManager &AM);
+};
+
 } // namespace polly
 
 namespace llvm {
 class PassRegistry;
-void initializeDumpModulePass(llvm::PassRegistry &);
+void initializeDumpModuleWrapperPassPass(llvm::PassRegistry &);
 } // namespace llvm
 
 #endif /* POLLY_SUPPORT_DUMPMODULEPASS_H */

diff  --git a/polly/lib/Support/DumpModulePass.cpp b/polly/lib/Support/DumpModulePass.cpp
index e190ee672b7dd..85f4dd39adde8 100644
--- a/polly/lib/Support/DumpModulePass.cpp
+++ b/polly/lib/Support/DumpModulePass.cpp
@@ -25,10 +25,34 @@ using namespace polly;
 
 namespace {
 
-class DumpModule : public ModulePass {
+static void runDumpModule(llvm::Module &M, StringRef Filename, bool IsSuffix) {
+  std::string Dumpfile;
+  if (IsSuffix) {
+    StringRef ModuleName = M.getName();
+    StringRef Stem = sys::path::stem(ModuleName);
+    Dumpfile = (Twine(Stem) + Filename + ".ll").str();
+  } else {
+    Dumpfile = Filename.str();
+  }
+  LLVM_DEBUG(dbgs() << "Dumping module to " << Dumpfile << '\n');
+
+  std::unique_ptr<ToolOutputFile> Out;
+  std::error_code EC;
+  Out.reset(new ToolOutputFile(Dumpfile, EC, sys::fs::OF_None));
+  if (EC) {
+    errs() << EC.message() << '\n';
+    return;
+  }
+
+  M.print(Out->os(), nullptr);
+  Out->keep();
+}
+
+class DumpModuleWrapperPass : public ModulePass {
 private:
-  DumpModule(const DumpModule &) = delete;
-  const DumpModule &operator=(const DumpModule &) = delete;
+  DumpModuleWrapperPass(const DumpModuleWrapperPass &) = delete;
+  const DumpModuleWrapperPass &
+  operator=(const DumpModuleWrapperPass &) = delete;
 
   std::string Filename;
   bool IsSuffix;
@@ -39,10 +63,11 @@ class DumpModule : public ModulePass {
   /// This constructor is used e.g. if using opt -polly-dump-module.
   ///
   /// Provide a default suffix to not overwrite the original file.
-  explicit DumpModule() : ModulePass(ID), Filename("-dump"), IsSuffix(true) {}
+  explicit DumpModuleWrapperPass()
+      : ModulePass(ID), Filename("-dump"), IsSuffix(true) {}
 
-  explicit DumpModule(llvm::StringRef Filename, bool IsSuffix)
-      : ModulePass(ID), Filename(Filename), IsSuffix(IsSuffix) {}
+  explicit DumpModuleWrapperPass(std::string Filename, bool IsSuffix)
+      : ModulePass(ID), Filename(std::move(Filename)), IsSuffix(IsSuffix) {}
 
   /// @name ModulePass interface
   //@{
@@ -51,41 +76,27 @@ class DumpModule : public ModulePass {
   }
 
   virtual bool runOnModule(llvm::Module &M) override {
-    std::string Dumpfile;
-    if (IsSuffix) {
-      auto ModuleName = M.getName();
-      auto Stem = sys::path::stem(ModuleName);
-      Dumpfile = (Twine(Stem) + Filename + ".ll").str();
-    } else {
-      Dumpfile = Filename;
-    }
-    LLVM_DEBUG(dbgs() << "Dumping module to " << Dumpfile << '\n');
-
-    std::unique_ptr<ToolOutputFile> Out;
-    std::error_code EC;
-    Out.reset(new ToolOutputFile(Dumpfile, EC, sys::fs::OF_None));
-    if (EC) {
-      errs() << EC.message() << '\n';
-      return false;
-    }
-
-    M.print(Out->os(), nullptr);
-    Out->keep();
-
+    runDumpModule(M, Filename, IsSuffix);
     return false;
   }
   //@}
 };
 
-char DumpModule::ID;
+char DumpModuleWrapperPass::ID;
 } // namespace
 
-ModulePass *polly::createDumpModulePass(llvm::StringRef Filename,
-                                        bool IsSuffix) {
-  return new DumpModule(Filename, IsSuffix);
+ModulePass *polly::createDumpModuleWrapperPass(std::string Filename,
+                                               bool IsSuffix) {
+  return new DumpModuleWrapperPass(std::move(Filename), IsSuffix);
+}
+
+llvm::PreservedAnalyses DumpModulePass::run(llvm::Module &M,
+                                            llvm::ModuleAnalysisManager &AM) {
+  runDumpModule(M, Filename, IsSuffix);
+  return PreservedAnalyses::all();
 }
 
-INITIALIZE_PASS_BEGIN(DumpModule, "polly-dump-module", "Polly - Dump Module",
-                      false, false)
-INITIALIZE_PASS_END(DumpModule, "polly-dump-module", "Polly - Dump Module",
-                    false, false)
+INITIALIZE_PASS_BEGIN(DumpModuleWrapperPass, "polly-dump-module",
+                      "Polly - Dump Module", false, false)
+INITIALIZE_PASS_END(DumpModuleWrapperPass, "polly-dump-module",
+                    "Polly - Dump Module", false, false)

diff  --git a/polly/lib/Support/RegisterPasses.cpp b/polly/lib/Support/RegisterPasses.cpp
index d8fe5efdd9f35..99144b87090fe 100644
--- a/polly/lib/Support/RegisterPasses.cpp
+++ b/polly/lib/Support/RegisterPasses.cpp
@@ -269,7 +269,7 @@ void initializePollyPasses(PassRegistry &Registry) {
   initializeForwardOpTreeWrapperPassPass(Registry);
   initializeDeLICMWrapperPassPass(Registry);
   initializeSimplifyWrapperPassPass(Registry);
-  initializeDumpModulePass(Registry);
+  initializeDumpModuleWrapperPassPass(Registry);
   initializePruneUnprofitableWrapperPassPass(Registry);
 }
 
@@ -302,10 +302,11 @@ void initializePollyPasses(PassRegistry &Registry) {
 static void registerPollyPasses(llvm::legacy::PassManagerBase &PM,
                                 bool EnableForOpt) {
   if (DumpBefore)
-    PM.add(polly::createDumpModulePass("-before", true));
+    PM.add(polly::createDumpModuleWrapperPass("-before", true));
   for (auto &Filename : DumpBeforeFile)
-    PM.add(polly::createDumpModulePass(Filename, false));
+    PM.add(polly::createDumpModuleWrapperPass(Filename, false));
 
+  PM.add(polly::createCodePreparationPass());
   PM.add(polly::createScopDetectionWrapperPassPass());
 
   if (PollyDetectOnly)
@@ -397,9 +398,9 @@ static void registerPollyPasses(llvm::legacy::PassManagerBase &PM,
   PM.add(createBarrierNoopPass());
 
   if (DumpAfter)
-    PM.add(polly::createDumpModulePass("-after", true));
+    PM.add(polly::createDumpModuleWrapperPass("-after", true));
   for (auto &Filename : DumpAfterFile)
-    PM.add(polly::createDumpModulePass(Filename, false));
+    PM.add(polly::createDumpModuleWrapperPass(Filename, false));
 
   if (CFGPrinter)
     PM.add(llvm::createCFGPrinterLegacyPassPass());
@@ -429,7 +430,6 @@ registerPollyEarlyAsPossiblePasses(const llvm::PassManagerBuilder &Builder,
     return;
 
   registerCanonicalicationPasses(PM);
-  PM.add(polly::createCodePreparationPass());
   registerPollyPasses(PM, EnableForOpt);
 }
 
@@ -444,7 +444,6 @@ registerPollyLoopOptimizerEndPasses(const llvm::PassManagerBuilder &Builder,
   if (!shouldEnablePollyForDiagnostic() && !EnableForOpt)
     return;
 
-  PM.add(polly::createCodePreparationPass());
   registerPollyPasses(PM, EnableForOpt);
   if (EnableForOpt)
     PM.add(createCodegenCleanupPass());
@@ -461,7 +460,6 @@ registerPollyScalarOptimizerLatePasses(const llvm::PassManagerBuilder &Builder,
   if (!shouldEnablePollyForDiagnostic() && !EnableForOpt)
     return;
 
-  PM.add(polly::createCodePreparationPass());
   polly::registerPollyPasses(PM, EnableForOpt);
   if (EnableForOpt)
     PM.add(createCodegenCleanupPass());
@@ -485,12 +483,6 @@ static void buildCommonPollyPipeline(FunctionPassManager &PM,
 
   // TODO add utility passes for the various command line options, once they're
   // ported
-  if (DumpBefore)
-    report_fatal_error("Option -polly-dump-before not supported with NPM",
-                       false);
-  if (!DumpBeforeFile.empty())
-    report_fatal_error("Option -polly-dump-before-file not supported with NPM",
-                       false);
 
   if (PollyDetectOnly) {
     // Don't add more passes other than the ScopPassManager's detection passes.
@@ -597,12 +589,16 @@ static void buildEarlyPollyPipeline(ModulePassManager &MPM,
 
   FunctionPassManager FPM = buildCanonicalicationPassesForNPM(MPM, Level);
 
-  if (DumpBefore)
-    report_fatal_error("Option -polly-dump-before not supported with NPM",
-                       false);
-  if (!DumpBeforeFile.empty())
-    report_fatal_error("Option -polly-dump-before-file not supported with NPM",
-                       false);
+  if (DumpBefore || !DumpBeforeFile.empty()) {
+    MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
+
+    if (DumpBefore)
+      MPM.addPass(DumpModulePass("-before", true));
+    for (auto &Filename : DumpBeforeFile)
+      MPM.addPass(DumpModulePass(Filename, false));
+
+    FPM = FunctionPassManager();
+  }
 
   buildCommonPollyPipeline(FPM, Level, EnableForOpt);
   MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));

diff  --git a/polly/test/Support/dumpmodule.ll b/polly/test/Support/dumpmodule.ll
new file mode 100644
index 0000000000000..c3a15066c7001
--- /dev/null
+++ b/polly/test/Support/dumpmodule.ll
@@ -0,0 +1,80 @@
+; Legacy pass manager
+; RUN: opt %loadPolly -enable-new-pm=0 -O3 -polly -polly-position=early             -polly-dump-before-file=%t-legacy-early.ll --disable-output < %s && FileCheck --input-file=%t-legacy-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-late.ll  --disable-output < %s && FileCheck --input-file=%t-legacy-late.ll  --check-prefix=LATE  %s
+;
+; New pass manager
+; RUN: opt %loadPolly -enable-new-pm=1 -O3 -polly -polly-position=early             -polly-dump-before-file=%t-npm-early.ll    --disable-output < %s && FileCheck --input-file=%t-npm-early.ll    --check-prefix=EARLY  %s
+;
+; Check the module dumping before Polly at specific positions in the
+; pass pipeline.
+;
+; void callee(int n, double A[], int i) {
+;   for (int j = 0; j < n; j += 1)
+;     A[i+j] = 42.0;
+; }
+;
+; void caller(int n, double A[]) {
+;   for (int i = 0; i < n; i += 1)
+;     callee(n, A, i);
+; }
+
+
+define internal void @callee(i32 %n, double* noalias nonnull %A, i32 %i) {
+entry:
+  br label %for
+
+for:
+  %j = phi i32 [0, %entry], [%j.inc, %inc]
+  %j.cmp = icmp slt i32 %j, %n
+  br i1 %j.cmp, label %body, label %exit
+
+    body:
+      %idx = add i32 %i, %j
+      %arrayidx = getelementptr inbounds double, double* %A, i32 %idx
+      store double 42.0, double* %arrayidx
+      br label %inc
+
+inc:
+  %j.inc = add nuw nsw i32 %j, 1
+  br label %for
+
+exit:
+  br label %return
+
+return:
+  ret void
+}
+
+
+define void @caller(i32 %n, double* noalias nonnull %A) {
+entry:
+  br label %for
+
+for:
+  %i = phi i32 [0, %entry], [%j.inc, %inc]
+  %i.cmp = icmp slt i32 %i, %n
+  br i1 %i.cmp, label %body, label %exit
+
+    body:
+      call void @callee(i32 %n, double* %A, i32 %i)
+      br label %inc
+
+inc:
+  %j.inc = add nuw nsw i32 %i, 1
+  br label %for
+
+exit:
+  br label %return
+
+return:
+  ret void
+}
+
+
+; EARLY-LABEL: @callee(
+; EARLY:         store double 4.200000e+01, double* %arrayidx
+; EARLY-LABEL: @caller(
+; EARLY:         call void @callee(
+
+; LATE-LABEL: @caller(
+; LATE:          store double 4.200000e+01, double* %arrayidx


        


More information about the llvm-commits mailing list