19#include "llvm/Config/config.h"
36#ifdef HAVE_PROC_PID_RUSAGE
69 return std::make_unique<raw_fd_ostream>(2,
false);
71 return std::make_unique<raw_fd_ostream>(1,
false);
78 auto Result = std::make_unique<raw_fd_ostream>(
83 errs() <<
"Error opening info-output-file '"
85 return std::make_unique<raw_fd_ostream>(2,
false);
98 assert(!TG &&
"Timer already initialized");
100 Description.assign(TimerDescription.
begin(), TimerDescription.
end());
101 Running = Triggered =
false;
108 TG->removeTimer(*
this);
118#if defined(HAVE_UNISTD_H) && defined(HAVE_PROC_PID_RUSAGE) && \
119 defined(RUSAGE_INFO_V4)
120 struct rusage_info_v4 ru;
121 if (proc_pid_rusage(getpid(), RUSAGE_INFO_V4, (rusage_info_t *)&ru) == 0) {
122 return ru.ri_instructions;
129 using Seconds = std::chrono::duration<double, std::ratio<1>>;
132 std::chrono::nanoseconds user, sys;
144 Result.WallTime = Seconds(
now.time_since_epoch()).count();
145 Result.UserTime = Seconds(user).count();
146 Result.SystemTime = Seconds(sys).count();
151 assert(!Running &&
"Cannot start a running timer");
152 Running = Triggered =
true;
153#if LLVM_SUPPORT_XCODE_SIGNPOSTS
160 assert(Running &&
"Cannot stop a paused timer");
164#if LLVM_SUPPORT_XCODE_SIGNPOSTS
170 Running = Triggered =
false;
187 if (
Total.getUserTime())
189 if (
Total.getSystemTime())
191 if (
Total.getProcessTime())
197 if (
Total.getMemUsed())
199 if (
Total.getInstructionsExecuted())
216 for (
StringMap<std::pair<TimerGroup*, Name2TimerMap> >::iterator
217 I = Map.begin(),
E = Map.end();
I !=
E; ++
I)
218 delete I->second.first;
225 std::pair<TimerGroup*, Name2TimerMap> &GroupEntry = Map[GroupName];
227 if (!GroupEntry.first)
228 GroupEntry.first =
new TimerGroup(GroupName, GroupDescription);
231 if (!
T.isInitialized())
232 T.init(
Name, Description, *GroupEntry.first);
245 GroupDescription)) {}
258 Description(Description.begin(), Description.end()) {
274 TimersToPrint.reserve(Records.size());
275 for (
const auto &
P : Records)
276 TimersToPrint.emplace_back(
P.getValue(), std::string(
P.getKey()),
277 std::string(
P.getKey()));
278 assert(TimersToPrint.size() == Records.size() &&
"Size mismatch");
285 removeTimer(*FirstTimer);
295void TimerGroup::removeTimer(
Timer &
T) {
299 if (
T.hasTriggered())
300 TimersToPrint.emplace_back(
T.Time,
T.Name,
T.Description);
307 T.Next->Prev =
T.Prev;
311 if (FirstTimer || TimersToPrint.empty())
315 PrintQueuedTimers(*OutStream);
318void TimerGroup::addTimer(
Timer &
T) {
323 FirstTimer->Prev = &
T.Next;
325 T.Prev = &FirstTimer;
335 for (
const PrintRecord &
Record : TimersToPrint)
339 OS <<
"===" << std::string(73,
'-') <<
"===\n";
341 unsigned Padding = (80-Description.length())/2;
343 OS.
indent(Padding) << Description <<
'\n';
344 OS <<
"===" << std::string(73,
'-') <<
"===\n";
350 OS <<
format(
" Total Execution Time: %5.4f seconds (%5.4f wall clock)\n",
354 if (
Total.getUserTime())
355 OS <<
" ---User Time---";
356 if (
Total.getSystemTime())
357 OS <<
" --System Time--";
358 if (
Total.getProcessTime())
359 OS <<
" --User+System--";
360 OS <<
" ---Wall Time---";
361 if (
Total.getMemUsed())
363 if (
Total.getInstructionsExecuted())
364 OS <<
" ---Instr---";
365 OS <<
" --- Name ---\n";
377 TimersToPrint.clear();
380void TimerGroup::prepareToPrintList(
bool ResetTime) {
382 for (
Timer *
T = FirstTimer;
T;
T =
T->Next) {
383 if (!
T->hasTriggered())
continue;
384 bool WasRunning =
T->isRunning();
388 TimersToPrint.emplace_back(
T->Time,
T->Name,
T->Description);
402 prepareToPrintList(ResetAfterPrint);
406 if (!TimersToPrint.empty())
407 PrintQueuedTimers(
OS);
412 for (
Timer *
T = FirstTimer;
T;
T =
T->Next)
429void TimerGroup::printJSONValue(
raw_ostream &
OS,
const PrintRecord &R,
430 const char *suffix,
double Value) {
431 assert(yaml::needsQuotes(Name) == yaml::QuotingType::None &&
432 "TimerGroup name should not need quotes");
433 assert(yaml::needsQuotes(R.Name) == yaml::QuotingType::None &&
434 "Timer name should not need quotes");
435 constexpr auto max_digits10 = std::numeric_limits<double>::max_digits10;
436 OS <<
"\t\"time." << Name <<
'.' << R.Name << suffix
437 <<
"\": " <<
format(
"%.*e", max_digits10 - 1,
Value);
443 prepareToPrintList(
false);
444 for (
const PrintRecord &R : TimersToPrint) {
449 printJSONValue(
OS, R,
".wall",
T.getWallTime());
451 printJSONValue(
OS, R,
".user",
T.getUserTime());
453 printJSONValue(
OS, R,
".sys",
T.getSystemTime());
454 if (
T.getMemUsed()) {
456 printJSONValue(
OS, R,
".mem",
T.getMemUsed());
458 if (
T.getInstructionsExecuted()) {
460 printJSONValue(
OS, R,
".instr",
T.getInstructionsExecuted());
463 TimersToPrint.clear();
470 delim = TG->printJSONValues(
OS, delim);
501 cl::desc(
"Enable -time-passes memory tracking (this may be slow)"),
505 cl::desc(
"In the report, sort the timers in each group in wall clock"
This file defines the StringMap class.
static sys::TimePoint< std::chrono::seconds > now(bool Deterministic)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static cl::opt< std::string > OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"), cl::init("-"))
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 'Statistic' class, which is designed to be an easy way to expose various metric...
static sys::SmartMutex< true > & timerLock()
static ManagedStatic< TimerGlobals > ManagedTimerGlobals
static TimerGroup & defaultTimerGroup()
static std::string & libSupportInfoOutputFilename()
static SignpostEmitter & signposts()
static size_t getMemUsage()
static void printVal(double Val, double Total, raw_ostream &OS)
static TimerGroup * TimerGroupList
This is the global list of TimerGroups, maintained by the TimerGroup ctor/dtor and is protected by th...
static uint64_t getCurInstructionsExecuted()
static Name2PairMap & namedGroupedTimers()
ManagedStatic - This transparently changes the behavior of global statics to be lazily constructed on...
Manages the emission of signposts into the recording method supported by the OS.
void endInterval(const void *O, StringRef Name)
End a signposted interval for a given object.
void startInterval(const void *O, StringRef Name)
Begin a signposted interval for a given object.
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.
double getUserTime() const
double getProcessTime() const
static TimeRecord getCurrentTime(bool Start=true)
Get the current time and memory usage.
double getWallTime() const
ssize_t getMemUsed() const
double getSystemTime() const
void print(const TimeRecord &Total, raw_ostream &OS) const
Print the current time record to OS, with a breakdown showing contributions to the Total time record.
uint64_t getInstructionsExecuted() const
The TimeRegion class is used as a helper class to call the startTimer() and stopTimer() methods of th...
cl::opt< std::string, true > InfoOutputFilename
cl::opt< bool > SortTimers
sys::SmartMutex< true > TimerLock
TimerGlobals & initDeferred()
std::string LibSupportInfoOutputFilename
TimerGroup DefaultTimerGroup
cl::opt< bool > TrackSpace
std::once_flag InitDeferredFlag
SignpostEmitter Signposts
std::optional< Name2PairMap > NamedGroupedTimersPtr
The TimerGroup class is used to group together related timers into a single report that is printed wh...
static void printAll(raw_ostream &OS)
This static method prints all timers.
void print(raw_ostream &OS, bool ResetAfterPrint=false)
Print any started timers in this group, optionally resetting timers after printing them.
static void clearAll()
Clear out all timers.
void clear()
Clear all timers in this group.
static void * acquireTimerGlobals()
This makes the timer globals unmanaged, and lets the user manage the lifetime.
static const char * printAllJSONValues(raw_ostream &OS, const char *delim)
Prints all timers as JSON key/value pairs.
const char * printJSONValues(raw_ostream &OS, const char *delim)
static void constructForStatistics()
Ensure global objects required for statistics printing are initialized.
This class is used to track the amount of time spent between invocations of its startTimer()/stopTime...
void yieldTo(Timer &)
Stop the timer and start another timer.
void stopTimer()
Stop the timer.
void init(StringRef TimerName, StringRef TimerDescription)
void clear()
Clear the timer state.
const std::string & getName() const
void startTimer()
Start the timer running.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
static void GetTimeUsage(TimePoint<> &elapsed, std::chrono::nanoseconds &user_time, std::chrono::nanoseconds &sys_time)
This static function will set user_time to the amount of CPU time spent in user (non-kernel) mode and...
static size_t GetMallocUsage()
Return process memory usage.
SmartMutex - A mutex with a compile time constant parameter that indicates whether this mutex should ...
initializer< Ty > init(const Ty &Val)
LocationClass< Ty > location(Ty &L)
@ OF_TextWithCRLF
The file should be opened in text mode and use a carriage linefeed '\r '.
@ OF_Append
The file should be opened in append mode.
std::chrono::time_point< std::chrono::system_clock, D > TimePoint
A time point on the system clock.
std::lock_guard< SmartMutex< mt_only > > SmartScopedLock
This is an optimization pass for GlobalISel generic memory operations.
std::unique_ptr< raw_ostream > CreateInfoOutputFile()
Return a stream to print our output on.
auto reverse(ContainerTy &&C)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void sort(IteratorTy Start, IteratorTy End)
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
NamedRegionTimer(StringRef Name, StringRef Description, StringRef GroupName, StringRef GroupDescription, bool Enabled=true)