19#include "llvm/Config/config.h"
35#ifdef HAVE_PROC_PID_RUSAGE
59struct CreateTrackSpace {
62 cl::desc(
"Enable -time-passes memory "
63 "tracking (this may be slow)"),
68struct CreateInfoOutputFilename {
78struct CreateSortTimers {
82 cl::desc(
"In the report, sort the timers in each group "
83 "in wall clock time order"),
99 return std::make_unique<raw_fd_ostream>(2,
false);
101 return std::make_unique<raw_fd_ostream>(1,
false);
108 auto Result = std::make_unique<raw_fd_ostream>(
113 errs() <<
"Error opening info-output-file '"
115 return std::make_unique<raw_fd_ostream>(2,
false);
119struct CreateDefaultTimerGroup {
120 static void *call() {
121 return new TimerGroup(
"misc",
"Miscellaneous Ungrouped Timers");
138 assert(!TG &&
"Timer already initialized");
139 Name.assign(TimerName.
begin(), TimerName.
end());
140 Description.assign(TimerDescription.
begin(), TimerDescription.
end());
141 Running = Triggered =
false;
148 TG->removeTimer(*
this);
158#if defined(HAVE_UNISTD_H) && defined(HAVE_PROC_PID_RUSAGE) && \
159 defined(RUSAGE_INFO_V4)
160 struct rusage_info_v4 ru;
161 if (proc_pid_rusage(getpid(), RUSAGE_INFO_V4, (rusage_info_t *)&ru) == 0) {
162 return ru.ri_instructions;
169 using Seconds = std::chrono::duration<double, std::ratio<1>>;
172 std::chrono::nanoseconds user, sys;
184 Result.WallTime = Seconds(
now.time_since_epoch()).count();
185 Result.UserTime = Seconds(user).count();
186 Result.SystemTime = Seconds(sys).count();
191 assert(!Running &&
"Cannot start a running timer");
192 Running = Triggered =
true;
198 assert(Running &&
"Cannot stop a paused timer");
206 Running = Triggered =
false;
218 if (
Total.getUserTime())
220 if (
Total.getSystemTime())
222 if (
Total.getProcessTime())
228 if (
Total.getMemUsed())
230 if (
Total.getInstructionsExecuted())
247 for (
StringMap<std::pair<TimerGroup*, Name2TimerMap> >::iterator
248 I = Map.begin(),
E = Map.end();
I !=
E; ++
I)
249 delete I->second.first;
256 std::pair<TimerGroup*, Name2TimerMap> &GroupEntry = Map[GroupName];
258 if (!GroupEntry.first)
259 GroupEntry.first =
new TimerGroup(GroupName, GroupDescription);
262 if (!
T.isInitialized())
263 T.init(
Name, Description, *GroupEntry.first);
277 GroupDescription)) {}
289 Description(Description.begin(), Description.end()) {
302 TimersToPrint.reserve(Records.size());
303 for (
const auto &
P : Records)
304 TimersToPrint.emplace_back(
P.getValue(), std::string(
P.getKey()),
305 std::string(
P.getKey()));
306 assert(TimersToPrint.size() == Records.size() &&
"Size mismatch");
313 removeTimer(*FirstTimer);
323void TimerGroup::removeTimer(
Timer &
T) {
327 if (
T.hasTriggered())
328 TimersToPrint.emplace_back(
T.Time,
T.Name,
T.Description);
335 T.Next->Prev =
T.Prev;
339 if (FirstTimer || TimersToPrint.empty())
343 PrintQueuedTimers(*OutStream);
346void TimerGroup::addTimer(
Timer &
T) {
351 FirstTimer->Prev = &
T.Next;
353 T.Prev = &FirstTimer;
363 for (
const PrintRecord &
Record : TimersToPrint)
367 OS <<
"===" << std::string(73,
'-') <<
"===\n";
369 unsigned Padding = (80-Description.length())/2;
371 OS.
indent(Padding) << Description <<
'\n';
372 OS <<
"===" << std::string(73,
'-') <<
"===\n";
378 OS <<
format(
" Total Execution Time: %5.4f seconds (%5.4f wall clock)\n",
382 if (
Total.getUserTime())
383 OS <<
" ---User Time---";
384 if (
Total.getSystemTime())
385 OS <<
" --System Time--";
386 if (
Total.getProcessTime())
387 OS <<
" --User+System--";
388 OS <<
" ---Wall Time---";
389 if (
Total.getMemUsed())
391 if (
Total.getInstructionsExecuted())
392 OS <<
" ---Instr---";
393 OS <<
" --- Name ---\n";
405 TimersToPrint.clear();
408void TimerGroup::prepareToPrintList(
bool ResetTime) {
410 for (
Timer *
T = FirstTimer;
T;
T =
T->Next) {
411 if (!
T->hasTriggered())
continue;
412 bool WasRunning =
T->isRunning();
416 TimersToPrint.emplace_back(
T->Time,
T->Name,
T->Description);
430 prepareToPrintList(ResetAfterPrint);
434 if (!TimersToPrint.empty())
435 PrintQueuedTimers(
OS);
440 for (
Timer *
T = FirstTimer;
T;
T =
T->Next)
457void TimerGroup::printJSONValue(
raw_ostream &
OS,
const PrintRecord &R,
458 const char *suffix,
double Value) {
459 assert(yaml::needsQuotes(Name) == yaml::QuotingType::None &&
460 "TimerGroup name should not need quotes");
461 assert(yaml::needsQuotes(R.Name) == yaml::QuotingType::None &&
462 "Timer name should not need quotes");
463 constexpr auto max_digits10 = std::numeric_limits<double>::max_digits10;
464 OS <<
"\t\"time." << Name <<
'.' << R.Name << suffix
465 <<
"\": " <<
format(
"%.*e", max_digits10 - 1,
Value);
471 prepareToPrintList(
false);
472 for (
const PrintRecord &R : TimersToPrint) {
477 printJSONValue(
OS, R,
".wall",
T.getWallTime());
479 printJSONValue(
OS, R,
".user",
T.getUserTime());
481 printJSONValue(
OS, R,
".sys",
T.getSystemTime());
482 if (
T.getMemUsed()) {
484 printJSONValue(
OS, R,
".mem",
T.getMemUsed());
486 if (
T.getInstructionsExecuted()) {
488 printJSONValue(
OS, R,
".instr",
T.getInstructionsExecuted());
491 TimersToPrint.clear();
498 delim = TG->printJSONValues(
OS, delim);
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 ManagedStatic< SignpostEmitter > Signposts
Allows llvm::Timer to emit signposts when supported.
static ManagedStatic< std::string > LibSupportInfoOutputFilename
static ManagedStatic< TimerGroup, CreateDefaultTimerGroup > DefaultTimerGroup
static size_t getMemUsage()
static void printVal(double Val, double Total, raw_ostream &OS)
static ManagedStatic< sys::SmartMutex< true > > TimerLock
static TimerGroup * TimerGroupList
This is the global list of TimerGroups, maintained by the TimerGroup ctor/dtor and is protected by th...
static TimerGroup * getDefaultTimerGroup()
static std::string & getLibSupportInfoOutputFilename()
static uint64_t getCurInstructionsExecuted()
static ManagedStatic< Name2PairMap > NamedGroupedTimers
ManagedStatic - This transparently changes the behavior of global statics to be lazily constructed on...
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...
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 std::unique_ptr< TimerGroup > aquireDefaultGroup()
This makes the default group unmanaged, and lets the user manage the group's 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 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.
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_fd_ostream > CreateInfoOutputFile()
Return a file 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)