Add option to print entire function instead of just the loops for loo… (#123229)

print-after-all is useful for diffing IR between two passes. When one of
the two is a function pass, and the other is a loop pass, the diff
becomes useless. Add an option which prints the entire function for loop
passes.
This commit is contained in:
Akshay Deodhar 2025-01-17 17:55:54 -08:00 committed by GitHub
parent 9fdc38c81c
commit 5b6a26ccdd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 98 additions and 0 deletions

View File

@ -51,6 +51,9 @@ std::vector<std::string> printAfterPasses();
// Returns true if we should always print the entire module.
bool forcePrintModuleIR();
// Returns true if we should print the entire function for loop passes.
bool forcePrintFuncIR();
// Return true if -filter-passes is empty or contains the pass name.
bool isPassInPrintList(StringRef PassName);
bool isFilterPassesEmpty();

View File

@ -999,6 +999,18 @@ void llvm::printLoop(Loop &L, raw_ostream &OS, const std::string &Banner) {
return;
}
if (forcePrintFuncIR()) {
// handling -print-loop-func-scope.
// -print-module-scope overrides this.
OS << Banner << " (loop: ";
L.getHeader()->printAsOperand(OS, false);
OS << ")\n";
// printing whole function.
OS << *L.getHeader()->getParent();
return;
}
OS << Banner;
auto *PreHeader = L.getLoopPreheader();

View File

@ -88,6 +88,12 @@ static cl::opt<bool>
"always print a module IR"),
cl::init(false), cl::Hidden);
static cl::opt<bool> LoopPrintFuncScope(
"print-loop-func-scope",
cl::desc("When printing IR for print-[before|after]{-all} "
"for a loop pass, always print function 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(
@ -141,6 +147,8 @@ std::vector<std::string> llvm::printAfterPasses() {
bool llvm::forcePrintModuleIR() { return PrintModuleScope; }
bool llvm::forcePrintFuncIR() { return LoopPrintFuncScope; }
bool llvm::isPassInPrintList(StringRef PassName) {
static std::unordered_set<std::string> Set(FilterPasses.begin(),
FilterPasses.end());

View File

@ -0,0 +1,75 @@
; This test documents how the IR dumped for loop passes differs with -print-loop-func-scope
; and -print-module-scope
; - Without -print-loop-func-scope, dumps only the loop, with 3 sections- preheader,
; loop, and exit blocks
; - With -print-loop-func-scope, dumps only the function which contains the loop
; - With -print-module-scope, dumps the entire module containing the loop, and disregards
; the -print-loop-func-scope flag.
; RUN: opt < %s 2>&1 -disable-output \
; RUN: -passes=licm -print-after=licm \
; RUN: | FileCheck %s -check-prefix=VANILLA
; RUN: opt < %s 2>&1 -disable-output \
; RUN: -passes=licm -print-after=licm -print-loop-func-scope \
; RUN: | FileCheck %s -check-prefix=LOOPFUNC
; RUN: opt < %s 2>&1 -disable-output \
; RUN: -passes=licm -print-after=licm -print-module-scope \
; RUN: | FileCheck %s -check-prefix=MODULE
; RUN: opt < %s 2>&1 -disable-output \
; RUN: -passes=licm -print-after=licm -print-module-scope -print-loop-func-scope\
; RUN: | FileCheck %s -check-prefix=MODULEWITHLOOP
; VANILLA: IR Dump After LICMPass
; VANILLA-NOT: define void @foo
; VANILLA: Preheader:
; VANILLA: Loop:
; VANILLA: Exit blocks
; LOOPFUNC: IR Dump After LICMPass
; LOOPFUNC: (loop:
; LOOPFUNC: define void @foo
; LOOPFUNC-NOT: Preheader:
; LOOPFUNC-NOT: Loop:
; LOOPFUNC-NOT: Exit blocks
; MODULE: IR Dump After LICMPass
; MODULE: ModuleID =
; MODULE: define void @foo
; MODULE-NOT: Preheader:
; MODULE-NOT: Loop:
; MODULE-NOT: Exit blocks
; MODULE: define void @bar
; MODULE: declare void @baz(i32)
; MODULEWITHLOOP: IR Dump After LICMPass
; MODULEWITHLOOP: ModuleID =
; MODULEWITHLOOP: define void @foo
; MODULEWITHLOOP-NOT: Preheader:
; MODULEWITHLOOP-NOT: Loop:
; MODULEWITHLOOP-NOT: Exit blocks
; MODULEWITHLOOP: define void @bar
; MODULEWITHLOOP: declare void @baz(i32)
define void @foo(i32 %n) {
entry:
br label %loop_cond
loop_cond:
%i = phi i32 [ 0, %entry ], [ %i_next, %loop_body ]
%cmp = icmp slt i32 %i, %n
br i1 %cmp, label %loop_body, label %loop_end
loop_body:
call void @baz(i32 %i)
%i_next = add i32 %i, 1
br label %loop_cond
loop_end:
ret void
}
define void @bar() {
ret void
}
declare void @baz(i32)