1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
//===- 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/FormatVariadic.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.getSecond();
}
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 after 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());
}
template <typename PassInfoT>
Timer *PassTimingInfo<PassInfoT>::newPassTimer(StringRef PassID,
StringRef PassDesc) {
unsigned &num = PassIDCountMap[PassID];
num++;
// Appending description with a pass-instance number for all but the first one
std::string PassDescNumbered =
num <= 1 ? PassDesc.str() : formatv("{0} #{1}", PassDesc, num).str();
return new Timer(PassID, PassDescNumbered, TG);
}
/// Returns the timer for the specified pass instance \p Pass.
/// Instances of the same pass type (uniquely identified by \p PassID) are
/// numbered by the order of appearance.
template <>
Timer *PassTimingInfo<StringRef>::getPassTimer(StringRef PassID,
PassInstanceID Pass) {
init();
sys::SmartScopedLock<true> Lock(*TimingInfoMutex);
Timer *&T = TimingData[Pass];
if (!T)
T = newPassTimer(PassID, PassID);
return T;
}
template <>
Timer *PassTimingInfo<Pass *>::getPassTimer(Pass *P, PassInstanceID Pass) {
if (P->getAsPMDataManager())
return nullptr;
init();
sys::SmartScopedLock<true> Lock(*TimingInfoMutex);
Timer *&T = TimingData[Pass];
if (!T) {
StringRef PassName = P->getPassName();
StringRef PassArgument;
if (const PassInfo *PI = Pass::lookupPassInfo(P->getPassID()))
PassArgument = PI->getPassArgument();
T = newPassTimer(PassArgument.empty() ? PassName : PassArgument, PassName);
}
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, P);
return nullptr;
}
Timer *getPassTimer(StringRef PassName) {
PassTimingInfo<StringRef>::init();
if (PassTimingInfo<StringRef>::TheTimeInfo)
return PassTimingInfo<StringRef>::TheTimeInfo->getPassTimer(PassName,
nullptr);
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
|