[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