34using std::chrono::duration;
35using std::chrono::duration_cast;
36using std::chrono::microseconds;
37using std::chrono::steady_clock;
39using std::chrono::time_point;
40using std::chrono::time_point_cast;
42struct TimeTraceProfilerInstances {
44 std::vector<TimeTraceProfiler *>
List;
47TimeTraceProfilerInstances &getTimeTraceProfilerInstances() {
48 static TimeTraceProfilerInstances Instances;
63using ClockType = steady_clock;
64using TimePointType = time_point<ClockType>;
65using DurationType = duration<ClockType::rep, ClockType::period>;
66using CountAndDurationType = std::pair<size_t, DurationType>;
67using NameAndCountAndDurationType =
68 std::pair<std::string, CountAndDurationType>;
96 return (time_point_cast<microseconds>(
Start) -
97 time_point_cast<microseconds>(StartTime))
102 return (time_point_cast<microseconds>(
End) -
103 time_point_cast<microseconds>(
Start))
141 "Instant Events don't have begin and end.");
143 ClockType::now(), TimePointType(), std::move(
Name), Detail(),
152 "Instant Events don't have begin and end.");
154 ClockType::now(), TimePointType(), std::move(
Name),
Metadata(),
164 ClockType::now(), TimePointType(), std::move(
Name), Detail(),
175 E.
End = ClockType::now();
182 return &Val->Event == &E;
189 for (
auto &IE : Iter->get()->InstantEvents) {
200 [&](
const std::unique_ptr<InProgressEntry> &Val) {
201 return Val->Event.Name == E.
Name;
204 CountAndTotal.first++;
215 auto &Instances = getTimeTraceProfilerInstances();
216 std::lock_guard<std::mutex> Lock(Instances.Lock);
218 "All profiler sections should be ended when calling write");
220 [](
const auto &TTP) { return TTP->Stack.empty(); }) &&
221 "All profiler sections should be ended when calling write");
229 auto writeEvent = [&](
const auto &E,
uint64_t Tid) {
230 auto StartUs = E.getFlameGraphStartUs(
StartTime);
231 auto DurUs = E.getFlameGraphDurUs();
246 "InstantEvent expected");
250 if (!E.Metadata.isEmpty()) {
252 if (!E.Metadata.Detail.empty())
253 J.
attribute(
"detail", E.Metadata.Detail);
254 if (!E.Metadata.File.empty())
256 if (E.Metadata.Line > 0)
275 writeEvent(E, this->
Tid);
278 writeEvent(E, TTP->
Tid);
285 MaxTid = std::max(MaxTid, TTP->
Tid);
289 auto combineStat = [&](
const auto &Stat) {
291 auto Value = Stat.getValue();
292 auto &CountAndTotal = AllCountAndTotalPerName[Key];
293 CountAndTotal.first +=
Value.first;
294 CountAndTotal.second +=
Value.second;
302 std::vector<NameAndCountAndDurationType> SortedTotals;
303 SortedTotals.reserve(AllCountAndTotalPerName.
size());
304 for (
const auto &
Total : AllCountAndTotalPerName)
305 SortedTotals.emplace_back(std::string(
Total.getKey()),
Total.getValue());
307 llvm::sort(SortedTotals, [](
const NameAndCountAndDurationType &
A,
308 const NameAndCountAndDurationType &
B) {
309 return A.second.second >
B.second.second;
314 for (
const NameAndCountAndDurationType &
Total : SortedTotals) {
315 auto DurUs = duration_cast<microseconds>(
Total.second.second).count();
316 auto Count = AllCountAndTotalPerName[
Total.first].first;
326 J.attribute(
"count", int64_t(Count));
327 J.attribute(
"avg ms", int64_t(DurUs / Count / 1000));
350 writeMetadataEvent(
"thread_name", TTP->
Tid, TTP->
ThreadName);
393 bool TimeTraceVerbose) {
395 "Profiler should not be initialized");
407 auto &Instances = getTimeTraceProfilerInstances();
408 std::lock_guard<std::mutex> Lock(Instances.Lock);
409 for (
auto *TTP : Instances.List)
411 Instances.List.clear();
417 auto &Instances = getTimeTraceProfilerInstances();
418 std::lock_guard<std::mutex> Lock(Instances.Lock);
425 "Profiler object can't be null");
432 "Profiler object can't be null");
434 std::string Path = PreferredFileName.
str();
436 Path = FallbackFileName ==
"-" ?
"out" : FallbackFileName.
str();
437 Path +=
".time-trace";
453 std::string(
Name), [&]() {
return std::string(Detail); },
454 TimeTraceEventType::CompleteEvent);
463 TimeTraceEventType::CompleteEvent);
472 TimeTraceEventType::CompleteEvent);
480 std::string(
Name), [&]() {
return std::string(Detail); },
481 TimeTraceEventType::AsyncEvent);
This file defines the StringMap class.
static sys::TimePoint< std::chrono::seconds > now(bool Deterministic)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_THREAD_LOCAL
\macro LLVM_THREAD_LOCAL A thread-local storage specifier which can be used with globals,...
This file supports working with JSON data.
Provides a library for accessing information about this process and other processes on the operating ...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
static LLVM_THREAD_LOCAL TimeTraceProfiler * TimeTraceProfilerInstance
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
reference emplace_back(ArgTypes &&... Args)
iterator erase(const_iterator CI)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
LLVM Value Representation.
An efficient, type-erasing, non-owning reference to a callable.
json::OStream allows writing well-formed JSON without materializing all structures as json::Value ahe...
void object(Block Contents)
Emit an object whose elements are emitted in the provided Block.
void attributeObject(llvm::StringRef Key, Block Contents)
Emit an attribute whose value is an object with attributes from the Block.
void attributeBegin(llvm::StringRef Key)
void attribute(llvm::StringRef Key, const Value &Contents)
Emit an attribute whose value is self-contained (number, vector<int> etc).
A raw_ostream that writes to a file descriptor.
An abstract base class for streams implementations that also support a pwrite operation.
A collection of legacy interfaces for querying information about the current executing process.
@ OF_TextWithCRLF
The file should be opened in text mode and use a carriage linefeed '\r '.
StringRef filename(StringRef path, Style style=Style::native)
Get filename.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
TimeTraceProfiler * getTimeTraceProfilerInstance()
void timeTraceProfilerInitialize(unsigned TimeTraceGranularity, StringRef ProcName, bool TimeTraceVerbose=false)
Initialize the time trace profiler.
auto reverse(ContainerTy &&C)
void timeTraceProfilerFinishThread()
Finish a time trace profiler running on a worker thread.
void sort(IteratorTy Start, IteratorTy End)
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
void timeTraceProfilerEnd()
Manually end the last time section.
void timeTraceAddInstantEvent(StringRef Name, llvm::function_ref< std::string()> Detail)
void get_thread_name(SmallVectorImpl< char > &Name)
Get the name of the current thread.
TimeTraceProfilerEntry * timeTraceAsyncProfilerBegin(StringRef Name, StringRef Detail)
Manually begin a time section, with the given Name and Detail.
bool isTimeTraceVerbose()
uint64_t get_threadid()
Return the current thread id, as used in various OS system calls.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
void timeTraceProfilerCleanup()
Cleanup the time trace profiler, if it was initialized.
void timeTraceProfilerWrite(raw_pwrite_stream &OS)
Write profiling data to output stream.
TimeTraceProfilerEntry * timeTraceProfilerBegin(StringRef Name, StringRef Detail)
Manually begin a time section, with the given Name and Detail.
Implement std::hash so that hash_code can be used in STL containers.
std::vector< TimeTraceProfilerEntry > InstantEvents
InProgressEntry(TimePointType S, TimePointType E, std::string N, TimeTraceMetadata Mt, TimeTraceEventType Et)
TimeTraceProfilerEntry Event
InProgressEntry(TimePointType S, TimePointType E, std::string N, std::string Dt, TimeTraceEventType Et)
Represents an open or completed time section entry to be captured.
const TimePointType Start
TimeTraceProfilerEntry(TimePointType &&S, TimePointType &&E, std::string &&N, std::string &&Dt, TimeTraceEventType Et)
ClockType::rep getFlameGraphDurUs() const
TimeTraceProfilerEntry(TimePointType &&S, TimePointType &&E, std::string &&N, TimeTraceMetadata &&Mt, TimeTraceEventType Et)
const TimeTraceEventType EventType
ClockType::rep getFlameGraphStartUs(TimePointType StartTime) const
TimeTraceMetadata Metadata
const sys::Process::Pid Pid
void write(raw_pwrite_stream &OS)
StringMap< CountAndDurationType > CountAndTotalPerName
const unsigned TimeTraceGranularity
void insert(std::string Name, llvm::function_ref< std::string()> Detail)
TimeTraceProfilerEntry * begin(std::string Name, llvm::function_ref< TimeTraceMetadata()> Metadata, TimeTraceEventType EventType=TimeTraceEventType::CompleteEvent)
const time_point< system_clock > BeginningOfTime
SmallVector< std::unique_ptr< InProgressEntry >, 16 > Stack
TimeTraceProfiler(unsigned TimeTraceGranularity=0, StringRef ProcName="", bool TimeTraceVerbose=false)
SmallString< 0 > ThreadName
const std::string ProcName
TimeTraceProfilerEntry * begin(std::string Name, llvm::function_ref< std::string()> Detail, TimeTraceEventType EventType=TimeTraceEventType::CompleteEvent)
SmallVector< TimeTraceProfilerEntry, 128 > Entries
const bool TimeTraceVerbose
const TimePointType StartTime
void end(TimeTraceProfilerEntry &E)