Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions llvm/include/llvm/IR/PrintPasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
12 changes: 12 additions & 0 deletions llvm/lib/Analysis/LoopInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
8 changes: 8 additions & 0 deletions llvm/lib/IR/PrintPasses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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());
Expand Down
75 changes: 75 additions & 0 deletions llvm/test/Other/print-loop-func-scope.ll
Original file line number Diff line number Diff line change
@@ -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