11
11
// ===----------------------------------------------------------------------===//
12
12
13
13
#include " llvm/Support/TimeProfiler.h"
14
+ #include " llvm/ADT/STLExtras.h"
14
15
#include " llvm/ADT/STLFunctionalExtras.h"
15
16
#include " llvm/ADT/StringMap.h"
16
17
#include " llvm/Support/JSON.h"
20
21
#include < algorithm>
21
22
#include < cassert>
22
23
#include < chrono>
24
+ #include < memory>
23
25
#include < mutex>
24
26
#include < string>
25
27
#include < vector>
@@ -64,8 +66,10 @@ using CountAndDurationType = std::pair<size_t, DurationType>;
64
66
using NameAndCountAndDurationType =
65
67
std::pair<std::string, CountAndDurationType>;
66
68
69
+ } // anonymous namespace
70
+
67
71
// / Represents an open or completed time section entry to be captured.
68
- struct TimeTraceProfilerEntry {
72
+ struct llvm :: TimeTraceProfilerEntry {
69
73
const TimePointType Start;
70
74
TimePointType End;
71
75
const std::string Name;
@@ -92,8 +96,6 @@ struct TimeTraceProfilerEntry {
92
96
}
93
97
};
94
98
95
- } // anonymous namespace
96
-
97
99
struct llvm ::TimeTraceProfiler {
98
100
TimeTraceProfiler (unsigned TimeTraceGranularity = 0 , StringRef ProcName = " " )
99
101
: BeginningOfTime(system_clock::now()), StartTime(ClockType::now()),
@@ -102,23 +104,22 @@ struct llvm::TimeTraceProfiler {
102
104
llvm::get_thread_name (ThreadName);
103
105
}
104
106
105
- void begin (std::string Name, llvm::function_ref<std::string()> Detail) {
106
- Stack.emplace_back (ClockType::now (), TimePointType (), std::move (Name),
107
- Detail ());
107
+ TimeTraceProfilerEntry *begin (std::string Name,
108
+ llvm::function_ref<std::string()> Detail) {
109
+ Stack.emplace_back (std::make_unique<TimeTraceProfilerEntry>(
110
+ ClockType::now (), TimePointType (), std::move (Name), Detail ()));
111
+ return Stack.back ().get ();
108
112
}
109
113
110
114
void end () {
115
+ TimeTraceProfilerEntry *E = Stack.back ().get ();
116
+ end (*E);
117
+ }
118
+
119
+ void end (TimeTraceProfilerEntry &E) {
111
120
assert (!Stack.empty () && " Must call begin() first" );
112
- TimeTraceProfilerEntry &E = Stack.back ();
113
121
E.End = ClockType::now ();
114
122
115
- // Check that end times monotonically increase.
116
- assert ((Entries.empty () ||
117
- (E.getFlameGraphStartUs (StartTime) + E.getFlameGraphDurUs () >=
118
- Entries.back ().getFlameGraphStartUs (StartTime) +
119
- Entries.back ().getFlameGraphDurUs ())) &&
120
- " TimeProfiler scope ended earlier than previous scope" );
121
-
122
123
// Calculate duration at full precision for overall counts.
123
124
DurationType Duration = E.End - E.Start ;
124
125
@@ -132,15 +133,18 @@ struct llvm::TimeTraceProfiler {
132
133
// happens to be the ones that don't have any currently open entries above
133
134
// itself.
134
135
if (llvm::none_of (llvm::drop_begin (llvm::reverse (Stack)),
135
- [&](const TimeTraceProfilerEntry &Val) {
136
- return Val. Name == E.Name ;
136
+ [&](const std::unique_ptr< TimeTraceProfilerEntry> &Val) {
137
+ return Val-> Name == E.Name ;
137
138
})) {
138
139
auto &CountAndTotal = CountAndTotalPerName[E.Name ];
139
140
CountAndTotal.first ++;
140
141
CountAndTotal.second += Duration;
141
- }
142
+ };
142
143
143
- Stack.pop_back ();
144
+ llvm::erase_if (Stack,
145
+ [&](const std::unique_ptr<TimeTraceProfilerEntry> &Val) {
146
+ return Val.get () == &E;
147
+ });
144
148
}
145
149
146
150
// Write events from this TimeTraceProfilerInstance and
@@ -269,7 +273,7 @@ struct llvm::TimeTraceProfiler {
269
273
J.objectEnd ();
270
274
}
271
275
272
- SmallVector<TimeTraceProfilerEntry, 16 > Stack;
276
+ SmallVector<std::unique_ptr< TimeTraceProfilerEntry> , 16 > Stack;
273
277
SmallVector<TimeTraceProfilerEntry, 128 > Entries;
274
278
StringMap<CountAndDurationType> CountAndTotalPerName;
275
279
// System clock time when the session was begun.
@@ -341,19 +345,28 @@ Error llvm::timeTraceProfilerWrite(StringRef PreferredFileName,
341
345
return Error::success ();
342
346
}
343
347
344
- void llvm::timeTraceProfilerBegin (StringRef Name, StringRef Detail) {
348
+ TimeTraceProfilerEntry *llvm::timeTraceProfilerBegin (StringRef Name,
349
+ StringRef Detail) {
345
350
if (TimeTraceProfilerInstance != nullptr )
346
- TimeTraceProfilerInstance->begin (std::string (Name),
347
- [&]() { return std::string (Detail); });
351
+ return TimeTraceProfilerInstance->begin (
352
+ std::string (Name), [&]() { return std::string (Detail); });
353
+ return nullptr ;
348
354
}
349
355
350
- void llvm::timeTraceProfilerBegin (StringRef Name,
351
- llvm::function_ref<std::string()> Detail) {
356
+ TimeTraceProfilerEntry *
357
+ llvm::timeTraceProfilerBegin (StringRef Name,
358
+ llvm::function_ref<std::string()> Detail) {
352
359
if (TimeTraceProfilerInstance != nullptr )
353
- TimeTraceProfilerInstance->begin (std::string (Name), Detail);
360
+ return TimeTraceProfilerInstance->begin (std::string (Name), Detail);
361
+ return nullptr ;
354
362
}
355
363
356
364
void llvm::timeTraceProfilerEnd () {
357
365
if (TimeTraceProfilerInstance != nullptr )
358
366
TimeTraceProfilerInstance->end ();
359
367
}
368
+
369
+ void llvm::timeTraceProfilerEnd (TimeTraceProfilerEntry *E) {
370
+ if (TimeTraceProfilerInstance != nullptr )
371
+ TimeTraceProfilerInstance->end (*E);
372
+ }
0 commit comments