Go to the documentation of this file.
19 #include "llvm/Config/config.h"
35 #ifdef HAVE_PROC_PID_RUSAGE
59 struct CreateTrackSpace {
62 cl::desc(
"Enable -time-passes memory "
63 "tracking (this may be slow)"),
68 struct CreateInfoOutputFilename {
78 struct 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);
119 struct 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;
214 OS <<
format(
" %7.4f (%5.1f%%)", Val, Val*100/Total);
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);
323 void 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);
346 void TimerGroup::addTimer(
Timer &T) {
351 FirstTimer->Prev = &
T.Next;
353 T.Prev = &FirstTimer;
357 void TimerGroup::PrintQueuedTimers(
raw_ostream &OS) {
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",
383 OS <<
" ---User Time---";
385 OS <<
" --System Time--";
387 OS <<
" --User+System--";
388 OS <<
" ---Wall Time---";
392 OS <<
" ---Instr---";
393 OS <<
" --- Name ---\n";
397 Record.Time.print(Total, OS);
398 OS <<
Record.Description <<
'\n';
401 Total.
print(Total, OS);
405 TimersToPrint.clear();
408 void 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)
457 void TimerGroup::printJSONValue(
raw_ostream &OS,
const PrintRecord &R,
458 const char *suffix,
double Value) {
460 "TimerGroup name should not need quotes");
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);
static ManagedStatic< SignpostEmitter > Signposts
Allows llvm::Timer to emit signposts when supported.
void clear()
Clear the timer state.
This is an optimization pass for GlobalISel generic memory operations.
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.
LocationClass< Ty > location(Ty &L)
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
void print(raw_ostream &OS, bool ResetAfterPrint=false)
Print any started timers in this group, optionally resetting timers after printing them.
void clear()
Clear all timers in this group.
static void printAll(raw_ostream &OS)
This static method prints all timers.
void init(StringRef TimerName, StringRef TimerDescription)
This class is used to track the amount of time spent between invocations of its startTimer()/stopTime...
auto reverse(ContainerTy &&C, std::enable_if_t< has_rbegin< ContainerTy >::value > *=nullptr)
const_iterator end(StringRef path)
Get end iterator over path.
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
static void printVal(double Val, double Total, raw_ostream &OS)
void startTimer()
Start the timer running.
std::unique_ptr< raw_fd_ostream > CreateInfoOutputFile()
Return a file stream to print our output on.
std::chrono::time_point< std::chrono::system_clock, D > TimePoint
A time point on the system clock.
static TimerGroup * TimerGroupList
This is the global list of TimerGroups, maintained by the TimerGroup ctor/dtor and is protected by th...
static TimeRecord getCurrentTime(bool Start=true)
Get the current time and memory usage.
static ManagedStatic< Name2PairMap > NamedGroupedTimers
The TimeRegion class is used as a helper class to call the startTimer() and stopTimer() methods of th...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
ManagedStatic - This transparently changes the behavior of global statics to be lazily constructed on...
This class implements an extremely fast bulk output stream that can only output to a stream.
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 uint64_t getCurInstructionsExecuted()
static sys::TimePoint< std::chrono::seconds > now(bool Deterministic)
static void clearAll()
Clear out all timers.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
@ OF_TextWithCRLF
The file should be opened in text mode and use a carriage linefeed '\r '.
static void ConstructTimerLists()
Ensure global timer group lists are initialized.
static ManagedStatic< TimerGroup, CreateDefaultTimerGroup > DefaultTimerGroup
const char * printJSONValues(raw_ostream &OS, const char *delim)
double getProcessTime() const
std::lock_guard< SmartMutex< mt_only > > SmartScopedLock
S is passed via registers r2 But gcc stores them to the and then reload them to and r3 before issuing the call(r0 contains the address of the format string)
initializer< Ty > init(const Ty &Val)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void stopTimer()
Stop the timer.
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.
double getWallTime() const
StringRef - Represent a constant reference to a string, i.e.
static ManagedStatic< std::string > LibSupportInfoOutputFilename
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
static ManagedStatic< sys::SmartMutex< true > > TimerLock
NamedRegionTimer(StringRef Name, StringRef Description, StringRef GroupName, StringRef GroupDescription, bool Enabled=true)
double getUserTime() const
ssize_t getMemUsed() const
The TimerGroup class is used to group together related timers into a single report that is printed wh...
Should compile to something r4 addze r3 instead we get
static size_t getMemUsage()
void sort(IteratorTy Start, IteratorTy End)
static TimerGroup * getDefaultTimerGroup()
static cl::opt< std::string > OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"), cl::init("-"))
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
@ OF_Append
The file should be opened in append mode.
const std::string & getName() const
static size_t GetMallocUsage()
Return process memory usage.
uint64_t getInstructionsExecuted() const
LLVM Value Representation.
static std::string & getLibSupportInfoOutputFilename()
double getSystemTime() const