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() {