19#include "llvm/Config/config.h"
35#ifdef HAVE_PROC_PID_RUSAGE
68 return std::make_unique<raw_fd_ostream>(2,
false);
70 return std::make_unique<raw_fd_ostream>(1,
false);
77 auto Result = std::make_unique<raw_fd_ostream>(
82 errs() <<
"Error opening info-output-file '"
84 return std::make_unique<raw_fd_ostream>(2,
false);
97 assert(!TG &&
"Timer already initialized");
99 Description.assign(TimerDescription.
begin(), TimerDescription.
end());
100 Running = Triggered =
false;
107 TG->removeTimer(*
this);
117#if defined(HAVE_UNISTD_H) && defined(HAVE_PROC_PID_RUSAGE) && \
118 defined(RUSAGE_INFO_V4)
119 struct rusage_info_v4 ru;
120 if (proc_pid_rusage(getpid(), RUSAGE_INFO_V4, (rusage_info_t *)&ru) == 0) {
121 return ru.ri_instructions;
128 using Seconds = std::chrono::duration<double, std::ratio<1>>;
131 std::chrono::nanoseconds user, sys;
143 Result.WallTime = Seconds(
now.time_since_epoch()).count();
144 Result.UserTime = Seconds(user).count();
145 Result.SystemTime = Seconds(sys).count();
150 assert(!Running &&
"Cannot start a running timer");
151 Running = Triggered =
true;
152#if LLVM_SUPPORT_XCODE_SIGNPOSTS
159 assert(Running &&
"Cannot stop a paused timer");
163#if LLVM_SUPPORT_XCODE_SIGNPOSTS
169 Running = Triggered =
false;
186 if (
Total.getUserTime())
188 if (
Total.getSystemTime())
190 if (
Total.getProcessTime())
196 if (
Total.getMemUsed())
198 if (
Total.getInstructionsExecuted())
215 for (
StringMap<std::pair<TimerGroup*, Name2TimerMap> >::iterator
216 I = Map.begin(),
E = Map.end();
I !=
E; ++
I)
217 delete I->second.first;
224 std::pair<TimerGroup *, Name2TimerMap> &GroupEntry =
225 getGroupEntry(GroupName, GroupDescription);
227 if (!
T.isInitialized())
228 T.init(
Name, Description, *GroupEntry.first);
234 return *getGroupEntry(GroupName, GroupDescription).first;
238 std::pair<TimerGroup *, Name2TimerMap> &
240 std::pair<TimerGroup *, Name2TimerMap> &GroupEntry =
Map[GroupName];
241 if (!GroupEntry.first)
242 GroupEntry.first =
new TimerGroup(GroupName, GroupDescription);
256 GroupDescription)) {}
274 Description(Description.begin(), Description.end()) {
290 TimersToPrint.reserve(Records.size());
291 for (
const auto &
P : Records)
292 TimersToPrint.emplace_back(
P.getValue(), std::string(
P.getKey()),
293 std::string(
P.getKey()));
294 assert(TimersToPrint.size() == Records.size() &&
"Size mismatch");
301 removeTimer(*FirstTimer);
303 if (!TimersToPrint.empty()) {
305 PrintQueuedTimers(*OutStream);
316void TimerGroup::removeTimer(
Timer &
T) {
320 if (
T.hasTriggered())
321 TimersToPrint.emplace_back(
T.Time,
T.Name,
T.Description);
328 T.Next->Prev =
T.Prev;
331void TimerGroup::addTimer(
Timer &
T) {
336 FirstTimer->Prev = &
T.Next;
338 T.Prev = &FirstTimer;
348 for (
const PrintRecord &
Record : TimersToPrint)
352 OS <<
"===" << std::string(73,
'-') <<
"===\n";
354 unsigned Padding = (80-Description.length())/2;
356 OS.
indent(Padding) << Description <<
'\n';
357 OS <<
"===" << std::string(73,
'-') <<
"===\n";
363 OS <<
format(
" Total Execution Time: %5.4f seconds (%5.4f wall clock)\n",
367 if (
Total.getUserTime())
368 OS <<
" ---User Time---";
369 if (
Total.getSystemTime())
370 OS <<
" --System Time--";
371 if (
Total.getProcessTime())
372 OS <<
" --User+System--";
373 OS <<
" ---Wall Time---";
374 if (
Total.getMemUsed())
376 if (
Total.getInstructionsExecuted())
377 OS <<
" ---Instr---";
378 OS <<
" --- Name ---\n";
390 TimersToPrint.clear();
393void TimerGroup::prepareToPrintList(
bool ResetTime) {
395 for (
Timer *
T = FirstTimer;
T;
T =
T->Next) {
396 if (!
T->hasTriggered())
continue;
397 bool WasRunning =
T->isRunning();
401 TimersToPrint.emplace_back(
T->Time,
T->Name,
T->Description);
415 prepareToPrintList(ResetAfterPrint);
419 if (!TimersToPrint.empty())
420 PrintQueuedTimers(
OS);
425 for (
Timer *
T = FirstTimer;
T;
T =
T->Next)
442void TimerGroup::printJSONValue(
raw_ostream &
OS,
const PrintRecord &R,
443 const char *suffix,
double Value) {
444 constexpr auto max_digits10 = std::numeric_limits<double>::max_digits10;
445 OS <<
"\t\"time." << Name <<
'.' << R.Name << suffix
446 <<
"\": " <<
format(
"%.*e", max_digits10 - 1,
Value);
452 prepareToPrintList(
false);
453 for (
const PrintRecord &R : TimersToPrint) {
458 printJSONValue(
OS, R,
".wall",
T.getWallTime());
460 printJSONValue(
OS, R,
".user",
T.getUserTime());
462 printJSONValue(
OS, R,
".sys",
T.getSystemTime());
463 if (
T.getMemUsed()) {
465 printJSONValue(
OS, R,
".mem",
T.getMemUsed());
467 if (
T.getInstructionsExecuted()) {
469 printJSONValue(
OS, R,
".instr",
T.getInstructionsExecuted());
472 TimersToPrint.clear();
479 delim = TG->printJSONValues(
OS, delim);
510 cl::desc(
"Enable -time-passes memory tracking (this may be slow)"),
514 cl::desc(
"In the report, sort the timers in each group in wall clock"
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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 ...
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.
LLVM_ABI void endInterval(const void *O, StringRef Name)
End a signposted interval for a given object.
LLVM_ABI 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 LLVM_ABI TimeRecord getCurrentTime(bool Start=true)
Get the current time and memory usage.
double getWallTime() const
ssize_t getMemUsed() const
double getSystemTime() const
LLVM_ABI 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 LLVM_ABI void printAll(raw_ostream &OS)
This static method prints all timers.
LLVM_ABI void print(raw_ostream &OS, bool ResetAfterPrint=false)
Print any started timers in this group, optionally resetting timers after printing them.
static LLVM_ABI void clearAll()
Clear out all timers.
LLVM_ABI void clear()
Clear all timers in this group.
static LLVM_ABI void * acquireTimerGlobals()
This makes the timer globals unmanaged, and lets the user manage the lifetime.
static LLVM_ABI const char * printAllJSONValues(raw_ostream &OS, const char *delim)
Prints all timers as JSON key/value pairs.
LLVM_ABI const char * printJSONValues(raw_ostream &OS, const char *delim)
static LLVM_ABI 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...
LLVM_ABI void yieldTo(Timer &)
Stop the timer and start another timer.
LLVM_ABI void stopTimer()
Stop the timer.
LLVM_ABI void init(StringRef TimerName, StringRef TimerDescription)
LLVM_ABI void clear()
Clear the timer state.
const std::string & getName() const
LLVM_ABI 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 LLVM_ABI 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 LLVM_ABI 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.
LLVM_ABI 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.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
LLVM_ABI NamedRegionTimer(StringRef Name, StringRef Description, StringRef GroupName, StringRef GroupDescription, bool Enabled=true)
static LLVM_ABI TimerGroup & getNamedTimerGroup(StringRef GroupName, StringRef GroupDescription)