From 6cdbedb38b38f2c144ff521519f8179067ab2b47 Mon Sep 17 00:00:00 2001 From: Bjorn Pettersson Date: Mon, 28 Jun 2021 00:22:11 +0200 Subject: [PATCH] [NewPM] Handle passes with params in -print-before/-print-after To support options like -print-before= and -print-after= the PassBuilder will register PassInstrumentation callbacks as well as a mapping between internal pass class names and the pass names used in those options (and other cmd line interfaces). But for some reason all the passes that takes options where missing in those maps, so for example "-print-after=loop-vectorize" didn't work. This patch will add the missing entries by also taking care of function and loop passes with params when setting up the class to pass name maps. One might notice that even with this patch it might be tricky to know what pass name to use in options such as -print-after. This because there only is a single mapping from class name to pass name, while the PassRegistry currently is a bit messy as it sometimes reuses the same class for different pass names (without using the "pass with params" scheme, or the pass-name syntax). It gets extra messy in some situations. For example the MemorySanitizerPass can run like this (with debug and print-after) opt -passes='kmsan' -print-after=msan-module -debug-only=msan The 'kmsan' alias for 'msan' is just confusing as one might think that 'kmsan' is a separate pass (but the DEBUG_TYPE is still just 'msan'). And since the module pass version of the pass adds a mapping from 'MemorySanitizerPass' to 'msan-module' one need to use 'msan-module' in the print-before and print-after options. Reviewed By: ychen Differential Revision: https://reviews.llvm.org/D105006 --- lib/IR/PassInstrumentation.cpp | 3 ++- lib/Passes/PassBuilder.cpp | 26 +++++++++++++++----------- lib/Passes/PassRegistry.def | 12 ++++++++++-- test/Other/print-before-after.ll | 25 ++++++++++++++++++++++++- 4 files changed, 51 insertions(+), 15 deletions(-) diff --git a/lib/IR/PassInstrumentation.cpp b/lib/IR/PassInstrumentation.cpp index 56a36db21e2..d85cefbbe6f 100644 --- a/lib/IR/PassInstrumentation.cpp +++ b/lib/IR/PassInstrumentation.cpp @@ -19,7 +19,8 @@ namespace llvm { void PassInstrumentationCallbacks::addClassToPassName(StringRef ClassName, StringRef PassName) { - ClassToPassName[ClassName] = PassName.str(); + if (ClassToPassName[ClassName].empty()) + ClassToPassName[ClassName] = PassName.str(); } StringRef diff --git a/lib/Passes/PassBuilder.cpp b/lib/Passes/PassBuilder.cpp index c9dd5a6abcd..a5b7e7d3f42 100644 --- a/lib/Passes/PassBuilder.cpp +++ b/lib/Passes/PassBuilder.cpp @@ -456,10 +456,14 @@ PassBuilder::PassBuilder(TargetMachine *TM, PipelineTuningOptions PTO, PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME); #define FUNCTION_PASS(NAME, CREATE_PASS) \ PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME); +#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \ + PIC->addClassToPassName(CLASS, NAME); #define FUNCTION_ANALYSIS(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) \ + PIC->addClassToPassName(CLASS, NAME); #define LOOP_ANALYSIS(NAME, CREATE_PASS) \ PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME); #define CGSCC_PASS(NAME, CREATE_PASS) \ @@ -2410,7 +2414,7 @@ static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks) { #define FUNCTION_PASS(NAME, CREATE_PASS) \ if (Name == NAME) \ return true; -#define FUNCTION_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER, PARAMS) \ +#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \ if (checkParametrizedPassName(Name, NAME)) \ return true; #define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \ @@ -2434,7 +2438,7 @@ static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks) { #define LOOP_PASS(NAME, CREATE_PASS) \ if (Name == NAME) \ return true; -#define LOOP_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER, PARAMS) \ +#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \ if (checkParametrizedPassName(Name, NAME)) \ return true; #define LOOP_ANALYSIS(NAME, CREATE_PASS) \ @@ -2624,7 +2628,7 @@ Error PassBuilder::parseModulePass(ModulePassManager &MPM, MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS)); \ return Error::success(); \ } -#define FUNCTION_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER, PARAMS) \ +#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \ if (checkParametrizedPassName(Name, NAME)) { \ auto Params = parsePassParameters(PARSER, Name, NAME); \ if (!Params) \ @@ -2638,7 +2642,7 @@ Error PassBuilder::parseModulePass(ModulePassManager &MPM, createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \ return Error::success(); \ } -#define LOOP_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER, PARAMS) \ +#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \ if (checkParametrizedPassName(Name, NAME)) { \ auto Params = parsePassParameters(PARSER, Name, NAME); \ if (!Params) \ @@ -2731,7 +2735,7 @@ Error PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM, CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS)); \ return Error::success(); \ } -#define FUNCTION_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER, PARAMS) \ +#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \ if (checkParametrizedPassName(Name, NAME)) { \ auto Params = parsePassParameters(PARSER, Name, NAME); \ if (!Params) \ @@ -2745,7 +2749,7 @@ Error PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM, createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \ return Error::success(); \ } -#define LOOP_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER, PARAMS) \ +#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \ if (checkParametrizedPassName(Name, NAME)) { \ auto Params = parsePassParameters(PARSER, Name, NAME); \ if (!Params) \ @@ -2816,7 +2820,7 @@ Error PassBuilder::parseFunctionPass(FunctionPassManager &FPM, FPM.addPass(CREATE_PASS); \ return Error::success(); \ } -#define FUNCTION_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER, PARAMS) \ +#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \ if (checkParametrizedPassName(Name, NAME)) { \ auto Params = parsePassParameters(PARSER, Name, NAME); \ if (!Params) \ @@ -2845,7 +2849,7 @@ Error PassBuilder::parseFunctionPass(FunctionPassManager &FPM, FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false, false)); \ return Error::success(); \ } -#define LOOP_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER, PARAMS) \ +#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \ if (checkParametrizedPassName(Name, NAME)) { \ auto Params = parsePassParameters(PARSER, Name, NAME); \ if (!Params) \ @@ -2903,7 +2907,7 @@ Error PassBuilder::parseLoopPass(LoopPassManager &LPM, LPM.addPass(CREATE_PASS); \ return Error::success(); \ } -#define LOOP_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER, PARAMS) \ +#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \ if (checkParametrizedPassName(Name, NAME)) { \ auto Params = parsePassParameters(PARSER, Name, NAME); \ if (!Params) \ @@ -3196,7 +3200,7 @@ void PassBuilder::printPassNames(raw_ostream &OS) { #include "PassRegistry.def" OS << "Function passes with params:\n"; -#define FUNCTION_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER, PARAMS) \ +#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \ printPassName(NAME, PARAMS, OS); #include "PassRegistry.def" @@ -3213,7 +3217,7 @@ void PassBuilder::printPassNames(raw_ostream &OS) { #include "PassRegistry.def" OS << "Loop passes with params:\n"; -#define LOOP_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER, PARAMS) \ +#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \ printPassName(NAME, PARAMS, OS); #include "PassRegistry.def" diff --git a/lib/Passes/PassRegistry.def b/lib/Passes/PassRegistry.def index 2a639ea9216..1a379c1abec 100644 --- a/lib/Passes/PassRegistry.def +++ b/lib/Passes/PassRegistry.def @@ -331,9 +331,10 @@ FUNCTION_PASS("memprof", MemProfilerPass()) #undef FUNCTION_PASS #ifndef FUNCTION_PASS_WITH_PARAMS -#define FUNCTION_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER, PARAMS) +#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) #endif FUNCTION_PASS_WITH_PARAMS("loop-unroll", + "LoopUnrollPass", [](LoopUnrollOptions Opts) { return LoopUnrollPass(Opts); }, @@ -345,12 +346,14 @@ FUNCTION_PASS_WITH_PARAMS("loop-unroll", "no-runtime;runtime;" "no-upperbound;upperbound") FUNCTION_PASS_WITH_PARAMS("msan", + "MemorySanitizerPass", [](MemorySanitizerOptions Opts) { return MemorySanitizerPass(Opts); }, parseMSanPassOptions, "recover;kernel;track-origins=N") FUNCTION_PASS_WITH_PARAMS("simplify-cfg", + "SimplifyCFGPass", [](SimplifyCFGOptions Opts) { return SimplifyCFGPass(Opts); }, @@ -363,6 +366,7 @@ FUNCTION_PASS_WITH_PARAMS("simplify-cfg", "bonus-inst-threshold=N" ) FUNCTION_PASS_WITH_PARAMS("loop-vectorize", + "LoopVectorizePass", [](LoopVectorizeOptions Opts) { return LoopVectorizePass(Opts); }, @@ -370,12 +374,14 @@ FUNCTION_PASS_WITH_PARAMS("loop-vectorize", "no-interleave-forced-only;interleave-forced-only;" "no-vectorize-forced-only;vectorize-forced-only") FUNCTION_PASS_WITH_PARAMS("mldst-motion", + "MergedLoadStoreMotionPass", [](MergedLoadStoreMotionOptions Opts) { return MergedLoadStoreMotionPass(Opts); }, parseMergedLoadStoreMotionOptions, "no-split-footer-bb;split-footer-bb") FUNCTION_PASS_WITH_PARAMS("gvn", + "GVN", [](GVNOptions Opts) { return GVN(Opts); }, @@ -385,6 +391,7 @@ FUNCTION_PASS_WITH_PARAMS("gvn", "no-split-backedge-load-pre;split-backedge-load-pre;" "no-memdep;memdep") FUNCTION_PASS_WITH_PARAMS("print", + "StackLifetimePrinterPass", [](StackLifetime::LivenessType Type) { return StackLifetimePrinterPass(dbgs(), Type); }, @@ -436,9 +443,10 @@ LOOP_PASS("loop-versioning-licm", LoopVersioningLICMPass()) #undef LOOP_PASS #ifndef LOOP_PASS_WITH_PARAMS -#define LOOP_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER, PARAMS) +#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) #endif LOOP_PASS_WITH_PARAMS("unswitch", + "SimpleLoopUnswitchPass", [](bool NonTrivial) { return SimpleLoopUnswitchPass(NonTrivial); }, diff --git a/test/Other/print-before-after.ll b/test/Other/print-before-after.ll index 41977929f74..b4287a1b034 100644 --- a/test/Other/print-before-after.ll +++ b/test/Other/print-before-after.ll @@ -8,6 +8,8 @@ ; RUN: opt < %s -disable-output -passes='no-op-function' -print-after=no-op-function 2>&1 | FileCheck %s --check-prefix=ONCE ; RUN: opt < %s -disable-output -passes='no-op-module,no-op-function' -print-before=no-op-function --print-module-scope 2>&1 | FileCheck %s --check-prefix=TWICE ; RUN: opt < %s -disable-output -passes='no-op-module,no-op-function' -print-after=no-op-function --print-module-scope 2>&1 | FileCheck %s --check-prefix=TWICE +; RUN: opt < %s -disable-output -passes='loop-vectorize' -print-before=loop-vectorize -print-after=loop-vectorize 2>&1 | FileCheck %s --check-prefix=CHECK-LV --allow-empty +; RUN: opt < %s -disable-output -passes='simple-loop-unswitch,unswitch' -print-before=unswitch -print-after=simple-loop-unswitch 2>&1 | FileCheck %s --check-prefix=CHECK-UNSWITCH --allow-empty ; NONE-NOT: @foo ; NONE-NOT: @bar @@ -24,10 +26,31 @@ ; TWICE-NOT: @foo ; TWICE-NOT: @bar +; Verify that we can handle function passes with params. +; CHECK-LV: *** IR Dump Before LoopVectorizePass on foo *** +; CHECK-LV: *** IR Dump After LoopVectorizePass on foo *** +; CHECK-LV: *** IR Dump Before LoopVectorizePass on bar *** +; CHECK-LV: *** IR Dump After LoopVectorizePass on bar *** + +; Verify that we can handle loop passes with params. + +; FIXME: The SimpleLoopUnswitchPass is extra complicated as we have different +; pass names mapping to the same class name. But we currently only use a 1-1 +; mapping, so we do not get the -print-before=unswitch printout here. So the +; NOT checks below is currently verifying the "faulty" behavior and we +; actually want to get those printout here in the future. +; CHECK-UNSWITCH-NOT: *** IR Dump Before SimpleLoopUnswitchPass on Loop at depth 1 containing +; CHECK-UNSWITCH: *** IR Dump After SimpleLoopUnswitchPass on Loop at depth 1 containing +; CHECK-UNSWITCH-NOT: *** IR Dump Before SimpleLoopUnswitchPass on Loop at depth 1 containing +; CHECK-UNSWITCH: *** IR Dump After SimpleLoopUnswitchPass on Loop at depth 1 containing + define void @foo() { ret void } define void @bar() { - ret void +entry: + br label %loop +loop: + br label %loop }