33using std::chrono::duration;
34using std::chrono::duration_cast;
35using std::chrono::microseconds;
36using std::chrono::steady_clock;
38using std::chrono::time_point;
39using std::chrono::time_point_cast;
41struct TimeTraceProfilerInstances {
43 std::vector<TimeTraceProfiler *>
List;
46TimeTraceProfilerInstances &getTimeTraceProfilerInstances() {
47 static TimeTraceProfilerInstances Instances;
62using ClockType = steady_clock;
63using TimePointType = time_point<ClockType>;
64using DurationType = duration<ClockType::rep, ClockType::period>;
65using CountAndDurationType = std::pair<size_t, DurationType>;
66using NameAndCountAndDurationType =
67 std::pair<std::string, CountAndDurationType>;
79 std::string &&Dt,
bool Ae)
87 return (time_point_cast<microseconds>(
Start) -
88 time_point_cast<microseconds>(StartTime))
93 return (time_point_cast<microseconds>(
End) -
94 time_point_cast<microseconds>(
Start))
109 bool AsyncEvent =
false) {
110 Stack.emplace_back(std::make_unique<TimeTraceProfilerEntry>(
111 ClockType::now(), TimePointType(), std::move(
Name), Detail(),
113 return Stack.back().get();
117 assert(!
Stack.empty() &&
"Must call begin() first");
122 assert(!
Stack.empty() &&
"Must call begin() first");
123 E.
End = ClockType::now();
138 [&](
const std::unique_ptr<TimeTraceProfilerEntry> &Val) {
139 return Val->Name == E.
Name;
142 CountAndTotal.first++;
147 [&](
const std::unique_ptr<TimeTraceProfilerEntry> &Val) {
148 return Val.get() == &E;
156 auto &Instances = getTimeTraceProfilerInstances();
157 std::lock_guard<std::mutex> Lock(Instances.Lock);
159 "All profiler sections should be ended when calling write");
161 [](
const auto &TTP) { return TTP->Stack.empty(); }) &&
162 "All profiler sections should be ended when calling write");
170 auto writeEvent = [&](
const auto &E,
uint64_t Tid) {
171 auto StartUs = E.getFlameGraphStartUs(
StartTime);
172 auto DurUs = E.getFlameGraphDurUs();
187 if (!E.Detail.empty()) {
205 writeEvent(E, this->
Tid);
208 writeEvent(E, TTP->
Tid);
215 MaxTid = std::max(MaxTid, TTP->
Tid);
219 auto combineStat = [&](
const auto &Stat) {
221 auto Value = Stat.getValue();
222 auto &CountAndTotal = AllCountAndTotalPerName[Key];
223 CountAndTotal.first +=
Value.first;
224 CountAndTotal.second +=
Value.second;
232 std::vector<NameAndCountAndDurationType> SortedTotals;
233 SortedTotals.reserve(AllCountAndTotalPerName.
size());
234 for (
const auto &
Total : AllCountAndTotalPerName)
235 SortedTotals.emplace_back(std::string(
Total.getKey()),
Total.getValue());
237 llvm::sort(SortedTotals, [](
const NameAndCountAndDurationType &
A,
238 const NameAndCountAndDurationType &
B) {
239 return A.second.second >
B.second.second;
244 for (
const NameAndCountAndDurationType &
Total : SortedTotals) {
245 auto DurUs = duration_cast<microseconds>(
Total.second.second).count();
246 auto Count = AllCountAndTotalPerName[
Total.first].first;
256 J.attribute(
"count", int64_t(Count));
257 J.attribute(
"avg ms", int64_t(DurUs / Count / 1000));
280 writeMetadataEvent(
"thread_name", TTP->
Tid, TTP->
ThreadName);
315 "Profiler should not be initialized");
326 auto &Instances = getTimeTraceProfilerInstances();
327 std::lock_guard<std::mutex> Lock(Instances.Lock);
328 for (
auto *TTP : Instances.List)
330 Instances.List.clear();
336 auto &Instances = getTimeTraceProfilerInstances();
337 std::lock_guard<std::mutex> Lock(Instances.Lock);
344 "Profiler object can't be null");
351 "Profiler object can't be null");
353 std::string Path = PreferredFileName.
str();
355 Path = FallbackFileName ==
"-" ?
"out" : FallbackFileName.
str();
356 Path +=
".time-trace";
372 std::string(
Name), [&]() {
return std::string(Detail); },
false);
388 std::string(
Name), [&]() {
return std::string(Detail); },
true);
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())
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...
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.
void timeTraceProfilerInitialize(unsigned TimeTraceGranularity, StringRef ProcName)
Initialize the time trace profiler.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
TimeTraceProfiler * getTimeTraceProfilerInstance()
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 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.
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.
void timeTraceProfilerCleanup()
Cleanup the time trace profiler, if it was initialized.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
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.
Represents an open or completed time section entry to be captured.
const TimePointType Start
ClockType::rep getFlameGraphDurUs() const
TimeTraceProfilerEntry(TimePointType &&S, TimePointType &&E, std::string &&N, std::string &&Dt, bool Ae)
ClockType::rep getFlameGraphStartUs(TimePointType StartTime) const
const sys::Process::Pid Pid
void write(raw_pwrite_stream &OS)
StringMap< CountAndDurationType > CountAndTotalPerName
const unsigned TimeTraceGranularity
TimeTraceProfiler(unsigned TimeTraceGranularity=0, StringRef ProcName="")
TimeTraceProfilerEntry * begin(std::string Name, llvm::function_ref< std::string()> Detail, bool AsyncEvent=false)
const time_point< system_clock > BeginningOfTime
SmallVector< std::unique_ptr< TimeTraceProfilerEntry >, 16 > Stack
SmallString< 0 > ThreadName
const std::string ProcName
SmallVector< TimeTraceProfilerEntry, 128 > Entries
const TimePointType StartTime
void end(TimeTraceProfilerEntry &E)