[MachineFunctionPass] Support -filter-passes for -print-changed
[MachineFunctionPass] Support -filter-passes for -print-changed -filter-passes specifies a `PassID` (a lower-case dashed-separated pass name, also used by -print-after, -stop-after, etc) instead of a CamelCasePass. `-filter-passes=CamelCaseNewPMPass` seems like a workaround for new PM passes before we can use lower-case dashed-separated pass names (as used by `-passes=`). Example: ``` # getPassName() is "IRTranslator". PassID is "irtranslator" llc -mtriple=aarch64 -print-changed -filter-passes=irtranslator < print-changed-machine.ll ``` Close https://github.com/llvm/llvm-project/issues/57453 Reviewed By: aeubanks Differential Revision: https://reviews.llvm.org/D133055
This commit is contained in:
parent
c0433f91d3
commit
8d95fd7e56
|
@ -51,6 +51,9 @@ std::vector<std::string> printAfterPasses();
|
|||
// Returns true if we should always print the entire module.
|
||||
bool forcePrintModuleIR();
|
||||
|
||||
// Return true if -filter-passes is empty or contains the pass name.
|
||||
bool isPassInPrintList(StringRef PassName);
|
||||
|
||||
// Returns true if we should print the function.
|
||||
bool isFunctionInPrintList(StringRef FunctionName);
|
||||
|
||||
|
|
|
@ -73,10 +73,14 @@ bool MachineFunctionPass::runOnFunction(Function &F) {
|
|||
|
||||
// For --print-changed, if the function name is a candidate, save the
|
||||
// serialized MF to be compared later.
|
||||
// TODO Implement --filter-passes.
|
||||
SmallString<0> BeforeStr, AfterStr;
|
||||
bool ShouldPrintChanged = PrintChanged != ChangePrinter::None &&
|
||||
isFunctionInPrintList(MF.getName());
|
||||
StringRef PassID;
|
||||
if (const PassInfo *PI = Pass::lookupPassInfo(getPassID()))
|
||||
PassID = PI->getPassArgument();
|
||||
const bool IsInterestingPass = isPassInPrintList(PassID);
|
||||
const bool ShouldPrintChanged = PrintChanged != ChangePrinter::None &&
|
||||
IsInterestingPass &&
|
||||
isFunctionInPrintList(MF.getName());
|
||||
if (ShouldPrintChanged) {
|
||||
raw_svector_ostream OS(BeforeStr);
|
||||
MF.print(OS);
|
||||
|
@ -112,15 +116,14 @@ bool MachineFunctionPass::runOnFunction(Function &F) {
|
|||
|
||||
// For --print-changed, print if the serialized MF has changed. Modes other
|
||||
// than quiet/verbose are unimplemented and treated the same as 'quiet'.
|
||||
if (ShouldPrintChanged) {
|
||||
raw_svector_ostream OS(AfterStr);
|
||||
MF.print(OS);
|
||||
if (BeforeStr != AfterStr) {
|
||||
StringRef Arg;
|
||||
if (const PassInfo *PI = Pass::lookupPassInfo(getPassID()))
|
||||
Arg = PI->getPassArgument();
|
||||
errs() << ("*** IR Dump After " + getPassName() + " (" + Arg + ") on " +
|
||||
MF.getName() + " ***\n");
|
||||
if (ShouldPrintChanged || !IsInterestingPass) {
|
||||
if (ShouldPrintChanged) {
|
||||
raw_svector_ostream OS(AfterStr);
|
||||
MF.print(OS);
|
||||
}
|
||||
if (IsInterestingPass && BeforeStr != AfterStr) {
|
||||
errs() << ("*** IR Dump After " + getPassName() + " (" + PassID +
|
||||
") on " + MF.getName() + " ***\n");
|
||||
switch (PrintChanged) {
|
||||
case ChangePrinter::None:
|
||||
llvm_unreachable("");
|
||||
|
@ -148,8 +151,12 @@ bool MachineFunctionPass::runOnFunction(Function &F) {
|
|||
ChangePrinter::DiffVerbose,
|
||||
ChangePrinter::ColourDiffVerbose},
|
||||
PrintChanged.getValue())) {
|
||||
errs() << ("*** IR Dump After " + getPassName() + " on " + MF.getName() +
|
||||
" omitted because no change ***\n");
|
||||
const char *Reason =
|
||||
IsInterestingPass ? " omitted because no change" : " filtered out";
|
||||
errs() << "*** IR Dump After " << getPassName();
|
||||
if (!PassID.empty())
|
||||
errs() << " (" << PassID << ")";
|
||||
errs() << " on " << MF.getName() + Reason + " ***\n";
|
||||
}
|
||||
}
|
||||
return RV;
|
||||
|
|
|
@ -87,6 +87,14 @@ static cl::opt<bool>
|
|||
"always print a module IR"),
|
||||
cl::init(false), cl::Hidden);
|
||||
|
||||
// See the description for -print-changed for an explanation of the use
|
||||
// of this option.
|
||||
static cl::list<std::string> FilterPasses(
|
||||
"filter-passes", cl::value_desc("pass names"),
|
||||
cl::desc("Only consider IR changes for passes whose names "
|
||||
"match the specified value. No-op without -print-changed"),
|
||||
cl::CommaSeparated, cl::Hidden);
|
||||
|
||||
static cl::list<std::string>
|
||||
PrintFuncsList("filter-print-funcs", cl::value_desc("function names"),
|
||||
cl::desc("Only print IR for functions whose name "
|
||||
|
@ -132,6 +140,12 @@ std::vector<std::string> llvm::printAfterPasses() {
|
|||
|
||||
bool llvm::forcePrintModuleIR() { return PrintModuleScope; }
|
||||
|
||||
bool llvm::isPassInPrintList(StringRef PassName) {
|
||||
static std::unordered_set<std::string> Set(FilterPasses.begin(),
|
||||
FilterPasses.end());
|
||||
return Set.empty() || Set.count(std::string(PassName));
|
||||
}
|
||||
|
||||
bool llvm::isFunctionInPrintList(StringRef FunctionName) {
|
||||
static std::unordered_set<std::string> PrintFuncNames(PrintFuncsList.begin(),
|
||||
PrintFuncsList.end());
|
||||
|
|
|
@ -56,14 +56,6 @@ cl::opt<bool> PreservedCFGCheckerInstrumentation::VerifyPreservedCFG(
|
|||
// An option that supports the -print-changed option. See
|
||||
// the description for -print-changed for an explanation of the use
|
||||
// of this option. Note that this option has no effect without -print-changed.
|
||||
static cl::list<std::string>
|
||||
PrintPassesList("filter-passes", cl::value_desc("pass names"),
|
||||
cl::desc("Only consider IR changes for passes whose names "
|
||||
"match for the print-changed option"),
|
||||
cl::CommaSeparated, cl::Hidden);
|
||||
// An option that supports the -print-changed option. See
|
||||
// the description for -print-changed for an explanation of the use
|
||||
// of this option. Note that this option has no effect without -print-changed.
|
||||
static cl::opt<bool>
|
||||
PrintChangedBefore("print-before-changed",
|
||||
cl::desc("Print before passes that change them"),
|
||||
|
@ -321,19 +313,10 @@ bool isInterestingFunction(const Function &F) {
|
|||
return isFunctionInPrintList(F.getName());
|
||||
}
|
||||
|
||||
bool isInterestingPass(StringRef PassID) {
|
||||
if (isIgnored(PassID))
|
||||
return false;
|
||||
|
||||
static std::unordered_set<std::string> PrintPassNames(PrintPassesList.begin(),
|
||||
PrintPassesList.end());
|
||||
return PrintPassNames.empty() || PrintPassNames.count(PassID.str());
|
||||
}
|
||||
|
||||
// Return true when this is a pass on IR for which printing
|
||||
// of changes is desired.
|
||||
bool isInteresting(Any IR, StringRef PassID) {
|
||||
if (!isInterestingPass(PassID))
|
||||
if (isIgnored(PassID) || !isPassInPrintList(PassID))
|
||||
return false;
|
||||
if (any_isa<const Function *>(IR))
|
||||
return isInterestingFunction(*any_cast<const Function *>(IR));
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
; RUN: llc -filetype=null -mtriple=aarch64 -O0 -print-changed=cdiff %s 2>&1 | FileCheck %s --check-prefixes=CDIFF,VERBOSE
|
||||
; RUN: llc -filetype=null -mtriple=aarch64 -O0 -print-changed=cdiff-quiet %s 2>&1 | FileCheck %s --check-prefixes=CDIFF,QUIET
|
||||
|
||||
; VERBOSE: *** IR Dump After AArch64O0PreLegalizerCombiner on foo omitted because no change ***
|
||||
; VERBOSE: *** IR Dump After AArch64O0PreLegalizerCombiner (aarch64-O0-prelegalizer-combiner) on foo omitted because no change ***
|
||||
; QUIET-NOT: *** {{.*}} omitted because no change ***
|
||||
|
||||
; DIFF: *** IR Dump After Legalizer (legalizer) on foo ***
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
; VERBOSE-NEXT: Function Live Ins: $w0
|
||||
; VERBOSE-EMPTY:
|
||||
; VERBOSE-NEXT: bb.1.entry:
|
||||
; VERBOSE: *** IR Dump After Analysis for ComputingKnownBits on foo omitted because no change ***
|
||||
; VERBOSE-NEXT: *** IR Dump After AArch64O0PreLegalizerCombiner on foo omitted because no change ***
|
||||
; VERBOSE: *** IR Dump After Analysis for ComputingKnownBits (gisel-known-bits) on foo omitted because no change ***
|
||||
; VERBOSE-NEXT: *** IR Dump After AArch64O0PreLegalizerCombiner (aarch64-O0-prelegalizer-combiner) on foo omitted because no change ***
|
||||
; VERBOSE: *** IR Dump After Legalizer (legalizer) on foo ***
|
||||
; VERBOSE-NEXT: # Machine code for function foo: IsSSA, TracksLiveness, Legalized
|
||||
; VERBOSE-NEXT: Function Live Ins: $w0
|
||||
|
@ -24,6 +24,19 @@
|
|||
; QUIET-NOT: ***
|
||||
; QUIET: *** IR Dump After Legalizer (legalizer) on foo ***
|
||||
|
||||
; RUN: llc -filetype=null -mtriple=aarch64 -O0 -print-changed -filter-passes=irtranslator,legalizer %s 2>&1 | \
|
||||
; RUN: FileCheck %s --check-prefixes=VERBOSE-FILTER
|
||||
; RUN: llc -filetype=null -mtriple=aarch64 -O0 -print-changed=quiet -filter-passes=irtranslator %s 2>&1 | \
|
||||
; RUN: FileCheck %s --check-prefixes=QUIET-FILTER --implicit-check-not='IR Dump'
|
||||
|
||||
; VERBOSE-FILTER: *** IR Dump After IRTranslator (irtranslator) on foo ***
|
||||
; VERBOSE-FILTER: *** IR Dump After AArch64O0PreLegalizerCombiner (aarch64-O0-prelegalizer-combiner) on foo filtered out ***
|
||||
; VERBOSE-FILTER: *** IR Dump After Legalizer (legalizer) on foo ***
|
||||
; VERBOSE-FILTER-NOT: *** IR Dump After {{.*}} () on
|
||||
|
||||
; QUIET-FILTER: *** IR Dump After IRTranslator (irtranslator) on foo ***
|
||||
; QUIET-FILTER: *** IR Dump After IRTranslator (irtranslator) on bar ***
|
||||
|
||||
;; dot-cfg/dot-cfg-quiet are unimplemented. Currently they behave like 'quiet'.
|
||||
; RUN: llc -filetype=null -mtriple=aarch64 -O0 -print-changed=dot-cfg %s 2>&1 | FileCheck %s --check-prefix=QUIET
|
||||
|
||||
|
|
Loading…
Reference in New Issue