[polly] 9cfab5e - [Polly] Add support for -polly-dump-before/after with NPM.

Michael Kruse via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 22 18:53:29 PDT 2021


Author: Michael Kruse
Date: 2021-08-22T20:43:35-05:00
New Revision: 9cfab5e2491ec1fbf8a3055453b3da08ecacc6a6

URL: https://github.com/llvm/llvm-project/commit/9cfab5e2491ec1fbf8a3055453b3da08ecacc6a6
DIFF: https://github.com/llvm/llvm-project/commit/9cfab5e2491ec1fbf8a3055453b3da08ecacc6a6.diff

LOG: [Polly] Add support for -polly-dump-before/after with NPM.

The new pass manager does not allow adding module passes at the
-polly-position=before-vectorizer extension point. Introduce a
DumpFunctionPass that dumps only current function. In contrast to the
legacy pass manager's -polly-dump-before, each function will be dumped
into its own file. -polly-dump-before-file is still not supported.

The DumpFunctionPass uses llvm::CloneModule to copy the current function
into a new module and then write it into a file.

Added: 
    polly/include/polly/Support/DumpFunctionPass.h
    polly/lib/Support/DumpFunctionPass.cpp
    polly/test/Support/dumpfunction.ll

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

Removed: 
    


################################################################################
diff  --git a/polly/include/polly/LinkAllPasses.h b/polly/include/polly/LinkAllPasses.h
index 7960b4a95cd20..ccda4ef650f21 100644
--- a/polly/include/polly/LinkAllPasses.h
+++ b/polly/include/polly/LinkAllPasses.h
@@ -16,6 +16,7 @@
 
 #include "polly/CodeGen/PPCGCodeGeneration.h"
 #include "polly/Config/config.h"
+#include "polly/Support/DumpFunctionPass.h"
 #include "polly/Support/DumpModulePass.h"
 #include "llvm/ADT/StringRef.h"
 #include <cstdlib>
@@ -100,6 +101,7 @@ struct PollyForcePassLinking {
     polly::createForwardOpTreeWrapperPass();
     polly::createDeLICMWrapperPass();
     polly::createDumpModuleWrapperPass("", true);
+    polly::createDumpFunctionWrapperPass("");
     polly::createSimplifyWrapperPass(0);
     polly::createPruneUnprofitableWrapperPass();
   }

diff  --git a/polly/include/polly/Support/DumpFunctionPass.h b/polly/include/polly/Support/DumpFunctionPass.h
new file mode 100644
index 0000000000000..21dfc632fc281
--- /dev/null
+++ b/polly/include/polly/Support/DumpFunctionPass.h
@@ -0,0 +1,43 @@
+//===------ DumpFunctionPass.cpp --------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Write a function to a file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef POLLY_SUPPORT_DUMPFUNCTIONPASS_H
+#define POLLY_SUPPORT_DUMPFUNCTIONPASS_H
+
+#include "llvm/IR/PassManager.h"
+#include <string>
+
+namespace llvm {
+class ModulePass;
+} // namespace llvm
+
+namespace polly {
+llvm::FunctionPass *createDumpFunctionWrapperPass(std::string Suffix);
+
+/// A pass that isolates a function into a new Module and writes it into a file.
+struct DumpFunctionPass : llvm::PassInfoMixin<DumpFunctionPass> {
+  std::string Suffix;
+
+  DumpFunctionPass(std::string Suffix) : Suffix(std::move(Suffix)) {}
+
+  llvm::PreservedAnalyses run(llvm::Function &F,
+                              llvm::FunctionAnalysisManager &AM);
+};
+
+} // namespace polly
+
+namespace llvm {
+class PassRegistry;
+void initializeDumpFunctionWrapperPassPass(llvm::PassRegistry &);
+} // namespace llvm
+
+#endif /* POLLY_SUPPORT_DUMPFUNCTIONPASS_H */

diff  --git a/polly/lib/CMakeLists.txt b/polly/lib/CMakeLists.txt
index 65fed2634ab85..9a967b106ea65 100644
--- a/polly/lib/CMakeLists.txt
+++ b/polly/lib/CMakeLists.txt
@@ -83,6 +83,7 @@ add_llvm_pass_plugin(Polly
   Support/ScopLocation.cpp
   Support/ISLTools.cpp
   Support/DumpModulePass.cpp
+  Support/DumpFunctionPass.cpp
   Support/VirtualInstruction.cpp
   Transform/Canonicalization.cpp
   Transform/CodePreparation.cpp

diff  --git a/polly/lib/Support/DumpFunctionPass.cpp b/polly/lib/Support/DumpFunctionPass.cpp
new file mode 100644
index 0000000000000..313fc71159348
--- /dev/null
+++ b/polly/lib/Support/DumpFunctionPass.cpp
@@ -0,0 +1,121 @@
+//===------ DumpFunctionPass.cpp --------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Write a function to a file.
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/Support/DumpFunctionPass.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Transforms/IPO/GlobalDCE.h"
+#include "llvm/Transforms/IPO/StripDeadPrototypes.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+
+#define DEBUG_TYPE "polly-dump-func"
+
+using namespace llvm;
+using namespace polly;
+
+namespace {
+
+static void runDumpFunction(llvm::Function &F, StringRef Suffix) {
+  StringRef FName = F.getName();
+  Module *M = F.getParent();
+
+  StringRef ModuleName = M->getName();
+  StringRef Stem = sys::path::stem(ModuleName);
+  std::string Dumpfile = (Twine(Stem) + "-" + FName + Suffix + ".ll").str();
+  LLVM_DEBUG(dbgs() << "Dumping function '" << FName << "' to '" << Dumpfile
+                    << "'...\n");
+
+  ValueToValueMapTy VMap;
+  auto ShouldCloneDefinition = [&F](const GlobalValue *GV) -> bool {
+    return GV == &F;
+  };
+  std::unique_ptr<Module> CM = CloneModule(*M, VMap, ShouldCloneDefinition);
+
+  LLVM_DEBUG(dbgs() << "Global DCE...\n");
+
+  {
+    ModuleAnalysisManager MAM;
+    ModulePassManager MPM;
+
+    PassInstrumentationCallbacks PIC;
+    MAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
+
+    MPM.addPass(GlobalDCEPass());
+    MPM.addPass(StripDeadPrototypesPass());
+    MPM.run(*CM, MAM);
+  }
+
+  LLVM_DEBUG(dbgs() << "Write to file '" << 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;
+  }
+
+  CM->print(Out->os(), nullptr);
+  Out->keep();
+  LLVM_DEBUG(dbgs() << "Dump file " << Dumpfile << " written successfully\n");
+}
+
+class DumpFunctionWrapperPass : public FunctionPass {
+private:
+  DumpFunctionWrapperPass(const DumpFunctionWrapperPass &) = delete;
+  const DumpFunctionWrapperPass &
+  operator=(const DumpFunctionWrapperPass &) = delete;
+
+  std::string Suffix;
+
+public:
+  static char ID;
+
+  explicit DumpFunctionWrapperPass() : FunctionPass(ID), Suffix("-dump") {}
+
+  explicit DumpFunctionWrapperPass(std::string Suffix)
+      : FunctionPass(ID), Suffix(std::move(Suffix)) {}
+
+  /// @name FunctionPass interface
+  //@{
+  virtual void getAnalysisUsage(llvm::AnalysisUsage &AU) const override {
+    AU.setPreservesAll();
+  }
+
+  virtual bool runOnFunction(llvm::Function &F) override {
+    runDumpFunction(F, Suffix);
+    return false;
+  }
+  //@}
+};
+
+char DumpFunctionWrapperPass::ID;
+} // namespace
+
+FunctionPass *polly::createDumpFunctionWrapperPass(std::string Suffix) {
+  return new DumpFunctionWrapperPass(std::move(Suffix));
+}
+
+llvm::PreservedAnalyses DumpFunctionPass::run(Function &F,
+                                              FunctionAnalysisManager &AM) {
+  runDumpFunction(F, Suffix);
+  return PreservedAnalyses::all();
+}
+
+INITIALIZE_PASS_BEGIN(DumpFunctionWrapperPass, "polly-dump-function",
+                      "Polly - Dump Function", false, false)
+INITIALIZE_PASS_END(DumpFunctionWrapperPass, "polly-dump-function",
+                    "Polly - Dump Function", false, false)

diff  --git a/polly/lib/Support/RegisterPasses.cpp b/polly/lib/Support/RegisterPasses.cpp
index f9475a2fe08b1..ebc0a7ee41ebe 100644
--- a/polly/lib/Support/RegisterPasses.cpp
+++ b/polly/lib/Support/RegisterPasses.cpp
@@ -36,6 +36,7 @@
 #include "polly/ScopDetection.h"
 #include "polly/ScopInfo.h"
 #include "polly/Simplify.h"
+#include "polly/Support/DumpFunctionPass.h"
 #include "polly/Support/DumpModulePass.h"
 #include "llvm/Analysis/CFGPrinter.h"
 #include "llvm/IR/LegacyPassManager.h"
@@ -610,19 +611,19 @@ static void buildLatePollyPipeline(FunctionPassManager &PM,
     return;
 
   if (DumpBefore)
-    report_fatal_error("Option -polly-dump-before not supported with NPM",
-                       false);
+    PM.addPass(DumpFunctionPass("-before"));
   if (!DumpBeforeFile.empty())
-    report_fatal_error("Option -polly-dump-before-file not supported with NPM",
+    report_fatal_error("Option -polly-dump-before-file at -polly-position=late "
+                       "not supported with NPM",
                        false);
 
   buildCommonPollyPipeline(PM, Level, EnableForOpt);
 
   if (DumpAfter)
-    report_fatal_error("Option -polly-dump-after not supported with NPM",
-                       false);
+    PM.addPass(DumpFunctionPass("-after"));
   if (!DumpAfterFile.empty())
-    report_fatal_error("Option -polly-dump-after-file not supported with NPM",
+    report_fatal_error("Option -polly-dump-after-file at -polly-position=late "
+                       "not supported with NPM",
                        false);
 }
 

diff  --git a/polly/test/Support/dumpfunction.ll b/polly/test/Support/dumpfunction.ll
new file mode 100644
index 0000000000000..70b586bd244b1
--- /dev/null
+++ b/polly/test/Support/dumpfunction.ll
@@ -0,0 +1,94 @@
+; New pass manager
+; RUN: opt %loadPolly -enable-new-pm=1 -O3 -polly -polly-position=before-vectorizer -polly-dump-before --disable-output %s 
+; RUN: FileCheck --input-file=dumpfunction-callee-before.ll --check-prefix=CHECK --check-prefix=CALLEE %s
+; RUN: FileCheck --input-file=dumpfunction-caller-before.ll --check-prefix=CHECK --check-prefix=CALLER %s
+;
+; RUN: opt %loadPolly -enable-new-pm=1 -O3 -polly -polly-position=before-vectorizer -polly-dump-after  --disable-output %s
+; RUN: FileCheck --input-file=dumpfunction-callee-before.ll --check-prefix=CHECK --check-prefix=CALLEE %s
+; RUN: FileCheck --input-file=dumpfunction-caller-before.ll --check-prefix=CHECK --check-prefix=CALLER %s
+
+; 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);
+; }
+
+
+%unrelated_type = type { i32 }
+
+ at callee_alias = dso_local unnamed_addr alias void(i32, double*, i32), void(i32, double*, i32 )* @callee
+
+define 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_alias(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
+}
+
+
+declare void @unrelated_decl()
+
+
+!llvm.ident = !{!8}
+!8 = !{!"xyxxy"}
+
+
+; CHECK-NOT: unrelated_type
+
+; CALLEE-LABEL: @callee(
+; CALLEE-NOT: @caller
+; CALLEE-NOT: @unrelated_decl
+
+; CALLER-NOT: @callee(
+; CALLER-LABEL: @caller(
+
+; CHECK-NOT: @unrelated_decl
+; CHECK: xyxxy


        


More information about the llvm-commits mailing list