Index: include/llvm/IR/PassManager.h =================================================================== --- include/llvm/IR/PassManager.h +++ include/llvm/IR/PassManager.h @@ -46,6 +46,7 @@ #include "llvm/IR/Module.h" #include "llvm/IR/PassInstrumentation.h" #include "llvm/IR/PassManagerInternal.h" +#include "llvm/IR/PassTimingInfo.h" #include "llvm/Support/Debug.h" #include "llvm/Support/TypeName.h" #include "llvm/Support/raw_ostream.h" @@ -454,6 +455,8 @@ if (DebugLogging) dbgs() << "Starting " << getTypeName() << " pass manager run.\n"; + Timer *MyTimer = getPassTimer(this->name()); + for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) { if (DebugLogging) dbgs() << "Running pass: " << Passes[Idx]->name() << " on " @@ -461,8 +464,14 @@ if (!PI.runBeforePass(Passes[Idx]->name(), IR)) continue; + if (MyTimer && MyTimer->isRunning()) + MyTimer->stopTimer(); + PreservedAnalyses PassPA = Passes[Idx]->run(IR, AM, ExtraArgs...); + if (MyTimer && MyTimer->hasTriggered() && !MyTimer->isRunning()) + MyTimer->startTimer(); + PI.runAfterPass(Passes[Idx]->name(), IR); // Update the analysis manager as each pass runs and potentially @@ -651,6 +660,9 @@ AnalysisManager(AnalysisManager &&) = default; AnalysisManager &operator=(AnalysisManager &&) = default; + /// Returns name of this analysis manager + StringRef name() { return getTypeName(); } + /// Returns true if the analysis manager has an empty results cache. bool empty() const { assert(AnalysisResults.empty() == AnalysisResultLists.empty() && @@ -915,9 +927,16 @@ PI.runBeforeAnalysis(P.name(), IR); } + Timer *MyTimer = getPassTimer(this->name()); + if (MyTimer && MyTimer->isRunning()) + MyTimer->stopTimer(); + AnalysisResultListT &ResultList = AnalysisResultLists[&IR]; ResultList.emplace_back(ID, P.run(IR, *this, ExtraArgs...)); + if (MyTimer && MyTimer->hasTriggered() && !MyTimer->isRunning()) + MyTimer->startTimer(); + if (!IsInstrumentationAnalysis) PI.runAfterAnalysis(P.name(), IR); Index: include/llvm/IR/PassTimingInfo.h =================================================================== --- include/llvm/IR/PassTimingInfo.h +++ include/llvm/IR/PassTimingInfo.h @@ -18,6 +18,7 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/IR/PassInstrumentation.h" #include "llvm/Support/Timer.h" #include @@ -65,6 +66,10 @@ /// This is the storage for the -time-passes option. extern bool TimePassesIsEnabled; +// Implementation of timer callbacks +bool runTimerBeforePass(StringRef PassID, Any IR, PassExecutionCounter PC); +void stopTimerAfterPass(StringRef PassID, Any IR, PassExecutionCounter PC); + } // namespace llvm #endif Index: lib/Analysis/CGSCCPassManager.cpp =================================================================== --- lib/Analysis/CGSCCPassManager.cpp +++ lib/Analysis/CGSCCPassManager.cpp @@ -68,6 +68,8 @@ // a pointer that we can update. LazyCallGraph::SCC *C = &InitialC; + Timer *MyTimer = getPassTimer(this->name()); + for (auto &Pass : Passes) { if (DebugLogging) dbgs() << "Running pass: " << Pass->name() << " on " << *C << "\n"; @@ -75,8 +77,14 @@ if (!PI.runBeforePass(Pass->name(), *C)) continue; + if (MyTimer && MyTimer->isRunning()) + MyTimer->stopTimer(); + PreservedAnalyses PassPA = Pass->run(*C, AM, G, UR); + if (MyTimer && MyTimer->hasTriggered() && !MyTimer->isRunning()) + MyTimer->startTimer(); + PI.runAfterPass(Pass->name(), *C); // Update the SCC if necessary. Index: lib/IR/PassTimingInfo.cpp =================================================================== --- lib/IR/PassTimingInfo.cpp +++ lib/IR/PassTimingInfo.cpp @@ -135,4 +135,16 @@ PassTimingInfo::TheTimeInfo->print(); } +bool runTimerBeforePass(StringRef PassID, Any IR, PassExecutionCounter PC) { + Timer *MyTimer = getPassTimer(PassID); + if (MyTimer) + MyTimer->startTimer(); + return true; +} + +void stopTimerAfterPass(StringRef PassID, Any IR, PassExecutionCounter PC) { + Timer *MyTimer = getPassTimer(PassID); + if (MyTimer) + MyTimer->stopTimer(); +} } // namespace llvm Index: lib/Transforms/Scalar/LoopPassManager.cpp =================================================================== --- lib/Transforms/Scalar/LoopPassManager.cpp +++ lib/Transforms/Scalar/LoopPassManager.cpp @@ -33,6 +33,8 @@ dbgs() << "Starting Loop pass manager run.\n"; PassInstrumentation PI = AM.getPassInstrumentation(L, AR); + Timer *MyTimer = getPassTimer(this->name()); + for (auto &Pass : Passes) { if (DebugLogging) dbgs() << "Running pass: " << Pass->name() << " on " << L; @@ -40,8 +42,14 @@ if (!PI.runBeforePass(Pass->name(), L)) continue; + if (MyTimer && MyTimer->isRunning()) + MyTimer->stopTimer(); + PreservedAnalyses PassPA = Pass->run(L, AM, AR, U); + if (MyTimer && MyTimer->hasTriggered() && !MyTimer->isRunning()) + MyTimer->startTimer(); + PI.runAfterPass(Pass->name(), L); // If the loop was deleted, abort the run and return to the outer walk. Index: test/Other/time-passes.ll =================================================================== --- test/Other/time-passes.ll +++ test/Other/time-passes.ll @@ -1,4 +1,5 @@ ; RUN: opt < %s -disable-output -instcombine -time-passes 2>&1 | FileCheck %s --check-prefix=TIME --check-prefix=TIME-LEGACY +; RUN: opt < %s -disable-output -passes=instcombine -time-passes 2>&1 | FileCheck %s --check-prefix=TIME --check-prefix=TIME-NEW ; ; TIME: Pass execution timing report ; TIME: Total Execution Time: @@ -7,6 +8,10 @@ ; TIME-LEGACY-DAG: Dominator Tree Construction ; TIME-LEGACY-DAG: Module Verifier ; TIME-LEGACY-DAG: Target Library Information +; TIME-NEW-DAG: InstCombinePass +; TIME-NEW-DAG: VerifierPass +; TIME-NEW-DAG: DominatorTreeAnalysis +; TIME-NEW-DAG: TargetLibraryAnalysis ; TIME: 100{{.*}} Total{{$}} define i32 @foo() { Index: tools/opt/NewPMDriver.cpp =================================================================== --- tools/opt/NewPMDriver.cpp +++ tools/opt/NewPMDriver.cpp @@ -27,6 +27,7 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/PassManager.h" +#include "llvm/IR/PassTimingInfo.h" #include "llvm/IR/Verifier.h" #include "llvm/Passes/PassBuilder.h" #include "llvm/Passes/PassPlugin.h" @@ -189,6 +190,14 @@ PB.registerPassInstrumentation([](PassInstrumentationImpl &PI) { PI.registerAfterPassCallback(PrintIR::printAfterPass); }); + if (llvm::TimePassesIsEnabled) { + PB.registerPassInstrumentation([](PassInstrumentationImpl &PI) { + PI.registerBeforePassCallback(llvm::runTimerBeforePass); + PI.registerAfterPassCallback(llvm::stopTimerAfterPass); + PI.registerBeforeAnalysisCallback(llvm::runTimerBeforePass); + PI.registerAfterAnalysisCallback(llvm::stopTimerAfterPass); + }); + } } #ifdef LINK_POLLY_INTO_TOOLS