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:
parent
9fdc38c81c
commit
5b6a26ccdd
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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());
|
||||
|
75
llvm/test/Other/print-loop-func-scope.ll
Normal file
75
llvm/test/Other/print-loop-func-scope.ll
Normal 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)
|
Loading…
x
Reference in New Issue
Block a user