diff options
author | Fedor Sergeev <fedor.sergeev@azul.com> | 2018-08-28 21:06:51 +0000 |
---|---|---|
committer | Fedor Sergeev <fedor.sergeev@azul.com> | 2018-08-28 21:06:51 +0000 |
commit | 43083111a257f39282df92f3879dbaec54191337 (patch) | |
tree | bcad11c61a498dec3bdebe24da7fef1ddae2add9 | |
parent | 52e97a28d47bf50364bef55cc6a1119c8364f0b5 (diff) | |
download | bcm5719-llvm-43083111a257f39282df92f3879dbaec54191337.tar.gz bcm5719-llvm-43083111a257f39282df92f3879dbaec54191337.zip |
[NFC][PassTiming] factor out generic PassTimingInfo
Moving PassTimingInfo from legacy pass manager code into a separate header.
Making it suitable for both legacy and new pass manager.
Adding a test on -time-passes main functionality.
llvm-svn: 340872
-rw-r--r-- | llvm/include/llvm/IR/LegacyPassManagers.h | 1 | ||||
-rw-r--r-- | llvm/include/llvm/IR/PassTimingInfo.h | 69 | ||||
-rw-r--r-- | llvm/lib/Analysis/CallGraphSCCPass.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/Analysis/LoopPass.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/Analysis/RegionPass.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/IR/CMakeLists.txt | 1 | ||||
-rw-r--r-- | llvm/lib/IR/LegacyPassManager.cpp | 97 | ||||
-rw-r--r-- | llvm/lib/IR/PassTimingInfo.cpp | 132 | ||||
-rw-r--r-- | llvm/test/Other/time-passes.ll | 15 |
9 files changed, 221 insertions, 97 deletions
diff --git a/llvm/include/llvm/IR/LegacyPassManagers.h b/llvm/include/llvm/IR/LegacyPassManagers.h index f6752f2817b..c0b98dcf9eb 100644 --- a/llvm/include/llvm/IR/LegacyPassManagers.h +++ b/llvm/include/llvm/IR/LegacyPassManagers.h @@ -508,7 +508,6 @@ public: } }; -Timer *getPassTimer(Pass *); } #endif diff --git a/llvm/include/llvm/IR/PassTimingInfo.h b/llvm/include/llvm/IR/PassTimingInfo.h new file mode 100644 index 00000000000..5f3bdcd02ce --- /dev/null +++ b/llvm/include/llvm/IR/PassTimingInfo.h @@ -0,0 +1,69 @@ +//===- PassTimingInfo.h - pass execution timing -----------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// +/// This header defines classes/functions to handle pass execution timing +/// information with an interface suitable for both pass managers. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IR_PASSTIMINGINFO_H +#define LLVM_IR_PASSTIMINGINFO_H + +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Timer.h" +#include <string> + +namespace llvm { + +class Pass; +class TimerGroup; + +/// Provides a generic interface for collecting pass timing information. +/// Legacy pass managers should specialize with \p PassInfo*. +/// New pass managers should specialize with \p StringRef. +template <typename PassInfoT> class PassTimingInfo { + StringMap<Timer *> TimingData; + TimerGroup TG; + +public: + /// Default constructor for yet-inactive timeinfo. + /// Use \p init() to activate it. + PassTimingInfo(); + + /// Print out timing information and release timers. + ~PassTimingInfo(); + + /// Initializes the static \p TheTimeInfo member to a non-null value when + /// -time-passes is enabled. Leaves it null otherwise. + /// + /// This method may be called multiple times. + static void init(); + + /// Prints out timing information and then resets the timers. + void print(); + + /// Returns the timer for the specified pass if it exists. + Timer *getPassTimer(PassInfoT); + + static PassTimingInfo *TheTimeInfo; +}; + +Timer *getPassTimer(Pass *); +Timer *getPassTimer(StringRef); + +/// If the user specifies the -time-passes argument on an LLVM tool command line +/// then the value of this boolean will be true, otherwise false. +/// This is the storage for the -time-passes option. +extern bool TimePassesIsEnabled; + +} // namespace llvm + +#endif diff --git a/llvm/lib/Analysis/CallGraphSCCPass.cpp b/llvm/lib/Analysis/CallGraphSCCPass.cpp index 4c33c420b65..df652552bd6 100644 --- a/llvm/lib/Analysis/CallGraphSCCPass.cpp +++ b/llvm/lib/Analysis/CallGraphSCCPass.cpp @@ -27,6 +27,7 @@ #include "llvm/IR/LegacyPassManagers.h" #include "llvm/IR/Module.h" #include "llvm/IR/OptBisect.h" +#include "llvm/IR/PassTimingInfo.h" #include "llvm/Pass.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" diff --git a/llvm/lib/Analysis/LoopPass.cpp b/llvm/lib/Analysis/LoopPass.cpp index 07a151ce0fc..f4f00f063a0 100644 --- a/llvm/lib/Analysis/LoopPass.cpp +++ b/llvm/lib/Analysis/LoopPass.cpp @@ -20,6 +20,7 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/OptBisect.h" #include "llvm/IR/PassManager.h" +#include "llvm/IR/PassTimingInfo.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" diff --git a/llvm/lib/Analysis/RegionPass.cpp b/llvm/lib/Analysis/RegionPass.cpp index ed17df2e7e9..a101ff10919 100644 --- a/llvm/lib/Analysis/RegionPass.cpp +++ b/llvm/lib/Analysis/RegionPass.cpp @@ -15,6 +15,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/RegionPass.h" #include "llvm/IR/OptBisect.h" +#include "llvm/IR/PassTimingInfo.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" diff --git a/llvm/lib/IR/CMakeLists.txt b/llvm/lib/IR/CMakeLists.txt index 0a78a0f8d81..a194b840e0e 100644 --- a/llvm/lib/IR/CMakeLists.txt +++ b/llvm/lib/IR/CMakeLists.txt @@ -44,6 +44,7 @@ add_llvm_library(LLVMCore Pass.cpp PassManager.cpp PassRegistry.cpp + PassTimingInfo.cpp SafepointIRVerifier.cpp ProfileSummary.cpp Statepoint.cpp diff --git a/llvm/lib/IR/LegacyPassManager.cpp b/llvm/lib/IR/LegacyPassManager.cpp index d11a2b3c01a..dbef00af45b 100644 --- a/llvm/lib/IR/LegacyPassManager.cpp +++ b/llvm/lib/IR/LegacyPassManager.cpp @@ -20,6 +20,7 @@ #include "llvm/IR/LegacyPassManagers.h" #include "llvm/IR/LegacyPassNameParser.h" #include "llvm/IR/Module.h" +#include "llvm/IR/PassTimingInfo.h" #include "llvm/Support/Chrono.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" @@ -494,65 +495,6 @@ char PassManagerImpl::ID = 0; } // End of legacy namespace } // End of llvm namespace -namespace { - -//===----------------------------------------------------------------------===// -/// TimingInfo Class - This class is used to calculate information about the -/// amount of time each pass takes to execute. This only happens when -/// -time-passes is enabled on the command line. -/// - -static ManagedStatic<sys::SmartMutex<true> > TimingInfoMutex; - -class TimingInfo { - DenseMap<Pass*, Timer*> TimingData; - TimerGroup TG; -public: - // Use 'create' member to get this. - TimingInfo() : TG("pass", "... Pass execution timing report ...") {} - - // TimingDtor - Print out information about timing information - ~TimingInfo() { - // Delete all of the timers, which accumulate their info into the - // TimerGroup. - for (auto &I : TimingData) - delete I.second; - // TimerGroup is deleted next, printing the report. - } - - // createTheTimeInfo - This method either initializes the TheTimeInfo pointer - // to a non-null value (if the -time-passes option is enabled) or it leaves it - // null. It may be called multiple times. - static void createTheTimeInfo(); - - // print - Prints out timing information and then resets the timers. - void print() { - TG.print(*CreateInfoOutputFile()); - } - - /// getPassTimer - Return the timer for the specified pass if it exists. - Timer *getPassTimer(Pass *P) { - if (P->getAsPMDataManager()) - return nullptr; - - sys::SmartScopedLock<true> Lock(*TimingInfoMutex); - Timer *&T = TimingData[P]; - if (!T) { - StringRef PassName = P->getPassName(); - StringRef PassArgument; - if (const PassInfo *PI = Pass::lookupPassInfo(P->getPassID())) - PassArgument = PI->getPassArgument(); - T = new Timer(PassArgument.empty() ? PassName : PassArgument, PassName, - TG); - } - return T; - } -}; - -} // End of anon namespace - -static TimingInfo *TheTimeInfo; - //===----------------------------------------------------------------------===// // PMTopLevelManager implementation @@ -1527,7 +1469,6 @@ void FunctionPassManagerImpl::releaseMemoryOnTheFly() { // Return true if any function is modified by a pass. bool FunctionPassManagerImpl::run(Function &F) { bool Changed = false; - TimingInfo::createTheTimeInfo(); initializeAllAnalysisInfo(); for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) { @@ -1763,7 +1704,6 @@ Pass* MPPassManager::getOnTheFlyPass(Pass *MP, AnalysisID PI, Function &F){ /// whether any of the passes modifies the module, and if so, return true. bool PassManagerImpl::run(Module &M) { bool Changed = false; - TimingInfo::createTheTimeInfo(); dumpArguments(); dumpPasses(); @@ -1808,41 +1748,6 @@ bool PassManager::run(Module &M) { } //===----------------------------------------------------------------------===// -// TimingInfo implementation - -bool llvm::TimePassesIsEnabled = false; -static cl::opt<bool, true> EnableTiming( - "time-passes", cl::location(TimePassesIsEnabled), cl::Hidden, - cl::desc("Time each pass, printing elapsed time for each on exit")); - -// createTheTimeInfo - This method either initializes the TheTimeInfo pointer to -// a non-null value (if the -time-passes option is enabled) or it leaves it -// null. It may be called multiple times. -void TimingInfo::createTheTimeInfo() { - if (!TimePassesIsEnabled || TheTimeInfo) return; - - // Constructed the first time this is called, iff -time-passes is enabled. - // This guarantees that the object will be constructed before static globals, - // thus it will be destroyed before them. - static ManagedStatic<TimingInfo> TTI; - TheTimeInfo = &*TTI; -} - -/// If TimingInfo is enabled then start pass timer. -Timer *llvm::getPassTimer(Pass *P) { - if (TheTimeInfo) - return TheTimeInfo->getPassTimer(P); - return nullptr; -} - -/// If timing is enabled, report the times collected up to now and then reset -/// them. -void llvm::reportAndResetTimings() { - if (TheTimeInfo) - TheTimeInfo->print(); -} - -//===----------------------------------------------------------------------===// // PMStack implementation // diff --git a/llvm/lib/IR/PassTimingInfo.cpp b/llvm/lib/IR/PassTimingInfo.cpp new file mode 100644 index 00000000000..c1efc651b7e --- /dev/null +++ b/llvm/lib/IR/PassTimingInfo.cpp @@ -0,0 +1,132 @@ +//===- PassTimingInfo.cpp - LLVM Pass Timing Implementation ---------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the LLVM Pass Timing infrastructure for both +// new and legacy pass managers. +// +// TimingInfo Class - This class is used to calculate information about the +// amount of time each pass takes to execute. This only happens when +// -time-passes is enabled on the command line. +// +//===----------------------------------------------------------------------===// + +#include "llvm/IR/PassTimingInfo.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Pass.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/Mutex.h" +#include "llvm/Support/Timer.h" +#include "llvm/Support/raw_ostream.h" +#include <string> + +using namespace llvm; + +namespace llvm { + +//===----------------------------------------------------------------------===// +// TimingInfo implementation + +bool TimePassesIsEnabled = false; +static cl::opt<bool, true> EnableTiming( + "time-passes", cl::location(TimePassesIsEnabled), cl::Hidden, + cl::desc("Time each pass, printing elapsed time for each on exit")); + +namespace { +static ManagedStatic<sys::SmartMutex<true>> TimingInfoMutex; +} + +template <typename PassT> +PassTimingInfo<PassT>::PassTimingInfo() + : TG("pass", "... Pass execution timing report ...") {} + +template <typename PassT> PassTimingInfo<PassT>::~PassTimingInfo() { + // Deleting the timers accumulates their info into the TG member. + // Then TG member is (implicitly) deleted, actually printing the report. + for (auto &I : TimingData) + delete I.getValue(); +} + +template <typename PassT> void PassTimingInfo<PassT>::init() { + if (!TimePassesIsEnabled || TheTimeInfo) + return; + + // Constructed the first time this is called, iff -time-passes is enabled. + // This guarantees that the object will be constructed before static globals, + // thus it will be destroyed before them. + static ManagedStatic<PassTimingInfo> TTI; + TheTimeInfo = &*TTI; +} + +/// Prints out timing information and then resets the timers. +template <typename PassT> void PassTimingInfo<PassT>::print() { + TG.print(*CreateInfoOutputFile()); +} + +/// Return the timer for the specified pass if it exists. +template <> Timer *PassTimingInfo<StringRef>::getPassTimer(StringRef PassName) { + init(); + sys::SmartScopedLock<true> Lock(*TimingInfoMutex); + Timer *&T = TimingData[PassName]; + if (!T) + T = new Timer(PassName, PassName, TG); + return T; +} + +template <> Timer *PassTimingInfo<Pass *>::getPassTimer(Pass *P) { + if (P->getAsPMDataManager()) + return nullptr; + + init(); + sys::SmartScopedLock<true> Lock(*TimingInfoMutex); + StringRef PassName = P->getPassName(); + Timer *&T = TimingData[PassName]; + + if (!T) { + StringRef PassArgument; + if (const PassInfo *PI = Pass::lookupPassInfo(P->getPassID())) + PassArgument = PI->getPassArgument(); + T = new Timer(PassArgument.empty() ? PassName : PassArgument, PassName, TG); + } + return T; +} + +template <typename PassInfoT> +PassTimingInfo<PassInfoT> *PassTimingInfo<PassInfoT>::TheTimeInfo; + +template class PassTimingInfo<Pass *>; +template class PassTimingInfo<StringRef>; + +Timer *getPassTimer(Pass *P) { + PassTimingInfo<Pass *>::init(); + if (PassTimingInfo<Pass *>::TheTimeInfo) + return PassTimingInfo<Pass *>::TheTimeInfo->getPassTimer(P); + return nullptr; +} + +Timer *getPassTimer(StringRef PassName) { + PassTimingInfo<StringRef>::init(); + if (PassTimingInfo<StringRef>::TheTimeInfo) + return PassTimingInfo<StringRef>::TheTimeInfo->getPassTimer(PassName); + return nullptr; +} + +/// If timing is enabled, report the times collected up to now and then reset +/// them. +void reportAndResetTimings() { + if (PassTimingInfo<StringRef>::TheTimeInfo) + PassTimingInfo<StringRef>::TheTimeInfo->print(); + if (PassTimingInfo<Pass *>::TheTimeInfo) + PassTimingInfo<Pass *>::TheTimeInfo->print(); +} + +} // namespace llvm diff --git a/llvm/test/Other/time-passes.ll b/llvm/test/Other/time-passes.ll new file mode 100644 index 00000000000..30325de0ff1 --- /dev/null +++ b/llvm/test/Other/time-passes.ll @@ -0,0 +1,15 @@ +; RUN: opt < %s -disable-output -instcombine -time-passes 2>&1 | FileCheck %s --check-prefix=TIME --check-prefix=TIME-LEGACY +; +; TIME: Pass execution timing report +; TIME: Total Execution Time: +; TIME: Name +; TIME-LEGACY-DAG: Combine redundant instructions +; TIME-LEGACY-DAG: Dominator Tree Construction +; TIME-LEGACY-DAG: Module Verifier +; TIME-LEGACY-DAG: Target Library Information +; TIME: 100{{.*}} Total{{$}} + +define i32 @foo() { + %res = add i32 5, 4 + ret i32 %res +} |