Skip to content

Commit 5b6a26c

Browse files
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.
1 parent 9fdc38c commit 5b6a26c

File tree

4 files changed

+98
-0
lines changed

4 files changed

+98
-0
lines changed

llvm/include/llvm/IR/PrintPasses.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ std::vector<std::string> printAfterPasses();
5151
// Returns true if we should always print the entire module.
5252
bool forcePrintModuleIR();
5353

54+
// Returns true if we should print the entire function for loop passes.
55+
bool forcePrintFuncIR();
56+
5457
// Return true if -filter-passes is empty or contains the pass name.
5558
bool isPassInPrintList(StringRef PassName);
5659
bool isFilterPassesEmpty();

llvm/lib/Analysis/LoopInfo.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,18 @@ void llvm::printLoop(Loop &L, raw_ostream &OS, const std::string &Banner) {
999999
return;
10001000
}
10011001

1002+
if (forcePrintFuncIR()) {
1003+
// handling -print-loop-func-scope.
1004+
// -print-module-scope overrides this.
1005+
OS << Banner << " (loop: ";
1006+
L.getHeader()->printAsOperand(OS, false);
1007+
OS << ")\n";
1008+
1009+
// printing whole function.
1010+
OS << *L.getHeader()->getParent();
1011+
return;
1012+
}
1013+
10021014
OS << Banner;
10031015

10041016
auto *PreHeader = L.getLoopPreheader();

llvm/lib/IR/PrintPasses.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ static cl::opt<bool>
8888
"always print a module IR"),
8989
cl::init(false), cl::Hidden);
9090

91+
static cl::opt<bool> LoopPrintFuncScope(
92+
"print-loop-func-scope",
93+
cl::desc("When printing IR for print-[before|after]{-all} "
94+
"for a loop pass, always print function IR"),
95+
cl::init(false), cl::Hidden);
96+
9197
// See the description for -print-changed for an explanation of the use
9298
// of this option.
9399
static cl::list<std::string> FilterPasses(
@@ -141,6 +147,8 @@ std::vector<std::string> llvm::printAfterPasses() {
141147

142148
bool llvm::forcePrintModuleIR() { return PrintModuleScope; }
143149

150+
bool llvm::forcePrintFuncIR() { return LoopPrintFuncScope; }
151+
144152
bool llvm::isPassInPrintList(StringRef PassName) {
145153
static std::unordered_set<std::string> Set(FilterPasses.begin(),
146154
FilterPasses.end());
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
; This test documents how the IR dumped for loop passes differs with -print-loop-func-scope
2+
; and -print-module-scope
3+
; - Without -print-loop-func-scope, dumps only the loop, with 3 sections- preheader,
4+
; loop, and exit blocks
5+
; - With -print-loop-func-scope, dumps only the function which contains the loop
6+
; - With -print-module-scope, dumps the entire module containing the loop, and disregards
7+
; the -print-loop-func-scope flag.
8+
9+
; RUN: opt < %s 2>&1 -disable-output \
10+
; RUN: -passes=licm -print-after=licm \
11+
; RUN: | FileCheck %s -check-prefix=VANILLA
12+
; RUN: opt < %s 2>&1 -disable-output \
13+
; RUN: -passes=licm -print-after=licm -print-loop-func-scope \
14+
; RUN: | FileCheck %s -check-prefix=LOOPFUNC
15+
; RUN: opt < %s 2>&1 -disable-output \
16+
; RUN: -passes=licm -print-after=licm -print-module-scope \
17+
; RUN: | FileCheck %s -check-prefix=MODULE
18+
; RUN: opt < %s 2>&1 -disable-output \
19+
; RUN: -passes=licm -print-after=licm -print-module-scope -print-loop-func-scope\
20+
; RUN: | FileCheck %s -check-prefix=MODULEWITHLOOP
21+
22+
; VANILLA: IR Dump After LICMPass
23+
; VANILLA-NOT: define void @foo
24+
; VANILLA: Preheader:
25+
; VANILLA: Loop:
26+
; VANILLA: Exit blocks
27+
28+
; LOOPFUNC: IR Dump After LICMPass
29+
; LOOPFUNC: (loop:
30+
; LOOPFUNC: define void @foo
31+
; LOOPFUNC-NOT: Preheader:
32+
; LOOPFUNC-NOT: Loop:
33+
; LOOPFUNC-NOT: Exit blocks
34+
35+
; MODULE: IR Dump After LICMPass
36+
; MODULE: ModuleID =
37+
; MODULE: define void @foo
38+
; MODULE-NOT: Preheader:
39+
; MODULE-NOT: Loop:
40+
; MODULE-NOT: Exit blocks
41+
; MODULE: define void @bar
42+
; MODULE: declare void @baz(i32)
43+
44+
; MODULEWITHLOOP: IR Dump After LICMPass
45+
; MODULEWITHLOOP: ModuleID =
46+
; MODULEWITHLOOP: define void @foo
47+
; MODULEWITHLOOP-NOT: Preheader:
48+
; MODULEWITHLOOP-NOT: Loop:
49+
; MODULEWITHLOOP-NOT: Exit blocks
50+
; MODULEWITHLOOP: define void @bar
51+
; MODULEWITHLOOP: declare void @baz(i32)
52+
53+
define void @foo(i32 %n) {
54+
entry:
55+
br label %loop_cond
56+
57+
loop_cond:
58+
%i = phi i32 [ 0, %entry ], [ %i_next, %loop_body ]
59+
%cmp = icmp slt i32 %i, %n
60+
br i1 %cmp, label %loop_body, label %loop_end
61+
62+
loop_body:
63+
call void @baz(i32 %i)
64+
%i_next = add i32 %i, 1
65+
br label %loop_cond
66+
67+
loop_end:
68+
ret void
69+
}
70+
71+
define void @bar() {
72+
ret void
73+
}
74+
75+
declare void @baz(i32)

0 commit comments

Comments
 (0)