Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
82 changes: 82 additions & 0 deletions llvm/test/Other/print-loop-func-scope.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
; 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

; 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



define void @foo(i32 %0, i32 %1, i32* %2) {
%4 = icmp sgt i32 %0, 0
br i1 %4, label %5, label %8

5: ; preds = %3
br label %12

6: ; preds = %12
%7 = phi i32 [ %15, %12 ]
br label %8

8: ; preds = %6, %3
%9 = phi i32 [ 1, %3 ], [ %7, %6 ]
%10 = add nsw i32 %1, %0
%11 = add nsw i32 %10, %9
store i32 %11, i32* %2, align 4
ret void

12: ; preds = %5, %12
%13 = phi i32 [ %16, %12 ], [ 0, %5 ]
%14 = phi i32 [ %15, %12 ], [ 1, %5 ]
%15 = mul nsw i32 %14, %1
%16 = add nuw nsw i32 %13, 1
%17 = icmp eq i32 %16, %0
br i1 %17, label %6, label %12
}

define void @bar() {
ret void
}
Loading