Index: include/llvm/IR/LegacyPassManagers.h
===================================================================
--- include/llvm/IR/LegacyPassManagers.h
+++ include/llvm/IR/LegacyPassManagers.h
@@ -382,6 +382,12 @@
   void dumpPreservedSet(const Pass *P) const;
   void dumpUsedSet(const Pass *P) const;
 
+  // Mark the function to dump in print pass
+  void markChangedFunc(const Function &F) const;
+
+  // Mark all functions in the module to dump in print pass
+  void markChangedFunc(const Module &M) const;
+
   unsigned getNumContainedPasses() const {
     return (unsigned)PassVector.size();
   }
Index: include/llvm/IR/Module.h
===================================================================
--- include/llvm/IR/Module.h
+++ include/llvm/IR/Module.h
@@ -187,6 +187,10 @@
   void *NamedMDSymTab;            ///< NamedMDNode names.
   DataLayout DL;                  ///< DataLayout associated with the module
 
+  /// Functions that are not modified after the previous dump.
+  /// Used to avoid redundant dump with -print-{before,after}-all.
+  std::unique_ptr<SmallPtrSetImpl<const Function *>> FuncsUnchangedAfterDump;
+
   friend class Constant;
 
 /// @}
@@ -840,6 +844,11 @@
 
   /// Take ownership of the given memory buffer.
   void setOwnedMemoryBuffer(std::unique_ptr<MemoryBuffer> MB);
+
+  /// Returns set of functions need not to dump
+  SmallPtrSetImpl<const Function *> *getUnchangedFuncs() const {
+    return FuncsUnchangedAfterDump.get();
+  }
 };
 
 /// \brief Given "llvm.used" or "llvm.compiler.used" as a global name, collect
Index: lib/CodeGen/MachineFunction.cpp
===================================================================
--- lib/CodeGen/MachineFunction.cpp
+++ lib/CodeGen/MachineFunction.cpp
@@ -456,9 +456,17 @@
 
   ModuleSlotTracker MST(getFunction()->getParent());
   MST.incorporateFunction(*getFunction());
-  for (const auto &BB : *this) {
-    OS << '\n';
-    BB.print(OS, MST, Indexes);
+
+  const Function *F = getFunction();
+  SmallPtrSetImpl<const Function *> *UFs = F->getParent()->getUnchangedFuncs();
+  if (UFs && UFs->count(F) != 0)
+    OS << "\n  listing omitted because it is not modified since last dump.\n";
+  else {
+    for (const auto &BB : *this) {
+      OS << '\n';
+      BB.print(OS, MST, Indexes);
+    }
+    if (UFs) UFs->insert(F);
   }
 
   OS << "\n# End machine code for function " << getName() << ".\n\n";
Index: lib/IR/AsmWriter.cpp
===================================================================
--- lib/IR/AsmWriter.cpp
+++ lib/IR/AsmWriter.cpp
@@ -2715,9 +2715,16 @@
     printMetadataAttachments(MDs, " ");
 
     Out << " {";
-    // Output all of the function's basic blocks.
-    for (const BasicBlock &BB : *F)
-      printBasicBlock(&BB);
+
+    SmallPtrSetImpl<const Function *> *UFs = F->getParent()->getUnchangedFuncs();
+    if (UFs && UFs->count(F) != 0)
+      Out << "\n  listing omitted because it is not modified since last dump.\n";
+    else {
+      // Output all of the function's basic blocks.
+      for (const BasicBlock &BB : *F)
+        printBasicBlock(&BB);
+      if (UFs) UFs->insert(F);
+    }
 
     // Output the function's use-lists.
     printUseLists(F);
Index: lib/IR/LegacyPassManager.cpp
===================================================================
--- lib/IR/LegacyPassManager.cpp
+++ lib/IR/LegacyPassManager.cpp
@@ -1223,6 +1223,16 @@
   dbgs() << '\n';
 }
 
+void PMDataManager::markChangedFunc(const Function &F) const {
+  SmallPtrSetImpl<const Function *> *UFs = F.getParent()->getUnchangedFuncs();
+  if (UFs) UFs->erase(&F);
+}
+
+void PMDataManager::markChangedFunc(const Module &M) const {
+  SmallPtrSetImpl<const Function *> *UFs = M.getUnchangedFuncs();
+  if (UFs) UFs->clear();
+}
+
 /// Add RequiredPass into list of lower level passes required by pass P.
 /// RequiredPass is run on the fly by Pass Manager when P requests it
 /// through getAnalysis interface.
@@ -1303,9 +1313,11 @@
       }
 
       Changed |= LocalChanged;
-      if (LocalChanged)
+      if (LocalChanged) {
         dumpPassInfo(BP, MODIFICATION_MSG, ON_BASICBLOCK_MSG,
                      I->getName());
+        markChangedFunc(F);
+      }
       dumpPreservedSet(BP);
       dumpUsedSet(BP);
 
@@ -1520,8 +1532,10 @@
     }
 
     Changed |= LocalChanged;
-    if (LocalChanged)
+    if (LocalChanged) {
       dumpPassInfo(FP, MODIFICATION_MSG, ON_FUNCTION_MSG, F.getName());
+      markChangedFunc(F);
+    }
     dumpPreservedSet(FP);
     dumpUsedSet(FP);
 
@@ -1597,9 +1611,11 @@
     }
 
     Changed |= LocalChanged;
-    if (LocalChanged)
+    if (LocalChanged) {
       dumpPassInfo(MP, MODIFICATION_MSG, ON_MODULE_MSG,
                    M.getModuleIdentifier());
+      markChangedFunc(M);
+    }
     dumpPreservedSet(MP);
     dumpUsedSet(MP);
 
Index: lib/IR/Module.cpp
===================================================================
--- lib/IR/Module.cpp
+++ lib/IR/Module.cpp
@@ -54,6 +54,9 @@
 
 using namespace llvm;
 
+static cl::opt<bool> OmitDuplicatedDump("omit-duplicated-dump",
+cl::init(false), cl::Hidden);
+
 //===----------------------------------------------------------------------===//
 // Methods to implement the globals and functions lists.
 //
@@ -70,10 +73,13 @@
 //
 
 Module::Module(StringRef MID, LLVMContext &C)
-    : Context(C), Materializer(), ModuleID(MID), SourceFileName(MID), DL("") {
+    : Context(C), Materializer(), ModuleID(MID), SourceFileName(MID), DL(""),
+      FuncsUnchangedAfterDump() {
   ValSymTab = new ValueSymbolTable();
   NamedMDSymTab = new StringMap<NamedMDNode *>();
   Context.addModule(this);
+  if (OmitDuplicatedDump)
+    FuncsUnchangedAfterDump.reset(new SmallPtrSet<const Function*, 16>());
 }
 
 Module::~Module() {