1313#include " llvm/Support/TimeProfiler.h"
1414#include " llvm/ADT/STLExtras.h"
1515#include " llvm/ADT/STLFunctionalExtras.h"
16+ #include " llvm/ADT/SmallVector.h"
1617#include " llvm/ADT/StringMap.h"
1718#include " llvm/Support/JSON.h"
1819#include " llvm/Support/Path.h"
@@ -70,23 +71,23 @@ using NameAndCountAndDurationType =
7071
7172// / Represents an open or completed time section entry to be captured.
7273struct llvm ::TimeTraceProfilerEntry {
73- const TimePointType Start;
74+ TimePointType Start;
7475 TimePointType End;
75- const std::string Name;
76+ std::string Name;
7677 TimeTraceMetadata Metadata;
78+ TimeTraceEventType EventType;
7779
78- const bool AsyncEvent = false ;
7980 TimeTraceProfilerEntry (TimePointType &&S, TimePointType &&E, std::string &&N,
80- std::string &&Dt, bool Ae )
81+ std::string &&Dt, TimeTraceEventType Et )
8182 : Start(std::move(S)), End(std::move(E)), Name(std::move(N)), Metadata(),
82- AsyncEvent (Ae ) {
83+ EventType (Et ) {
8384 Metadata.Detail = std::move (Dt);
8485 }
8586
8687 TimeTraceProfilerEntry (TimePointType &&S, TimePointType &&E, std::string &&N,
87- TimeTraceMetadata &&Mt, bool Ae )
88+ TimeTraceMetadata &&Mt, TimeTraceEventType Et )
8889 : Start(std::move(S)), End(std::move(E)), Name(std::move(N)),
89- Metadata(std::move(Mt)), AsyncEvent(Ae ) {}
90+ Metadata(std::move(Mt)), EventType(Et ) {}
9091
9192 // Calculate timings for FlameGraph. Cast time points to microsecond precision
9293 // rather than casting duration. This avoids truncation issues causing inner
@@ -116,19 +117,19 @@ struct llvm::TimeTraceProfiler {
116117
117118 TimeTraceProfilerEntry *begin (std::string Name,
118119 llvm::function_ref<std::string()> Detail,
119- bool AsyncEvent = false ) {
120+ TimeTraceEventType Et = TimeTraceEventType::CompleteEvent ) {
120121 Stack.emplace_back (std::make_unique<TimeTraceProfilerEntry>(
121122 ClockType::now (), TimePointType (), std::move (Name), Detail (),
122- AsyncEvent ));
123+ Et ));
123124 return Stack.back ().get ();
124125 }
125126
126127 TimeTraceProfilerEntry *
127128 begin (std::string Name, llvm::function_ref<TimeTraceMetadata()> Metadata,
128- bool AsyncEvent = false ) {
129+ TimeTraceEventType Et = TimeTraceEventType::CompleteEvent ) {
129130 Stack.emplace_back (std::make_unique<TimeTraceProfilerEntry>(
130131 ClockType::now (), TimePointType (), std::move (Name), Metadata (),
131- AsyncEvent ));
132+ Et ));
132133 return Stack.back ().get ();
133134 }
134135
@@ -144,9 +145,22 @@ struct llvm::TimeTraceProfiler {
144145 // Calculate duration at full precision for overall counts.
145146 DurationType Duration = E.End - E.Start ;
146147
147- // Only include sections longer or equal to TimeTraceGranularity msec.
148- if (duration_cast<microseconds>(Duration).count () >= TimeTraceGranularity)
148+ // Only include Instant Events or events with a duration longer or equal to
149+ // TimeTraceGranularity msec.
150+ if (E.EventType == TimeTraceEventType::InstantEvent ||
151+ duration_cast<microseconds>(Duration).count () >= TimeTraceGranularity) {
149152 Entries.emplace_back (E);
153+ } else {
154+ // if the event is not included, exclude also all instant events that
155+ // happened during this event.
156+ for (SmallVector<TimeTraceProfilerEntry, 128 >::iterator it = Entries.begin (); it != Entries.end ();) {
157+ if (TimeTraceEventType::InstantEvent == it->EventType &&
158+ it->Start > E.Start && it->Start < E.End )
159+ it = Entries.erase (it);
160+ else
161+ ++it;
162+ }
163+ }
150164
151165 // Track total time taken by each "name", but only the topmost levels of
152166 // them; e.g. if there's a template instantiation that instantiates other
@@ -194,13 +208,15 @@ struct llvm::TimeTraceProfiler {
194208 J.attribute (" pid" , Pid);
195209 J.attribute (" tid" , int64_t (Tid));
196210 J.attribute (" ts" , StartUs);
197- if (E.AsyncEvent ) {
211+ if (E.EventType == TimeTraceEventType:: AsyncEvent) {
198212 J.attribute (" cat" , E.Name );
199213 J.attribute (" ph" , " b" );
200214 J.attribute (" id" , 0 );
201- } else {
215+ } else if (E. EventType == TimeTraceEventType::CompleteEvent) {
202216 J.attribute (" ph" , " X" );
203217 J.attribute (" dur" , DurUs);
218+ } else { // instant event
219+ J.attribute (" ph" , " i" );
204220 }
205221 J.attribute (" name" , E.Name );
206222 if (!E.Metadata .isEmpty ()) {
@@ -215,7 +231,7 @@ struct llvm::TimeTraceProfiler {
215231 }
216232 });
217233
218- if (E.AsyncEvent ) {
234+ if (E.EventType == TimeTraceEventType:: AsyncEvent) {
219235 J.object ([&] {
220236 J.attribute (" pid" , Pid);
221237 J.attribute (" tid" , int64_t (Tid));
@@ -406,31 +422,39 @@ TimeTraceProfilerEntry *llvm::timeTraceProfilerBegin(StringRef Name,
406422 StringRef Detail) {
407423 if (TimeTraceProfilerInstance != nullptr )
408424 return TimeTraceProfilerInstance->begin (
409- std::string (Name), [&]() { return std::string (Detail); }, false );
425+ std::string (Name), [&]() { return std::string (Detail); }, TimeTraceEventType::CompleteEvent );
410426 return nullptr ;
411427}
412428
413429TimeTraceProfilerEntry *
414430llvm::timeTraceProfilerBegin (StringRef Name,
415431 llvm::function_ref<std::string()> Detail) {
416432 if (TimeTraceProfilerInstance != nullptr )
417- return TimeTraceProfilerInstance->begin (std::string (Name), Detail, false );
433+ return TimeTraceProfilerInstance->begin (std::string (Name), Detail, TimeTraceEventType::CompleteEvent );
418434 return nullptr ;
419435}
420436
421437TimeTraceProfilerEntry *
422438llvm::timeTraceProfilerBegin (StringRef Name,
423439 llvm::function_ref<TimeTraceMetadata()> Metadata) {
424440 if (TimeTraceProfilerInstance != nullptr )
425- return TimeTraceProfilerInstance->begin (std::string (Name), Metadata, false );
441+ return TimeTraceProfilerInstance->begin (std::string (Name), Metadata, TimeTraceEventType::CompleteEvent);
442+ return nullptr ;
443+ }
444+
445+ TimeTraceProfilerEntry *
446+ llvm::timeTraceInstantEventProfilerBegin (StringRef Name,
447+ llvm::function_ref<TimeTraceMetadata()> Metadata) {
448+ if (TimeTraceProfilerInstance != nullptr )
449+ return TimeTraceProfilerInstance->begin (std::string (Name), Metadata, TimeTraceEventType::InstantEvent);
426450 return nullptr ;
427451}
428452
429453TimeTraceProfilerEntry *llvm::timeTraceAsyncProfilerBegin (StringRef Name,
430454 StringRef Detail) {
431455 if (TimeTraceProfilerInstance != nullptr )
432456 return TimeTraceProfilerInstance->begin (
433- std::string (Name), [&]() { return std::string (Detail); }, true );
457+ std::string (Name), [&]() { return std::string (Detail); }, TimeTraceEventType::AsyncEvent );
434458 return nullptr ;
435459}
436460
0 commit comments