Index: include/llvm/Analysis/PrintIR.h
===================================================================
--- /dev/null
+++ include/llvm/Analysis/PrintIR.h
@@ -0,0 +1,37 @@
+//===- PrintIR.h - routines to print IR/Analysis constructs ---*- C++ ---*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This file defines functions to print out IR in various granularities.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_PRINTIR_H
+#define LLVM_ANALYSIS_PRINTIR_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/PassInstrumentation.h"
+
+namespace llvm {
+
+namespace PrintIR {
+
+/// IR-printing wrapper to be installed into PassInstrumentation as BeforePass
+/// callback
+bool printBeforePass(StringRef PassID, Any);
+
+/// IR-printing wrapper to be installed into PassInstrumentation as AfterPass
+/// callback
+bool printAfterPass(StringRef PassID, Any);
+
+} // namespace PrintIR
+
+} // namespace llvm
+
+#endif
Index: include/llvm/IR/IRPrintingPasses.h
===================================================================
--- include/llvm/IR/IRPrintingPasses.h
+++ include/llvm/IR/IRPrintingPasses.h
@@ -58,6 +58,22 @@
 /// Return true if a pass is for IR printing.
 bool isIRPrintingPass(Pass *P);
 
+/// isFunctionInPrintList - returns true if a function should be printed via
+//  debugging options like -print-after-all/-print-before-all.
+//  Tells if the function IR should be printed by PrinterPass.
+extern bool isFunctionInPrintList(StringRef FunctionName);
+
+/// forcePrintModuleIR - returns true if IR printing passes should
+//  be printing module IR (even for local-pass printers e.g. function-pass)
+//  to provide more context, as enabled by debugging option -print-module-scope
+//  Tells if IR printer should be printing module IR
+extern bool forcePrintModuleIR();
+
+extern bool shouldPrintBeforePass();
+extern bool shouldPrintBeforePass(StringRef);
+extern bool shouldPrintAfterPass();
+extern bool shouldPrintAfterPass(StringRef);
+
 /// Pass for printing a Module as LLVM's text IR assembly.
 ///
 /// Note: This pass is for use with the new pass manager. Use the create...Pass
Index: include/llvm/Pass.h
===================================================================
--- include/llvm/Pass.h
+++ include/llvm/Pass.h
@@ -356,17 +356,6 @@
 /// This is the storage for the -time-passes option.
 extern bool TimePassesIsEnabled;
 
-/// isFunctionInPrintList - returns true if a function should be printed via
-//  debugging options like -print-after-all/-print-before-all.
-//  Tells if the function IR should be printed by PrinterPass.
-extern bool isFunctionInPrintList(StringRef FunctionName);
-
-/// forcePrintModuleIR - returns true if IR printing passes should
-//  be printing module IR (even for local-pass printers e.g. function-pass)
-//  to provide more context, as enabled by debugging option -print-module-scope
-//  Tells if IR printer should be printing module IR
-extern bool forcePrintModuleIR();
-
 } // end namespace llvm
 
 // Include support files that contain important APIs commonly used by Passes,
Index: include/llvm/Passes/PassBuilder.h
===================================================================
--- include/llvm/Passes/PassBuilder.h
+++ include/llvm/Passes/PassBuilder.h
@@ -573,6 +573,9 @@
     return true;
   }
 
+  /// Registers a set of useful in-tree instrumentations
+  void registerDefaultInstrumentations();
+
 private:
   static Optional<std::vector<PipelineElement>>
   parsePipelineText(StringRef Text);
Index: lib/Analysis/CMakeLists.txt
===================================================================
--- lib/Analysis/CMakeLists.txt
+++ lib/Analysis/CMakeLists.txt
@@ -71,6 +71,7 @@
   PHITransAddr.cpp
   PhiValues.cpp
   PostDominators.cpp
+  PrintIR.cpp
   ProfileSummaryInfo.cpp
   PtrUseVisitor.cpp
   RegionInfo.cpp
Index: lib/Analysis/CallGraphSCCPass.cpp
===================================================================
--- lib/Analysis/CallGraphSCCPass.cpp
+++ lib/Analysis/CallGraphSCCPass.cpp
@@ -22,6 +22,7 @@
 #include "llvm/Analysis/CallGraph.h"
 #include "llvm/IR/CallSite.h"
 #include "llvm/IR/Function.h"
+#include "llvm/IR/IRPrintingPasses.h"
 #include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/LegacyPassManagers.h"
Index: lib/Analysis/LoopInfo.cpp
===================================================================
--- lib/Analysis/LoopInfo.cpp
+++ lib/Analysis/LoopInfo.cpp
@@ -26,6 +26,7 @@
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DebugLoc.h"
 #include "llvm/IR/Dominators.h"
+#include "llvm/IR/IRPrintingPasses.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Metadata.h"
Index: lib/Analysis/PrintIR.cpp
===================================================================
--- /dev/null
+++ lib/Analysis/PrintIR.cpp
@@ -0,0 +1,100 @@
+//===--- PrintIR.cpp - routines to print IR/Analysis constructs -------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// PrintIR routines implementation
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/PrintIR.h"
+#include "llvm/Analysis/CallGraphSCCPass.h"
+#include "llvm/Analysis/LazyCallGraph.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRPrintingPasses.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/raw_ostream.h"
+
+#define DEBUG_TYPE "printir"
+
+namespace llvm {
+
+/// Generic IR-printing helper that unpacks a pointer to IRUnit wrapped into
+/// llvm::Any and does actual print job.
+static void unwrapAndPrint(StringRef Banner, Any IR) {
+  if (any_isa<const CallGraphSCC *>(IR) ||
+      any_isa<const LazyCallGraph::SCC *>(IR))
+    return;
+
+  SmallString<40> Extra{"\n"};
+  const Module *M = nullptr;
+  if (any_isa<const Module *>(IR)) {
+    M = any_cast<const Module *>(IR);
+  } else if (any_isa<const Function *>(IR)) {
+    const Function *F = any_cast<const Function *>(IR);
+    if (!llvm::isFunctionInPrintList(F->getName()))
+      return;
+    if (!llvm::forcePrintModuleIR()) {
+      dbgs() << Banner << Extra << static_cast<const Value &>(*F);
+      return;
+    }
+    M = F->getParent();
+    Extra = formatv(" (function: {0})\n", F->getName());
+  } else if (any_isa<const Loop *>(IR)) {
+    const Loop *L = any_cast<const Loop *>(IR);
+    const Function *F = L->getHeader()->getParent();
+    if (!isFunctionInPrintList(F->getName()))
+      return;
+    if (!llvm::forcePrintModuleIR()) {
+      llvm::printLoop(const_cast<Loop &>(*L), dbgs(), Banner);
+      return;
+    }
+    M = F->getParent();
+    {
+      std::string LoopName;
+      raw_string_ostream ss(LoopName);
+      L->getHeader()->printAsOperand(ss, false);
+      Extra = formatv(" (loop: {0})\n", ss.str());
+    }
+  }
+  if (M) {
+    dbgs() << Banner << Extra;
+    M->print(dbgs(), nullptr, false);
+  } else {
+    llvm_unreachable("Unknown wrapped IR type");
+  }
+}
+
+bool PrintIR::printBeforePass(StringRef PassID, Any IR) {
+  if (!llvm::shouldPrintBeforePass(PassID))
+    return true;
+
+  if (PassID.startswith("PassManager<") || PassID.contains("PassAdaptor<"))
+    return true;
+
+  SmallString<20> Banner = formatv("*** IR Dump Before {0} ***", PassID);
+  unwrapAndPrint(Banner, IR);
+  return true;
+}
+
+bool PrintIR::printAfterPass(StringRef PassID, Any IR) {
+  if (!llvm::shouldPrintAfterPass(PassID))
+    return false;
+
+  if (PassID.startswith("PassManager<") || PassID.contains("PassAdaptor<"))
+    return true;
+
+  SmallString<20> Banner = formatv("*** IR Dump After {0} ***", PassID);
+  unwrapAndPrint(Banner, IR);
+  return true;
+}
+
+} // namespace llvm
Index: lib/CodeGen/MachineFunctionPrinterPass.cpp
===================================================================
--- lib/CodeGen/MachineFunctionPrinterPass.cpp
+++ lib/CodeGen/MachineFunctionPrinterPass.cpp
@@ -15,6 +15,7 @@
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/CodeGen/SlotIndexes.h"
+#include "llvm/IR/IRPrintingPasses.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
 
Index: lib/IR/LegacyPassManager.cpp
===================================================================
--- lib/IR/LegacyPassManager.cpp
+++ lib/IR/LegacyPassManager.cpp
@@ -100,27 +100,31 @@
 /// This is a helper to determine whether to print IR before or
 /// after a pass.
 
-static bool ShouldPrintBeforeOrAfterPass(const PassInfo *PI,
+bool llvm::shouldPrintBeforePass() {
+  return PrintBeforeAll || !PrintBefore.empty();
+}
+
+bool llvm::shouldPrintAfterPass() {
+  return PrintAfterAll || !PrintAfter.empty();
+}
+
+static bool ShouldPrintBeforeOrAfterPass(StringRef PassID,
                                          PassOptionList &PassesToPrint) {
   for (auto *PassInf : PassesToPrint) {
     if (PassInf)
-      if (PassInf->getPassArgument() == PI->getPassArgument()) {
+      if (PassInf->getPassArgument() == PassID) {
         return true;
       }
   }
   return false;
 }
 
-/// This is a utility to check whether a pass should have IR dumped
-/// before it.
-static bool ShouldPrintBeforePass(const PassInfo *PI) {
-  return PrintBeforeAll || ShouldPrintBeforeOrAfterPass(PI, PrintBefore);
+bool llvm::shouldPrintBeforePass(StringRef PassID) {
+  return PrintBeforeAll || ShouldPrintBeforeOrAfterPass(PassID, PrintBefore);
 }
 
-/// This is a utility to check whether a pass should have IR dumped
-/// after it.
-static bool ShouldPrintAfterPass(const PassInfo *PI) {
-  return PrintAfterAll || ShouldPrintBeforeOrAfterPass(PI, PrintAfter);
+bool llvm::shouldPrintAfterPass(StringRef PassID) {
+  return PrintAfterAll || ShouldPrintBeforeOrAfterPass(PassID, PrintAfter);
 }
 
 bool llvm::forcePrintModuleIR() { return PrintModuleScope; }
@@ -780,7 +784,7 @@
     return;
   }
 
-  if (PI && !PI->isAnalysis() && ShouldPrintBeforePass(PI)) {
+  if (PI && !PI->isAnalysis() && shouldPrintBeforePass(PI->getPassArgument())) {
     Pass *PP = P->createPrinterPass(
         dbgs(), ("*** IR Dump Before " + P->getPassName() + " ***").str());
     PP->assignPassManager(activeStack, getTopLevelPassManagerType());
@@ -789,7 +793,7 @@
   // Add the requested pass to the best available pass manager.
   P->assignPassManager(activeStack, getTopLevelPassManagerType());
 
-  if (PI && !PI->isAnalysis() && ShouldPrintAfterPass(PI)) {
+  if (PI && !PI->isAnalysis() && shouldPrintAfterPass(PI->getPassArgument())) {
     Pass *PP = P->createPrinterPass(
         dbgs(), ("*** IR Dump After " + P->getPassName() + " ***").str());
     PP->assignPassManager(activeStack, getTopLevelPassManagerType());
Index: lib/Passes/PassBuilder.cpp
===================================================================
--- lib/Passes/PassBuilder.cpp
+++ lib/Passes/PassBuilder.cpp
@@ -43,6 +43,7 @@
 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
 #include "llvm/Analysis/PhiValues.h"
 #include "llvm/Analysis/PostDominators.h"
+#include "llvm/Analysis/PrintIR.h"
 #include "llvm/Analysis/ProfileSummaryInfo.h"
 #include "llvm/Analysis/RegionInfo.h"
 #include "llvm/Analysis/ScalarEvolution.h"
@@ -1904,3 +1905,17 @@
 
   return true;
 }
+
+void PassBuilder::registerDefaultInstrumentations() {
+  if (!PIC)
+    return;
+
+  if (llvm::shouldPrintBeforePass())
+    registerPassInstrumentation([](PassInstrumentationCallbacks &PIC) {
+      PIC.registerBeforePassCallback(PrintIR::printBeforePass);
+    });
+  if (llvm::shouldPrintAfterPass())
+    registerPassInstrumentation([](PassInstrumentationCallbacks &PIC) {
+      PIC.registerAfterPassCallback(PrintIR::printAfterPass);
+    });
+}
Index: test/Other/loop-pass-printer.ll
===================================================================
--- test/Other/loop-pass-printer.ll
+++ test/Other/loop-pass-printer.ll
@@ -5,14 +5,22 @@
 ; RUN: 	   -loop-deletion -print-before=loop-deletion \
 ; RUN:	   | FileCheck %s -check-prefix=DEL
 ; RUN: opt < %s 2>&1 -disable-output \
+; RUN: 	   -passes='loop(loop-deletion)' -print-before-all \
+; 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 -check-prefix=BAR-OLD
+; RUN: opt < %s 2>&1 -disable-output \
+; RUN: 	   -passes='require<opt-remark-emit>,loop(unroll-full)' -print-after-all -filter-print-funcs=bar \
 ; RUN:	   | FileCheck %s -check-prefix=BAR
 ; RUN: opt < %s 2>&1 -disable-output \
 ; RUN: 	   -loop-unroll -print-after=loop-unroll -filter-print-funcs=foo -print-module-scope \
+; RUN:	   | FileCheck %s -check-prefix=FOO-MODULE -check-prefix=FOO-MODULE-OLD
+; RUN: opt < %s 2>&1 -disable-output \
+; RUN: 	   -passes='require<opt-remark-emit>,loop(unroll-full)' -print-after-all -filter-print-funcs=foo -print-module-scope \
 ; RUN:	   | FileCheck %s -check-prefix=FOO-MODULE
 
-; DEL:	    IR Dump Before
-; DEL-SAME: dead loops
+; DEL:	    IR Dump Before {{Delete dead loops|LoopDeletionPass}}
 ; DEL: 	    ; Preheader:
 ; DEL-NEXT:  %idx = alloca i32, align 4
 ; DEL:      ; Loop:
@@ -20,8 +28,7 @@
 ; DEL:	     cont:
 ; DEL:	    ; Exit blocks
 ; DEL:	     done:
-; DEL:	    IR Dump Before
-; DEL-SAME: dead loops
+; DEL:	    IR Dump Before {{Delete dead loops|LoopDeletionPass}}
 ; DEL: 	    ; Preheader:
 ; DEL-NEXT:  br label %loop
 ; DEL:      ; Loop:
@@ -29,24 +36,22 @@
 ; DEL:	    ; Exit blocks
 ; DEL:	     end:
 
-; BAR:	    IR Dump After
-; BAR-SAME: Unroll
+; BAR:	    IR Dump After {{Unroll|LoopFullUnrollPass}}
 ; BAR: 	    ; Preheader:
 ; BAR-NEXT:  br label %loop
 ; BAR:      ; Loop:
 ; BAR-NEXT:  loop:
 ; BAR:	    ; Exit blocks
 ; BAR:	     end:
-; BAR-NOT: IR Dump
-; BAR-NOT:  ; Loop
+; BAR-OLD-NOT: IR Dump
+; BAR-OLD-NOT:  ; Loop
 
-; FOO-MODULE: IR Dump After
-; FOO-MODULE-SAME: Unroll
+; FOO-MODULE: IR Dump After {{Unroll|LoopFullUnrollPass}}
 ; FOO-MODULE-SAME: loop: %loop
 ; FOO-MODULE-NEXT: ModuleID =
 ; FOO-MODULE: define void @foo
 ; FOO-MODULE: define void @bar
-; FOO-MODULE-NOT: IR Dump
+; FOO-MODULE-OLD-NOT: IR Dump
 
 define void @foo(){
   %idx = alloca i32, align 4
Index: test/Other/print-module-scope.ll
===================================================================
--- test/Other/print-module-scope.ll
+++ test/Other/print-module-scope.ll
@@ -7,10 +7,16 @@
 ; RUN: 	   -simplifycfg -print-after=simplifycfg -print-module-scope \
 ; RUN:	   | FileCheck %s -check-prefix=CFG
 ; RUN: opt < %s 2>&1 -disable-output \
+; RUN: 	   -passes=simplify-cfg -print-after-all -print-module-scope \
+; RUN:	   | FileCheck %s -check-prefix=CFG
+; RUN: opt < %s 2>&1 -disable-output \
 ; RUN: 	   -simplifycfg -print-after=simplifycfg -filter-print-funcs=foo -print-module-scope \
 ; RUN:	   | FileCheck %s -check-prefix=FOO
+; RUN: opt < %s 2>&1 -disable-output \
+; RUN: 	   -passes=simplify-cfg -print-after-all -filter-print-funcs=foo -print-module-scope \
+; RUN:	   | FileCheck %s -check-prefix=FOO
 
-; CFG:      IR Dump After
+; CFG:      IR Dump After {{Simplify the CFG|SimplifyCFGPass}}
 ; CFG-SAME:   function: foo
 ; CFG-NEXT: ModuleID =
 ; CFG: define void @foo
@@ -23,7 +29,7 @@
 ; CFG: define void @bar
 ; CFG: declare void @baz
 
-; FOO:      IR Dump After
+; FOO:      IR Dump After {{Simplify the CFG|SimplifyCFGPass}}
 ; FOO-NOT:    function: bar
 ; FOO-SAME:   function: foo
 ; FOO-NEXT: ModuleID =
@@ -52,4 +58,4 @@
 
 ; FOO: attributes #{{[0-9]}} = { nounwind readnone ssp "use-soft-float"="false" }
 
-; FOO-NOT: IR Dump
+; FOO-NOT: IR Dump After {{Simplify the CFG|SimplifyCFGPass}}
Index: test/Other/printer.ll
===================================================================
--- test/Other/printer.ll
+++ test/Other/printer.ll
@@ -1,4 +1,5 @@
-; RUN: opt -mem2reg -instcombine -print-after-all -S < %s 2>&1 | FileCheck %s
+; RUN: opt -mem2reg -instcombine -print-after-all -disable-output < %s 2>&1 | FileCheck %s
+; RUN: opt -passes='mem2reg,instcombine' -print-after-all -disable-output < %s 2>&1 | FileCheck %s
 define void @tester(){
   ret void
 }
@@ -7,7 +8,21 @@
   ret void
 }
 
-;CHECK: IR Dump After Promote Memory to Register
-;CHECK: IR Dump After Combine redundant instructions
-;CHECK: IR Dump After Module Verifier
+;CHECK-NOT: IR Dump After PassManager
+;CHECK-NOT: IR Dump After ModuleToFunctionPassAdaptor
+;
+;CHECK:     *** IR Dump After {{Promote Memory to Register|PromotePass}}
+;CHECK:     define void @tester
+;CHECK-NOT: define void @foo
+;CHECK:     *** IR Dump After {{Combine redundant instructions|InstCombinePass}}
+;CHECK:     define void @tester
+;CHECK-NOT: define void @foo
+;CHECK:     *** IR Dump After {{Promote Memory to Register|PromotePass}}
+;CHECK:     define void @foo
+;CHECK-NOT: define void @tester
+;CHECK:     *** IR Dump After {{Combine redundant instructions|InstCombinePass}}
+;CHECK:     define void @foo
+;CHECK-NOT: define void @tester
+;CHECK:     *** IR Dump After {{Module Verifier|VerifierPass}}
+;
 ;CHECK-NOT: IR Dump After Print Module IR
Index: tools/opt/NewPMDriver.cpp
===================================================================
--- tools/opt/NewPMDriver.cpp
+++ tools/opt/NewPMDriver.cpp
@@ -13,12 +13,13 @@
 ///
 //===----------------------------------------------------------------------===//
 
-#include "Debugify.h"
 #include "NewPMDriver.h"
+#include "Debugify.h"
 #include "PassPrinters.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/Analysis/CGSCCPassManager.h"
+#include "llvm/Analysis/PrintIR.h"
 #include "llvm/Bitcode/BitcodeWriterPass.h"
 #include "llvm/Config/llvm-config.h"
 #include "llvm/IR/Dominators.h"
@@ -213,8 +214,10 @@
       else
         P = None;
   }
-  PassBuilder PB(TM, P);
+  PassInstrumentationCallbacks PIC;
+  PassBuilder PB(TM, P, &PIC);
   registerEPCallbacks(PB, VerifyEachPass, DebugPM);
+  PB.registerDefaultInstrumentations();
 
   // Load requested pass plugins and let them register pass builder callbacks
   for (auto &PluginFN : PassPlugins) {