31using std::chrono::duration;
32using std::chrono::duration_cast;
33using std::chrono::microseconds;
34using std::chrono::steady_clock;
35using std::chrono::system_clock;
36using std::chrono::time_point;
37using std::chrono::time_point_cast;
39struct TimeTraceProfilerInstances {
41 std::vector<TimeTraceProfiler *>
List;
44TimeTraceProfilerInstances &getTimeTraceProfilerInstances() {
45 static TimeTraceProfilerInstances Instances;
60using ClockType = steady_clock;
61using TimePointType = time_point<ClockType>;
62using DurationType = duration<ClockType::rep, ClockType::period>;
63using CountAndDurationType = std::pair<size_t, DurationType>;
64using NameAndCountAndDurationType =
65 std::pair<std::string, CountAndDurationType>;
68struct TimeTraceProfilerEntry {
69 const TimePointType Start;
71 const std::string Name;
72 const std::string Detail;
74 TimeTraceProfilerEntry(TimePointType &&S, TimePointType &&
E, std::string &&
N,
82 ClockType::rep getFlameGraphStartUs(TimePointType StartTime)
const {
83 return (time_point_cast<microseconds>(Start) -
84 time_point_cast<microseconds>(StartTime))
88 ClockType::rep getFlameGraphDurUs()
const {
89 return (time_point_cast<microseconds>(End) -
90 time_point_cast<microseconds>(Start))
113 E.End = ClockType::now();
117 (
E.getFlameGraphStartUs(
StartTime) +
E.getFlameGraphDurUs() >=
120 "TimeProfiler scope ended earlier than previous scope");
135 [&](
const TimeTraceProfilerEntry &Val) {
136 return Val.Name ==
E.Name;
139 CountAndTotal.first++;
150 auto &Instances = getTimeTraceProfilerInstances();
151 std::lock_guard<std::mutex> Lock(Instances.Lock);
153 "All profiler sections should be ended when calling write");
155 [](
const auto &TTP) { return TTP->Stack.empty(); }) &&
156 "All profiler sections should be ended when calling write");
165 auto StartUs =
E.getFlameGraphStartUs(
StartTime);
166 auto DurUs =
E.getFlameGraphDurUs();
175 if (!
E.Detail.empty()) {
180 for (
const TimeTraceProfilerEntry &
E :
Entries)
181 writeEvent(
E, this->
Tid);
183 for (
const TimeTraceProfilerEntry &
E : TTP->
Entries)
184 writeEvent(
E, TTP->
Tid);
191 MaxTid = std::max(MaxTid, TTP->
Tid);
195 auto combineStat = [&](
const auto &Stat) {
197 auto Value = Stat.getValue();
198 auto &CountAndTotal = AllCountAndTotalPerName[Key];
199 CountAndTotal.first +=
Value.first;
200 CountAndTotal.second +=
Value.second;
208 std::vector<NameAndCountAndDurationType> SortedTotals;
209 SortedTotals.reserve(AllCountAndTotalPerName.
size());
210 for (
const auto &
Total : AllCountAndTotalPerName)
211 SortedTotals.emplace_back(std::string(
Total.getKey()),
Total.getValue());
213 llvm::sort(SortedTotals, [](
const NameAndCountAndDurationType &
A,
214 const NameAndCountAndDurationType &
B) {
215 return A.second.second >
B.second.second;
220 for (
const NameAndCountAndDurationType &
Total : SortedTotals) {
221 auto DurUs = duration_cast<microseconds>(
Total.second.second).count();
222 auto Count = AllCountAndTotalPerName[
Total.first].first;
232 J.attribute(
"count", int64_t(Count));
233 J.attribute(
"avg ms", int64_t(DurUs / Count / 1000));
256 writeMetadataEvent(
"thread_name", TTP->
Tid, TTP->
ThreadName);
291 "Profiler should not be initialized");
302 auto &Instances = getTimeTraceProfilerInstances();
303 std::lock_guard<std::mutex> Lock(Instances.Lock);
304 for (
auto *TTP : Instances.List)
306 Instances.List.clear();
312 auto &Instances = getTimeTraceProfilerInstances();
313 std::lock_guard<std::mutex> Lock(Instances.Lock);
320 "Profiler object can't be null");
327 "Profiler object can't be null");
329 std::string Path = PreferredFileName.
str();
331 Path = FallbackFileName ==
"-" ?
"out" : FallbackFileName.
str();
332 Path +=
".time-trace";
347 [&]() {
return std::string(Detail); });
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")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#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...
reference emplace_back(ArgTypes &&... Args)
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 timeTraceProfilerBegin(StringRef Name, StringRef Detail)
Manually begin a time section, with the given Name and Detail.
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.
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 timeTraceProfilerWrite(raw_pwrite_stream &OS)
Write profiling data to output stream.
SmallVector< TimeTraceProfilerEntry, 16 > Stack
const sys::Process::Pid Pid
void write(raw_pwrite_stream &OS)
StringMap< CountAndDurationType > CountAndTotalPerName
const unsigned TimeTraceGranularity
TimeTraceProfiler(unsigned TimeTraceGranularity=0, StringRef ProcName="")
const time_point< system_clock > BeginningOfTime
SmallString< 0 > ThreadName
const std::string ProcName
SmallVector< TimeTraceProfilerEntry, 128 > Entries
const TimePointType StartTime
void begin(std::string Name, llvm::function_ref< std::string()> Detail)