19#include "llvm/Config/config.h"
35#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");
99 Name.assign(TimerName.
begin(), TimerName.
end());
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;
183 OS <<
format(
" %7.4f (%5.1f%%)", Val, Val*100/
Total);
187 if (
Total.getUserTime())
189 if (
Total.getSystemTime())
191 if (
Total.getProcessTime())
197 if (
Total.getMemUsed())
199 if (
Total.getInstructionsExecuted())
217 I = Map.begin(), E = Map.end();
I != E; ++
I)
218 delete I->second.first;
225 std::pair<TimerGroup *, Name2TimerMap> &GroupEntry =
226 getGroupEntry(GroupName, GroupDescription);
227 Timer &
T = GroupEntry.second[Name];
228 if (!
T.isInitialized())
229 T.init(Name, Description, *GroupEntry.first);
233 TimerGroup &getTimerGroup(StringRef GroupName, StringRef GroupDescription) {
235 return *getGroupEntry(GroupName, GroupDescription).first;
239 std::pair<TimerGroup *, Name2TimerMap> &
240 getGroupEntry(StringRef GroupName, StringRef GroupDescription) {
241 std::pair<TimerGroup *, Name2TimerMap> &GroupEntry =
Map[GroupName];
242 if (!GroupEntry.first)
243 GroupEntry.first =
new TimerGroup(GroupName, GroupDescription);
257 GroupDescription)) {}
274 : Name(Name.begin(), Name.end()),
275 Description(Description.begin(), Description.end()) {
286 : TimerGroup(Name, Description,
timerLock()) {}
290 : TimerGroup(Name, Description) {
291 TimersToPrint.reserve(Records.
size());
292 for (
const auto &
P : Records)
293 TimersToPrint.emplace_back(
P.getValue(), std::string(
P.getKey()),
294 std::string(
P.getKey()));
295 assert(TimersToPrint.size() == Records.
size() &&
"Size mismatch");
302 removeTimer(*FirstTimer);
304 if (!TimersToPrint.empty()) {
306 PrintQueuedTimers(*OutStream);
309 auto unlink = [&]() {
329void TimerGroup::removeTimer(
Timer &
T) {
333 if (
T.hasTriggered())
334 TimersToPrint.emplace_back(
T.Time,
T.Name,
T.Description);
341 T.Next->Prev =
T.Prev;
344void TimerGroup::addTimer(
Timer &
T) {
349 FirstTimer->Prev = &
T.Next;
351 T.Prev = &FirstTimer;
355void TimerGroup::PrintQueuedTimers(
raw_ostream &OS) {
361 for (
const PrintRecord &Record : TimersToPrint)
362 Total += Record.Time;
365 OS <<
"===" << std::string(73,
'-') <<
"===\n";
367 unsigned Padding = (80-Description.length())/2;
369 OS.
indent(Padding) << Description <<
'\n';
370 OS <<
"===" << std::string(73,
'-') <<
"===\n";
376 OS <<
format(
" Total Execution Time: %5.4f seconds (%5.4f wall clock)\n",
380 if (
Total.getUserTime())
381 OS <<
" ---User Time---";
382 if (
Total.getSystemTime())
383 OS <<
" --System Time--";
384 if (
Total.getProcessTime())
385 OS <<
" --User+System--";
386 OS <<
" ---Wall Time---";
387 if (
Total.getMemUsed())
389 if (
Total.getInstructionsExecuted())
390 OS <<
" ---Instr---";
391 OS <<
" --- Name ---\n";
394 for (
const PrintRecord &Record :
llvm::reverse(TimersToPrint)) {
395 Record.Time.print(
Total, OS);
396 OS << Record.Description <<
'\n';
403 TimersToPrint.clear();
406void TimerGroup::prepareToPrintList(
bool ResetTime) {
408 for (
Timer *
T = FirstTimer;
T;
T =
T->Next) {
409 if (!
T->hasTriggered())
continue;
410 bool WasRunning =
T->isRunning();
414 TimersToPrint.emplace_back(
T->Time,
T->Name,
T->Description);
428 prepareToPrintList(ResetAfterPrint);
432 if (!TimersToPrint.empty())
433 PrintQueuedTimers(OS);
438 for (
Timer *
T = FirstTimer;
T;
T =
T->Next)
455void TimerGroup::printJSONValue(
raw_ostream &OS,
const PrintRecord &R,
456 const char *suffix,
double Value) {
457 constexpr auto max_digits10 = std::numeric_limits<double>::max_digits10;
458 OS <<
"\t\"time." << Name <<
'.' << R.Name << suffix
459 <<
"\": " <<
format(
"%.*e", max_digits10 - 1,
Value);
465 prepareToPrintList(
false);
466 for (
const PrintRecord &R : TimersToPrint) {
471 printJSONValue(OS, R,
".wall",
T.getWallTime());
473 printJSONValue(OS, R,
".user",
T.getUserTime());
475 printJSONValue(OS, R,
".sys",
T.getSystemTime());
476 if (
T.getMemUsed()) {
478 printJSONValue(OS, R,
".mem",
T.getMemUsed());
480 if (
T.getInstructionsExecuted()) {
482 printJSONValue(OS, R,
".instr",
T.getInstructionsExecuted());
485 TimersToPrint.clear();
492 delim = TG->printJSONValues(OS, delim);
523 cl::desc(
"Enable -time-passes memory tracking (this may be slow)"),
527 cl::desc(
"In the report, sort the timers in each group in wall clock"
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
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 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 bool isTimerGlobalsConstructed()
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
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
Timer(StringRef TimerName, StringRef TimerDescription)
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::lock_guard< SmartMutex< mt_only > > SmartScopedLock
std::chrono::time_point< std::chrono::system_clock, D > TimePoint
A time point on the system clock.
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.
FunctionAddr VTableAddr Next
LLVM_ABI NamedRegionTimer(StringRef Name, StringRef Description, StringRef GroupName, StringRef GroupDescription, bool Enabled=true)
static LLVM_ABI TimerGroup & getNamedTimerGroup(StringRef GroupName, StringRef GroupDescription)