43 TrackSpace(
"track-memory",
cl::desc(
"Enable -time-passes memory "
44 "tracking (this may be slow)"),
49 cl::desc(
"File to append -stats and -timer output to"),
55 if (OutputFilename.empty())
56 return llvm::make_unique<raw_fd_ostream>(2,
false);
57 if (OutputFilename ==
"-")
58 return llvm::make_unique<raw_fd_ostream>(1,
false);
65 auto Result = llvm::make_unique<raw_fd_ostream>(
70 errs() <<
"Error opening info-output-file '"
71 << OutputFilename <<
" for appending!\n";
72 return llvm::make_unique<raw_fd_ostream>(2,
false);
85 tmp =
new TimerGroup(
"misc",
"Miscellaneous Ungrouped Timers");
102 assert(!TG &&
"Timer already initialized");
103 this->Name.assign(Name.
begin(), Name.
end());
104 this->Description.assign(Description.
begin(), Description.
end());
105 Running = Triggered =
false;
112 TG->removeTimer(*
this);
116 if (!TrackSpace)
return 0;
121 using Seconds = std::chrono::duration<double, std::ratio<1>>;
124 std::chrono::nanoseconds user, sys;
134 Result.WallTime = Seconds(now.time_since_epoch()).
count();
135 Result.UserTime = Seconds(user).count();
136 Result.SystemTime = Seconds(sys).count();
141 assert(!Running &&
"Cannot start a running timer");
142 Running = Triggered =
true;
147 assert(Running &&
"Cannot stop a paused timer");
154 Running = Triggered =
false;
162 OS <<
format(
" %7.4f (%5.1f%%)", Val, Val*100/Total);
193 for (
StringMap<std::pair<TimerGroup*, Name2TimerMap> >::iterator
194 I = Map.begin(),
E = Map.end();
I !=
E; ++
I)
195 delete I->second.first;
202 std::pair<TimerGroup*, Name2TimerMap> &GroupEntry = Map[GroupName];
204 if (!GroupEntry.first)
205 GroupEntry.first =
new TimerGroup(GroupName, GroupDescription);
209 T.
init(
Name, Description, *GroupEntry.first);
223 GroupDescription)) {}
235 Description(Description.
begin(), Description.
end()) {
249 removeTimer(*FirstTimer);
259 void TimerGroup::removeTimer(
Timer &
T) {
264 TimersToPrint.emplace_back(T.Time, T.Name, T.Description);
271 T.Next->Prev = T.Prev;
275 if (FirstTimer || TimersToPrint.empty())
279 PrintQueuedTimers(*OutStream);
282 void TimerGroup::addTimer(
Timer &T) {
287 FirstTimer->Prev = &T.Next;
289 T.Prev = &FirstTimer;
293 void TimerGroup::PrintQueuedTimers(
raw_ostream &OS) {
295 std::sort(TimersToPrint.begin(), TimersToPrint.end());
298 for (
const PrintRecord &
Record : TimersToPrint)
302 OS <<
"===" << std::string(73,
'-') <<
"===\n";
304 unsigned Padding = (80-Description.length())/2;
305 if (Padding > 80) Padding = 0;
306 OS.
indent(Padding) << Description <<
'\n';
307 OS <<
"===" << std::string(73,
'-') <<
"===\n";
313 OS <<
format(
" Total Execution Time: %5.4f seconds (%5.4f wall clock)\n",
314 Total.getProcessTime(), Total.getWallTime());
317 if (Total.getUserTime())
318 OS <<
" ---User Time---";
319 if (Total.getSystemTime())
320 OS <<
" --System Time--";
321 if (Total.getProcessTime())
322 OS <<
" --User+System--";
323 OS <<
" ---Wall Time---";
324 if (Total.getMemUsed())
326 OS <<
" --- Name ---\n";
330 TimersToPrint.rend())) {
331 Record.Time.print(Total, OS);
332 OS <<
Record.Description <<
'\n';
335 Total.print(Total, OS);
339 TimersToPrint.clear();
342 void TimerGroup::prepareToPrintList() {
345 for (
Timer *T = FirstTimer;
T; T = T->Next) {
347 TimersToPrint.emplace_back(T->Time, T->Name, T->Description);
357 prepareToPrintList();
360 if (!TimersToPrint.empty())
361 PrintQueuedTimers(OS);
371 void TimerGroup::printJSONValue(
raw_ostream &OS,
const PrintRecord &R,
372 const char *suffix,
double Value) {
375 OS <<
"\t\"time." << Name <<
'.' << R.Name << suffix <<
"\": " << Value;
378 const char *TimerGroup::printJSONValues(
raw_ostream &OS,
const char *delim) {
379 prepareToPrintList();
380 for (
const PrintRecord &R : TimersToPrint) {
391 TimersToPrint.clear();
395 const char *TimerGroup::printAllJSONValues(
raw_ostream &OS,
const char *delim) {
398 delim = TG->printJSONValues(OS, delim);
bool isInitialized() const
const_iterator end(StringRef path)
Get end iterator over path.
F_Append - When opening a file, if it already exists append to the existing file instead of returning...
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...
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
static TimeRecord getCurrentTime(bool Start=true)
Get the current time and memory usage.
void init(StringRef Name, StringRef Description)
void stopTimer()
Stop the timer.
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
const_iterator begin(StringRef path)
Get begin iterator over path.
bool needsQuotes(StringRef S)
The TimeRegion class is used as a helper class to call the startTimer() and stopTimer() methods of th...
double getProcessTime() const
double getWallTime() const
static cl::opt< std::string > OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"), cl::init("-"))
This class is used to track the amount of time spent between invocations of its startTimer()/stopTime...
double getUserTime() const
auto count(R &&Range, const E &Element) -> typename std::iterator_traits< decltype(std::begin(Range))>::difference_type
Wrapper function around std::count to count the number of times an element Element occurs in the give...
static void printVal(double Val, double Total, raw_ostream &OS)
static TimerGroup * DefaultTimerGroup
std::unique_ptr< raw_fd_ostream > CreateInfoOutputFile()
Return a file stream to print our output on.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
format_object< Ts...> format(const char *Fmt, const Ts &...Vals)
These are helper functions used to produce formatted output.
static TimerGroup * TimerGroupList
This is the global list of TimerGroups, maintained by the TimerGroup ctor/dtor and is protected by th...
ssize_t getMemUsed() const
static sys::TimePoint< std::chrono::seconds > now(bool Deterministic)
void clear()
Clear the timer state.
static ManagedStatic< std::string > LibSupportInfoOutputFilename
static ManagedStatic< Name2PairMap > NamedGroupedTimers
static size_t GetMallocUsage()
Return process memory usage.
void print(raw_ostream &OS)
Print any started timers in this group and zero them.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
static TimerGroup * getDefaultTimerGroup()
double getSystemTime() const
void startTimer()
Start the timer running.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings"...
static std::string & getLibSupportInfoOutputFilename()
The file should be opened in text mode on platforms that make this distinction.
bool hasTriggered() const
Check if startTimer() has ever been called on this timer.
Provides a library for accessing information about this process and other processes on the operating ...
The TimerGroup class is used to group together related timers into a single report that is printed wh...
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...
NamedRegionTimer(StringRef Name, StringRef Description, StringRef GroupName, StringRef GroupDescription, bool Enabled=true)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static void ConstructTimerLists()
Ensure global timer group lists are initialized.
LLVM Value Representation.
static void printAll(raw_ostream &OS)
This static method prints all timers and clears them all out.
This class implements an extremely fast bulk output stream that can only output to a stream...
static size_t getMemUsage()
StringRef - Represent a constant reference to a string, i.e.
ManagedStatic - This transparently changes the behavior of global statics to be lazily constructed on...
LocationClass< Ty > location(Ty &L)
static ManagedStatic< sys::SmartMutex< true > > TimerLock
std::chrono::time_point< std::chrono::system_clock, D > TimePoint
A time point on the system clock.