[llvm] 9342110 - Add NoOpLoopNestPass and LOOPNEST_PASS macro
Whitney Tsang via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 5 09:11:56 PDT 2021
Author: Whitney Tsang
Date: 2021-11-05T16:11:48Z
New Revision: 93421108d2551f91eb33a8c95bc94661ba953b64
URL: https://github.com/llvm/llvm-project/commit/93421108d2551f91eb33a8c95bc94661ba953b64
DIFF: https://github.com/llvm/llvm-project/commit/93421108d2551f91eb33a8c95bc94661ba953b64.diff
LOG: Add NoOpLoopNestPass and LOOPNEST_PASS macro
Having a NoOpLoopNestPass can ensure that only outermost loop is invoked
for a LoopNestPass with a lit test.
There are some existing passes that are implemented as LoopNestPass, but
they are still using LOOP_PASS macro.
It would be easier to identify LoopNestPasses with a LOOPNEST_PASS
macro.
Differential Revision: https://reviews.llvm.org/D113185
Added:
llvm/test/Other/loopnest-pass-ordering.ll
Modified:
llvm/lib/Passes/PassBuilder.cpp
llvm/lib/Passes/PassRegistry.def
llvm/test/Other/print-passes.ll
Removed:
################################################################################
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 40a885fe88d47..5056aef8069e8 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -319,6 +319,15 @@ class NoOpFunctionAnalysis : public AnalysisInfoMixin<NoOpFunctionAnalysis> {
static StringRef name() { return "NoOpFunctionAnalysis"; }
};
+/// No-op loop nest pass which does nothing.
+struct NoOpLoopNestPass : PassInfoMixin<NoOpLoopNestPass> {
+ PreservedAnalyses run(LoopNest &L, LoopAnalysisManager &,
+ LoopStandardAnalysisResults &, LPMUpdater &) {
+ return PreservedAnalyses::all();
+ }
+ static StringRef name() { return "NoOpLoopNestPass"; }
+};
+
/// No-op loop pass which does nothing.
struct NoOpLoopPass : PassInfoMixin<NoOpLoopPass> {
PreservedAnalyses run(Loop &L, LoopAnalysisManager &,
@@ -378,6 +387,8 @@ PassBuilder::PassBuilder(TargetMachine *TM, PipelineTuningOptions PTO,
PIC->addClassToPassName(CLASS, NAME);
#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
+#define LOOPNEST_PASS(NAME, CREATE_PASS) \
+ PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
#define LOOP_PASS(NAME, CREATE_PASS) \
PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
@@ -907,6 +918,28 @@ static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
return callbacksAcceptPassName<FunctionPassManager>(Name, Callbacks);
}
+template <typename CallbacksT>
+static bool isLoopNestPassName(StringRef Name, CallbacksT &Callbacks,
+ bool &UseMemorySSA) {
+ UseMemorySSA = false;
+
+ // Explicitly handle custom-parsed pass names.
+ if (parseRepeatPassName(Name))
+ return true;
+
+ if (Name == "lnicm") {
+ UseMemorySSA = true;
+ return true;
+ }
+
+#define LOOPNEST_PASS(NAME, CREATE_PASS) \
+ if (Name == NAME) \
+ return true;
+#include "PassRegistry.def"
+
+ return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
+}
+
template <typename CallbacksT>
static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks,
bool &UseMemorySSA) {
@@ -1140,6 +1173,12 @@ Error PassBuilder::parseModulePass(ModulePassManager &MPM,
MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
return Error::success(); \
}
+#define LOOPNEST_PASS(NAME, CREATE_PASS) \
+ if (Name == NAME) { \
+ MPM.addPass(createModuleToFunctionPassAdaptor( \
+ createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
+ return Error::success(); \
+ }
#define LOOP_PASS(NAME, CREATE_PASS) \
if (Name == NAME) { \
MPM.addPass(createModuleToFunctionPassAdaptor( \
@@ -1256,6 +1295,12 @@ Error PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM,
CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
return Error::success(); \
}
+#define LOOPNEST_PASS(NAME, CREATE_PASS) \
+ if (Name == NAME) { \
+ CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
+ createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
+ return Error::success(); \
+ }
#define LOOP_PASS(NAME, CREATE_PASS) \
if (Name == NAME) { \
CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
@@ -1360,6 +1405,11 @@ Error PassBuilder::parseFunctionPass(FunctionPassManager &FPM,
// bool UseMemorySSA = !("canon-freeze" || "loop-predication" ||
// "guard-widening");
// The risk is that it may become obsolete if we're not careful.
+#define LOOPNEST_PASS(NAME, CREATE_PASS) \
+ if (Name == NAME) { \
+ FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false, false)); \
+ return Error::success(); \
+ }
#define LOOP_PASS(NAME, CREATE_PASS) \
if (Name == NAME) { \
FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false, false)); \
@@ -1418,6 +1468,11 @@ Error PassBuilder::parseLoopPass(LoopPassManager &LPM,
}
// Now expand the basic registered passes from the .inc file.
+#define LOOPNEST_PASS(NAME, CREATE_PASS) \
+ if (Name == NAME) { \
+ LPM.addPass(CREATE_PASS); \
+ return Error::success(); \
+ }
#define LOOP_PASS(NAME, CREATE_PASS) \
if (Name == NAME) { \
LPM.addPass(CREATE_PASS); \
@@ -1545,6 +1600,10 @@ Error PassBuilder::parsePassPipeline(ModulePassManager &MPM,
} else if (isFunctionPassName(FirstName,
FunctionPipelineParsingCallbacks)) {
Pipeline = {{"function", std::move(*Pipeline)}};
+ } else if (isLoopNestPassName(FirstName, LoopPipelineParsingCallbacks,
+ UseMemorySSA)) {
+ Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
+ std::move(*Pipeline)}}}};
} else if (isLoopPassName(FirstName, LoopPipelineParsingCallbacks,
UseMemorySSA)) {
Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
@@ -1739,6 +1798,10 @@ void PassBuilder::printPassNames(raw_ostream &OS) {
OS << "Function alias analyses:\n";
#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
+#include "PassRegistry.def"
+
+ OS << "LoopNest passes:\n";
+#define LOOPNEST_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
#include "PassRegistry.def"
OS << "Loop passes:\n";
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index 80ec9f839fd25..361cc1eb57de6 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -452,6 +452,16 @@ FUNCTION_PASS_WITH_PARAMS("print<stack-lifetime>",
"may;must")
#undef FUNCTION_PASS_WITH_PARAMS
+#ifndef LOOPNEST_PASS
+#define LOOPNEST_PASS(NAME, CREATE_PASS)
+#endif
+LOOPNEST_PASS("lnicm", LNICMPass())
+LOOPNEST_PASS("loop-flatten", LoopFlattenPass())
+LOOPNEST_PASS("loop-interchange", LoopInterchangePass())
+LOOPNEST_PASS("loop-unroll-and-jam", LoopUnrollAndJamPass())
+LOOPNEST_PASS("no-op-loopnest", NoOpLoopNestPass())
+#undef LOOPNEST_PASS
+
#ifndef LOOP_ANALYSIS
#define LOOP_ANALYSIS(NAME, CREATE_PASS)
#endif
@@ -469,11 +479,8 @@ LOOP_PASS("canon-freeze", CanonicalizeFreezeInLoopsPass())
LOOP_PASS("dot-ddg", DDGDotPrinterPass())
LOOP_PASS("invalidate<all>", InvalidateAllAnalysesPass())
LOOP_PASS("licm", LICMPass())
-LOOP_PASS("lnicm", LNICMPass())
-LOOP_PASS("loop-flatten", LoopFlattenPass())
LOOP_PASS("loop-idiom", LoopIdiomRecognizePass())
LOOP_PASS("loop-instsimplify", LoopInstSimplifyPass())
-LOOP_PASS("loop-interchange", LoopInterchangePass())
LOOP_PASS("loop-rotate", LoopRotatePass())
LOOP_PASS("no-op-loop", NoOpLoopPass())
LOOP_PASS("print", PrintLoopPass(dbgs()))
@@ -481,7 +488,6 @@ LOOP_PASS("loop-deletion", LoopDeletionPass())
LOOP_PASS("loop-simplifycfg", LoopSimplifyCFGPass())
LOOP_PASS("loop-reduce", LoopStrengthReducePass())
LOOP_PASS("indvars", IndVarSimplifyPass())
-LOOP_PASS("loop-unroll-and-jam", LoopUnrollAndJamPass())
LOOP_PASS("loop-unroll-full", LoopFullUnrollPass())
LOOP_PASS("print-access-info", LoopAccessInfoPrinterPass(dbgs()))
LOOP_PASS("print<ddg>", DDGAnalysisPrinterPass(dbgs()))
diff --git a/llvm/test/Other/loopnest-pass-ordering.ll b/llvm/test/Other/loopnest-pass-ordering.ll
new file mode 100644
index 0000000000000..4f176a8094c61
--- /dev/null
+++ b/llvm/test/Other/loopnest-pass-ordering.ll
@@ -0,0 +1,34 @@
+; RUN: opt -disable-output -debug-pass-manager \
+; RUN: -passes='no-op-loopnest' %s 2>&1 \
+; RUN: | FileCheck %s
+
+; @f()
+; / \
+; loop.0 loop.1
+; / \ \
+; loop.0.0 loop.0.1 loop.1.0
+;
+; CHECK: Running pass: NoOpLoopNestPass on Loop at depth 1 containing: %loop.0<header><exiting>,%loop.0.0,%loop.0.1,%loop.0.1.preheader,%loop.0.loopexit<latch>,%loop.0.0.preheader
+; CHECK: Running pass: NoOpLoopNestPass on Loop at depth 1 containing: %loop.1<header>,%loop.1.bb1,%loop.1.bb2<exiting>,%loop.1.0,%loop.1.0.preheader,%loop.1.loopexit,%loop.1.backedge<latch>
+; CHECK-NOT: Running pass: NoOpLoopNestPass on Loop at depth 2
+
+define void @f() {
+entry:
+ br label %loop.0
+loop.0:
+ br i1 undef, label %loop.0.0, label %loop.1
+loop.0.0:
+ br i1 undef, label %loop.0.0, label %loop.0.1
+loop.0.1:
+ br i1 undef, label %loop.0.1, label %loop.0
+loop.1:
+ br i1 undef, label %loop.1, label %loop.1.bb1
+loop.1.bb1:
+ br i1 undef, label %loop.1, label %loop.1.bb2
+loop.1.bb2:
+ br i1 undef, label %end, label %loop.1.0
+loop.1.0:
+ br i1 undef, label %loop.1.0, label %loop.1
+end:
+ ret void
+}
diff --git a/llvm/test/Other/print-passes.ll b/llvm/test/Other/print-passes.ll
index 09db6e9678387..955a0cd225468 100644
--- a/llvm/test/Other/print-passes.ll
+++ b/llvm/test/Other/print-passes.ll
@@ -18,6 +18,8 @@
; CHECK: no-op-function
; CHECK: Function alias analyses:
; CHECK: basic-aa
+; CHECK: LoopNest passes:
+; CHECK: no-op-loopnest
; CHECK: Loop passes:
; CHECK: no-op-loop
; CHECK: Loop passes with params:
More information about the llvm-commits
mailing list