]> granicus.if.org Git - llvm/commitdiff
IR printing improvement for loop passes
authorFedor Sergeev <fedor.sergeev@oracle.com>
Wed, 22 Nov 2017 20:59:53 +0000 (20:59 +0000)
committerFedor Sergeev <fedor.sergeev@oracle.com>
Wed, 22 Nov 2017 20:59:53 +0000 (20:59 +0000)
Summary:
Loop-pass printing is somewhat deficient since it does not provide the
context around the loop (e.g. preheader). This context information becomes
pretty essential when analyzing transformations that move stuff out of the loop.

Extending printLoop to cover preheader and exit blocks (if any).

Reviewers: sanjoy, silvas, weimingz

Reviewed By: sanjoy

Subscribers: apilipenko, skatkov, llvm-commits

Differential Revision: https://reviews.llvm.org/D40246

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@318878 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/LoopInfo.cpp
test/Other/loop-pass-printer.ll [new file with mode: 0644]

index c6019f267a30ff6c56f9c26a451100dcc46e83fa..9a223df9394cc5eb3c46d16b1850887787a71550 100644 (file)
@@ -732,11 +732,30 @@ PreservedAnalyses LoopPrinterPass::run(Function &F,
 
 void llvm::printLoop(Loop &L, raw_ostream &OS, const std::string &Banner) {
   OS << Banner;
+
+  auto *PreHeader = L.getLoopPreheader();
+  if (PreHeader) {
+    OS << "\n; Preheader:";
+    PreHeader->print(OS);
+    OS << "\n; Loop:";
+  }
+
   for (auto *Block : L.blocks())
     if (Block)
       Block->print(OS);
     else
       OS << "Printing <null> block";
+
+  SmallVector<BasicBlock *, 8> ExitBlocks;
+  L.getExitBlocks(ExitBlocks);
+  if (!ExitBlocks.empty()) {
+    OS << "\n; Exit blocks";
+    for (auto *Block : ExitBlocks)
+      if (Block)
+        Block->print(OS);
+      else
+        OS << "Printing <null> block";
+  }
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/test/Other/loop-pass-printer.ll b/test/Other/loop-pass-printer.ll
new file mode 100644 (file)
index 0000000..e5ad8bd
--- /dev/null
@@ -0,0 +1,67 @@
+; This test checks -print-after/before on loop passes
+; Besides of the loop itself it should be dumping loop pre-header and exits.
+;
+; RUN: opt < %s 2>&1 -disable-output \
+; RUN:            -loop-deletion -print-before=loop-deletion \
+; RUN:    | FileCheck %s -check-prefix=DEL
+; RUN: opt < %s 2>&1 -disable-output \
+; RUN:            -loop-unroll -print-after=loop-unroll -filter-print-funcs=bar \
+; RUN:    | FileCheck %s -check-prefix=BAR
+;
+
+; DEL:     IR Dump Before
+; DEL-SAME: dead loops
+; DEL:             ; Preheader:
+; DEL-NEXT:  %idx = alloca i32, align 4
+; DEL:      ; Loop:
+; DEL-NEXT:  loop:
+; DEL:      cont:
+; DEL:     ; Exit blocks
+; DEL:      done:
+; DEL:     IR Dump Before
+; DEL-SAME: dead loops
+; DEL:             ; Preheader:
+; DEL-NEXT:  br label %loop
+; DEL:      ; Loop:
+; DEL-NEXT:  loop:
+; DEL:     ; Exit blocks
+; DEL:      end:
+
+; BAR:     IR Dump After
+; BAR-SAME: Unroll
+; BAR:             ; Preheader:
+; BAR-NEXT:  br label %loop
+; BAR:      ; Loop:
+; BAR-NEXT:  loop:
+; BAR:     ; Exit blocks
+; BAR:      end:
+; BAR-NOT: IR Dump Before
+; BAR-NOT:  ; Loop
+
+define void @foo(){
+  %idx = alloca i32, align 4
+  store i32 0, i32* %idx, align 4
+  br label %loop
+
+loop:
+  %1 = load i32, i32* %idx, align 4
+  %2 = icmp slt i32 %1, 10
+  br i1 %2, label %cont, label %done
+
+cont:
+  %3 = load i32, i32* %idx, align 4
+  %4 = add nsw i32 %3, 1
+  store i32 %4, i32* %idx, align 4
+  br label %loop
+
+done:
+  ret void
+}
+
+define void @bar(){
+  br label %loop
+loop:
+  br i1 1, label %loop, label %end
+end:
+  ret void
+}