Go to the documentation of this file.
28 using namespace std::chrono;
42 typedef duration<steady_clock::rep, steady_clock::period>
DurationType;
45 typedef std::pair<std::string, CountAndDurationType>
52 const std::string
Name;
53 const std::string Detail;
62 steady_clock::rep getFlameGraphStartUs(
TimePointType StartTime)
const {
63 return (time_point_cast<microseconds>(Start) -
64 time_point_cast<microseconds>(StartTime))
68 steady_clock::rep getFlameGraphDurUs()
const {
69 return (time_point_cast<microseconds>(End) -
70 time_point_cast<microseconds>(Start))
78 : BeginningOfTime(system_clock::
now()), StartTime(steady_clock::
now()),
79 ProcName(ProcName), Pid(sys::
Process::getProcessId()),
90 assert(!Stack.empty() &&
"Must call begin() first");
91 Entry &
E = Stack.back();
96 (
E.getFlameGraphStartUs(StartTime) +
E.getFlameGraphDurUs() >=
97 Entries.back().getFlameGraphStartUs(StartTime) +
98 Entries.back().getFlameGraphDurUs())) &&
99 "TimeProfiler scope ended earlier than previous scope");
105 if (duration_cast<microseconds>(
Duration).
count() >= TimeTraceGranularity)
106 Entries.emplace_back(
E);
114 [&](
const Entry &Val) {
return Val.Name ==
E.Name; })) {
115 auto &CountAndTotal = CountAndTotalPerName[
E.Name];
116 CountAndTotal.first++;
127 std::lock_guard<std::mutex>
Lock(
Mu);
129 "All profiler sections should be ended when calling write");
131 [](
const auto &TTP) {
return TTP->Stack.empty(); }) &&
132 "All profiler sections should be ended when calling write");
140 auto writeEvent = [&](
const auto &
E,
uint64_t Tid) {
141 auto StartUs =
E.getFlameGraphStartUs(StartTime);
142 auto DurUs =
E.getFlameGraphDurUs();
151 if (!
E.Detail.empty()) {
156 for (
const Entry &
E : Entries)
157 writeEvent(
E, this->Tid);
159 for (
const Entry &
E : TTP->Entries)
160 writeEvent(
E, TTP->Tid);
167 MaxTid =
std::max(MaxTid, TTP->Tid);
171 auto combineStat = [&](
const auto &Stat) {
173 auto Value = Stat.getValue();
174 auto &CountAndTotal = AllCountAndTotalPerName[
Key];
175 CountAndTotal.first +=
Value.first;
176 CountAndTotal.second +=
Value.second;
178 for (
const auto &Stat : CountAndTotalPerName)
181 for (
const auto &Stat : TTP->CountAndTotalPerName)
184 std::vector<NameAndCountAndDurationType> SortedTotals;
185 SortedTotals.reserve(AllCountAndTotalPerName.
size());
186 for (
const auto &Total : AllCountAndTotalPerName)
187 SortedTotals.emplace_back(std::string(Total.getKey()), Total.getValue());
191 return A.second.second >
B.second.second;
197 auto DurUs = duration_cast<microseconds>(Total.second.second).count();
198 auto Count = AllCountAndTotalPerName[Total.first].first;
206 J.
attribute(
"name",
"Total " + Total.first);
208 J.attribute(
"count", int64_t(Count));
209 J.attribute(
"avg ms", int64_t(DurUs / Count / 1000));
216 auto writeMetadataEvent = [&](
const char *
Name,
uint64_t Tid,
229 writeMetadataEvent(
"process_name", Tid, ProcName);
230 writeMetadataEvent(
"thread_name", Tid, ThreadName);
232 writeMetadataEvent(
"thread_name", TTP->Tid, TTP->ThreadName);
241 time_point_cast<microseconds>(BeginningOfTime)
265 "Profiler should not be initialized");
275 std::lock_guard<std::mutex>
Lock(
Mu);
284 std::lock_guard<std::mutex>
Lock(
Mu);
291 "Profiler object can't be null");
298 "Profiler object can't be null");
300 std::string Path = PreferredFileName.
str();
302 Path = FallbackFileName ==
"-" ?
"out" : FallbackFileName.
str();
303 Path +=
".time-trace";
312 return Error::success();
318 [&]() {
return std::string(Detail); });
void attributeBegin(llvm::StringRef Key)
This is an optimization pass for GlobalISel generic memory operations.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
static ManagedStatic< std::vector< TimeTraceProfiler * > > ThreadTimeTraceProfilerInstances
TimeTraceProfiler * getTimeTraceProfilerInstance()
void timeTraceProfilerWrite(raw_pwrite_stream &OS)
Write profiling data to output stream.
const unsigned TimeTraceGranularity
const TimePointType StartTime
void timeTraceProfilerCleanup()
Cleanup the time trace profiler, if it was initialized.
SmallString< 0 > ThreadName
StringMap< CountAndDurationType > CountAndTotalPerName
auto reverse(ContainerTy &&C, std::enable_if_t< has_rbegin< ContainerTy >::value > *=nullptr)
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
void timeTraceProfilerFinishThread()
Finish a time trace profiler running on a worker thread.
void timeTraceProfilerInitialize(unsigned TimeTraceGranularity, StringRef ProcName)
Initialize the time trace profiler.
A collection of legacy interfaces for querying information about the current executing process.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
#define LLVM_THREAD_LOCAL
\macro LLVM_THREAD_LOCAL A thread-local storage specifier which can be used with globals,...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void object(Block Contents)
Emit an object whose elements are emitted in the provided Block.
void timeTraceProfilerBegin(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.
const std::string ProcName
ManagedStatic - This transparently changes the behavior of global statics to be lazily constructed on...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
void get_thread_name(SmallVectorImpl< char > &Name)
Get the name of the current thread.
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
static sys::TimePoint< std::chrono::seconds > now(bool Deterministic)
@ OF_TextWithCRLF
The file should be opened in text mode and use a carriage linefeed '\r '.
An efficient, type-erasing, non-owning reference to a callable.
void begin(std::string Name, llvm::function_ref< std::string()> Detail)
json::OStream allows writing well-formed JSON without materializing all structures as json::Value ahe...
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...
An abstract base class for streams implementations that also support a pwrite operation.
const time_point< system_clock > BeginningOfTime
void write(raw_pwrite_stream &OS)
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
SmallVector< Entry, 128 > Entries
SmallVector< Entry, 16 > Stack
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::pair< size_t, DurationType > CountAndDurationType
time_point< steady_clock > TimePointType
StringRef - Represent a constant reference to a string, i.e.
duration< steady_clock::rep, steady_clock::period > DurationType
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
A raw_ostream that writes to a file descriptor.
TimeTraceProfiler(unsigned TimeTraceGranularity=0, StringRef ProcName="")
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Lightweight error class with error context and mandatory checking.
void sort(IteratorTy Start, IteratorTy End)
StringRef filename(StringRef path, Style style=Style::native)
Get filename.
static LLVM_THREAD_LOCAL TimeTraceProfiler * TimeTraceProfilerInstance
void attributeObject(llvm::StringRef Key, Block Contents)
Emit an attribute whose value is an object with attributes from the Block.
void timeTraceProfilerEnd()
Manually end the last time section.
std::pair< std::string, CountAndDurationType > NameAndCountAndDurationType
void attribute(llvm::StringRef Key, const Value &Contents)
Emit an attribute whose value is self-contained (number, vector<int> etc).
const sys::Process::Pid Pid
LLVM Value Representation.