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)
244 new TimerGroup(GroupName, GroupDescription,
true);
258 GroupDescription)) {}
275 : Name(Name.begin(), Name.end()),
276 Description(Description.begin(), Description.end()),
288 : TimerGroup(Name, Description,
timerLock(), PrintOnExit) {}
292 : TimerGroup(Name, Description, PrintOnExit) {
293 TimersToPrint.reserve(Records.
size());
294 for (
const auto &
P : Records)
295 TimersToPrint.emplace_back(
P.getValue(), std::string(
P.getKey()),
296 std::string(
P.getKey()));
297 assert(TimersToPrint.size() == Records.
size() &&
"Size mismatch");
304 removeTimer(*FirstTimer);
306 if (!TimersToPrint.empty() && PrintOnExit) {
308 PrintQueuedTimers(*OutStream);
311 auto unlink = [&]() {
331void TimerGroup::removeTimer(
Timer &
T) {
335 if (
T.hasTriggered())
336 TimersToPrint.emplace_back(
T.Time,
T.Name,
T.Description);
343 T.Next->Prev =
T.Prev;
346void TimerGroup::addTimer(
Timer &
T) {
351 FirstTimer->Prev = &
T.Next;
353 T.Prev = &FirstTimer;
357void TimerGroup::PrintQueuedTimers(
raw_ostream &OS) {
363 for (
const PrintRecord &Record : TimersToPrint)
364 Total += Record.Time;
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";
396 for (
const PrintRecord &Record :
llvm::reverse(TimersToPrint)) {
397 Record.Time.print(
Total, OS);
398 OS << Record.Description <<
'\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 constexpr auto max_digits10 = std::numeric_limits<double>::max_digits10;
460 OS <<
"\t\"time." << Name <<
'.' << R.Name << suffix
461 <<
"\": " <<
format(
"%.*e", max_digits10 - 1,
Value);
467 prepareToPrintList(
false);
468 for (
const PrintRecord &R : TimersToPrint) {
473 printJSONValue(OS, R,
".wall",
T.getWallTime());
475 printJSONValue(OS, R,
".user",
T.getUserTime());
477 printJSONValue(OS, R,
".sys",
T.getSystemTime());
478 if (
T.getMemUsed()) {
480 printJSONValue(OS, R,
".mem",
T.getMemUsed());
482 if (
T.getInstructionsExecuted()) {
484 printJSONValue(OS, R,
".instr",
T.getInstructionsExecuted());
487 TimersToPrint.clear();
494 delim = TG->printJSONValues(OS, delim);
525 cl::desc(
"Enable -time-passes memory tracking (this may be slow)"),
529 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)