Skip to content

Commit

Permalink
[MachineFunctionPass] Support -filter-passes for -print-changed
Browse files Browse the repository at this point in the history
[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 #57453

Reviewed By: aeubanks

Differential Revision: https://reviews.llvm.org/D133055
  • Loading branch information
MaskRay committed Sep 1, 2022
1 parent c0433f9 commit 8d95fd7
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 35 deletions.
3 changes: 3 additions & 0 deletions llvm/include/llvm/IR/PrintPasses.h
Expand Up @@ -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);

Expand Down
35 changes: 21 additions & 14 deletions llvm/lib/CodeGen/MachineFunctionPass.cpp
Expand Up @@ -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);
Expand Down Expand Up @@ -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("");
Expand Down Expand Up @@ -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;
Expand Down
14 changes: 14 additions & 0 deletions llvm/lib/IR/PrintPasses.cpp
Expand Up @@ -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 "
Expand Down Expand Up @@ -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());
Expand Down
19 changes: 1 addition & 18 deletions llvm/lib/Passes/StandardInstrumentations.cpp
Expand Up @@ -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"),
Expand Down Expand Up @@ -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));
Expand Down
Expand Up @@ -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 ***
Expand Down
17 changes: 15 additions & 2 deletions llvm/test/Other/print-changed-machine.ll
Expand Up @@ -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
Expand All @@ -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

Expand Down

0 comments on commit 8d95fd7

Please sign in to comment.