diff --git a/llvm/include/llvm/IR/PassManager.h b/llvm/include/llvm/IR/PassManager.h --- a/llvm/include/llvm/IR/PassManager.h +++ b/llvm/include/llvm/IR/PassManager.h @@ -37,6 +37,7 @@ #ifndef LLVM_IR_PASSMANAGER_H #define LLVM_IR_PASSMANAGER_H +#include "llvm/Support/PrettyStackTrace.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" @@ -451,6 +452,29 @@ // header. class PassInstrumentationAnalysis; +class MachineFunction; + +/// Add stack entry with the pass name and the IR unit it runs on. +class NewPassManagerPrettyStackEntry : public PrettyStackTraceEntry { + StringRef PassName; + Module *M = nullptr; + MachineFunction *MF = nullptr; + Value *V = nullptr; + +public: + NewPassManagerPrettyStackEntry(StringRef PassName, Module &M) + : PassName(PassName), M(&M) {} + + NewPassManagerPrettyStackEntry(StringRef PassName, MachineFunction &MF) + : PassName(PassName), MF(&MF) {} + + NewPassManagerPrettyStackEntry(StringRef PassName, Value &V) + : PassName(PassName), V(&V) {} + + /// print - Emit information about this stack frame to OS. + void print(raw_ostream &OS) const override; +}; + /// Manages a sequence of passes over a particular unit of IR. /// /// A pass manager contains a sequence of passes to run over a particular unit @@ -519,6 +543,7 @@ PreservedAnalyses PassPA; { TimeTraceScope TimeScope(P->name(), IR.getName()); + NewPassManagerPrettyStackEntry StackEntry(P->name(), IR); PassPA = P->run(IR, AM, ExtraArgs...); } diff --git a/llvm/lib/IR/PassManager.cpp b/llvm/lib/IR/PassManager.cpp --- a/llvm/lib/IR/PassManager.cpp +++ b/llvm/lib/IR/PassManager.cpp @@ -124,6 +124,7 @@ PreservedAnalyses PassPA; { TimeTraceScope TimeScope(Pass->name(), F.getName()); + NewPassManagerPrettyStackEntry StackEntry(Pass->name(), F); PassPA = Pass->run(F, FAM); } @@ -152,3 +153,31 @@ AnalysisSetKey CFGAnalyses::SetKey; AnalysisSetKey PreservedAnalyses::AllAnalysesKey; + +void NewPassManagerPrettyStackEntry::print(raw_ostream &OS) const { + OS << "Running pass '" << PassName << "'"; + + if (M) { + OS << " on module '" << M->getModuleIdentifier() << "'.\n"; + return; + } + + if (MF) { + OS << " on machine function \n"; //'" << MF->getName() << "'.\n"; + return; + } + + assert(V && "Either M, MF or V must be set"); + + OS << " on "; + if (isa(V)) + OS << "function"; + else if (isa(V)) + OS << "basic block"; + else + OS << "value"; + + OS << " '"; + V->printAsOperand(OS, /*PrintType=*/false); + OS << "'\n"; +}