summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFedor Sergeev <fedor.sergeev@azul.com>2018-08-28 21:06:51 +0000
committerFedor Sergeev <fedor.sergeev@azul.com>2018-08-28 21:06:51 +0000
commit43083111a257f39282df92f3879dbaec54191337 (patch)
treebcad11c61a498dec3bdebe24da7fef1ddae2add9
parent52e97a28d47bf50364bef55cc6a1119c8364f0b5 (diff)
downloadbcm5719-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.h1
-rw-r--r--llvm/include/llvm/IR/PassTimingInfo.h69
-rw-r--r--llvm/lib/Analysis/CallGraphSCCPass.cpp1
-rw-r--r--llvm/lib/Analysis/LoopPass.cpp1
-rw-r--r--llvm/lib/Analysis/RegionPass.cpp1
-rw-r--r--llvm/lib/IR/CMakeLists.txt1
-rw-r--r--llvm/lib/IR/LegacyPassManager.cpp97
-rw-r--r--llvm/lib/IR/PassTimingInfo.cpp132
-rw-r--r--llvm/test/Other/time-passes.ll15
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
+}
OpenPOWER on IntegriCloud