[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