LLVM 22.0.0git
Timer.cpp
Go to the documentation of this file.
1//===-- Timer.cpp - Interval Timing Support -------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file Interval Timing implementation.
10//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/Support/Timer.h"
14
15#include "DebugOptions.h"
16
17#include "llvm/ADT/Statistic.h"
18#include "llvm/ADT/StringMap.h"
19#include "llvm/Config/config.h"
22#include "llvm/Support/Format.h"
24#include "llvm/Support/Mutex.h"
28#include <limits>
29#include <optional>
30
31#if HAVE_UNISTD_H
32#include <unistd.h>
33#endif
34
35#ifdef HAVE_PROC_PID_RUSAGE
36#include <libproc.h>
37#endif
38
39using namespace llvm;
40
41//===----------------------------------------------------------------------===//
42// Forward declarations for Managed Timer Globals getters.
43//
44// Globals have been placed at the end of the file to restrict direct
45// access. Use of getters also has the benefit of making it a bit more explicit
46// that a global is being used.
47//===----------------------------------------------------------------------===//
48namespace {
49class Name2PairMap;
50}
51
52static std::string &libSupportInfoOutputFilename();
53static bool trackSpace();
54static bool sortTimers();
55[[maybe_unused]]
59static Name2PairMap &namedGroupedTimers();
60static bool isTimerGlobalsConstructed();
61
62//===----------------------------------------------------------------------===//
63//
64//===----------------------------------------------------------------------===//
65
66std::unique_ptr<raw_ostream> llvm::CreateInfoOutputFile() {
67 const std::string &OutputFilename = libSupportInfoOutputFilename();
68 if (OutputFilename.empty())
69 return std::make_unique<raw_fd_ostream>(2, false); // stderr.
70 if (OutputFilename == "-")
71 return std::make_unique<raw_fd_ostream>(1, false); // stdout.
72
73 // Append mode is used because the info output file is opened and closed
74 // each time -stats or -time-passes wants to print output to it. To
75 // compensate for this, the test-suite Makefiles have code to delete the
76 // info output file before running commands which write to it.
77 std::error_code EC;
78 auto Result = std::make_unique<raw_fd_ostream>(
80 if (!EC)
81 return Result;
82
83 errs() << "Error opening info-output-file '"
84 << OutputFilename << " for appending!\n";
85 return std::make_unique<raw_fd_ostream>(2, false); // stderr.
86}
87
88//===----------------------------------------------------------------------===//
89// Timer Implementation
90//===----------------------------------------------------------------------===//
91
92void Timer::init(StringRef TimerName, StringRef TimerDescription) {
93 init(TimerName, TimerDescription, defaultTimerGroup());
94}
95
96void Timer::init(StringRef TimerName, StringRef TimerDescription,
97 TimerGroup &tg) {
98 assert(!TG && "Timer already initialized");
99 Name.assign(TimerName.begin(), TimerName.end());
100 Description.assign(TimerDescription.begin(), TimerDescription.end());
101 Running = Triggered = false;
102 TG = &tg;
103 TG->addTimer(*this);
104}
105
107 if (!TG) return; // Never initialized, or already cleared.
108 TG->removeTimer(*this);
109}
110
111static inline size_t getMemUsage() {
112 if (!trackSpace())
113 return 0;
115}
116
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;
123 }
124#endif
125 return 0;
126}
127
129 using Seconds = std::chrono::duration<double, std::ratio<1>>;
130 TimeRecord Result;
132 std::chrono::nanoseconds user, sys;
133
134 if (Start) {
135 Result.MemUsed = getMemUsage();
136 Result.InstructionsExecuted = getCurInstructionsExecuted();
138 } else {
140 Result.InstructionsExecuted = getCurInstructionsExecuted();
141 Result.MemUsed = getMemUsage();
142 }
143
144 Result.WallTime = Seconds(now.time_since_epoch()).count();
145 Result.UserTime = Seconds(user).count();
146 Result.SystemTime = Seconds(sys).count();
147 return Result;
148}
149
151 assert(!Running && "Cannot start a running timer");
152 Running = Triggered = true;
153#if LLVM_SUPPORT_XCODE_SIGNPOSTS
155#endif
156 StartTime = TimeRecord::getCurrentTime(true);
157}
158
160 assert(Running && "Cannot stop a paused timer");
161 Running = false;
162 Time += TimeRecord::getCurrentTime(false);
163 Time -= StartTime;
164#if LLVM_SUPPORT_XCODE_SIGNPOSTS
165 signposts().endInterval(this, getName());
166#endif
167}
168
170 Running = Triggered = false;
171 Time = StartTime = TimeRecord();
172}
173
175 stopTimer();
176 O.startTimer();
177}
178
179static void printVal(double Val, double Total, raw_ostream &OS) {
180 if (Total < 1e-7) // Avoid dividing by zero.
181 OS << " ----- ";
182 else
183 OS << format(" %7.4f (%5.1f%%)", Val, Val*100/Total);
184}
185
187 if (Total.getUserTime())
188 printVal(getUserTime(), Total.getUserTime(), OS);
189 if (Total.getSystemTime())
190 printVal(getSystemTime(), Total.getSystemTime(), OS);
191 if (Total.getProcessTime())
192 printVal(getProcessTime(), Total.getProcessTime(), OS);
193 printVal(getWallTime(), Total.getWallTime(), OS);
194
195 OS << " ";
196
197 if (Total.getMemUsed())
198 OS << format("%9" PRId64 " ", (int64_t)getMemUsed());
199 if (Total.getInstructionsExecuted())
200 OS << format("%9" PRId64 " ", (int64_t)getInstructionsExecuted());
201}
202
203
204//===----------------------------------------------------------------------===//
205// NamedRegionTimer Implementation
206//===----------------------------------------------------------------------===//
207
208namespace {
209
210typedef StringMap<Timer> Name2TimerMap;
211
212class Name2PairMap {
214public:
215 ~Name2PairMap() {
216 for (StringMap<std::pair<TimerGroup*, Name2TimerMap> >::iterator
217 I = Map.begin(), E = Map.end(); I != E; ++I)
218 delete I->second.first;
219 }
220
221 Timer &get(StringRef Name, StringRef Description, StringRef GroupName,
222 StringRef GroupDescription) {
224
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);
230 return T;
231 }
232
233 TimerGroup &getTimerGroup(StringRef GroupName, StringRef GroupDescription) {
235 return *getGroupEntry(GroupName, GroupDescription).first;
236 }
237
238private:
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 =
244 new TimerGroup(GroupName, GroupDescription, /*PrintOnExit=*/true);
245
246 return GroupEntry;
247 }
248};
249
250}
251
253 StringRef GroupName,
254 StringRef GroupDescription, bool Enabled)
255 : TimeRegion(!Enabled
256 ? nullptr
257 : &namedGroupedTimers().get(Name, Description, GroupName,
258 GroupDescription)) {}
259
261 StringRef GroupDescription) {
262 return namedGroupedTimers().getTimerGroup(GroupName, GroupDescription);
263}
264
265//===----------------------------------------------------------------------===//
266// TimerGroup Implementation
267//===----------------------------------------------------------------------===//
268
269/// This is the global list of TimerGroups, maintained by the TimerGroup
270/// ctor/dtor and is protected by the timerLock lock.
271static TimerGroup *TimerGroupList = nullptr;
272
273TimerGroup::TimerGroup(StringRef Name, StringRef Description,
275 : Name(Name.begin(), Name.end()),
276 Description(Description.begin(), Description.end()),
278 // Add the group to TimerGroupList.
280 if (TimerGroupList)
281 TimerGroupList->Prev = &Next;
283 Prev = &TimerGroupList;
284 TimerGroupList = this;
285}
286
287TimerGroup::TimerGroup(StringRef Name, StringRef Description, bool PrintOnExit)
288 : TimerGroup(Name, Description, timerLock(), PrintOnExit) {}
289
290TimerGroup::TimerGroup(StringRef Name, StringRef Description,
291 const StringMap<TimeRecord> &Records, bool 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");
298}
299
301 // If the timer group is destroyed before the timers it owns, accumulate and
302 // print the timing data.
303 while (FirstTimer)
304 removeTimer(*FirstTimer);
305
306 if (!TimersToPrint.empty() && PrintOnExit) {
307 std::unique_ptr<raw_ostream> OutStream = CreateInfoOutputFile();
308 PrintQueuedTimers(*OutStream);
309 }
310
311 auto unlink = [&]() {
312 *Prev = Next;
313 if (Next)
314 Next->Prev = Prev;
315 };
316
317 // TimerGlobals is always created implicity, through a call to timerLock(),
318 // when a TimeGroup is created. On CRT shutdown, the TimerGlobals instance
319 // might have been destroyed already. Avoid re-creating it if calling
320 // timerLock().
322 unlink();
323 return;
324 }
325
326 // Remove the group from the TimerGroupList.
328 unlink();
329}
330
331void TimerGroup::removeTimer(Timer &T) {
333
334 // If the timer was started, move its data to TimersToPrint.
335 if (T.hasTriggered())
336 TimersToPrint.emplace_back(T.Time, T.Name, T.Description);
337
338 T.TG = nullptr;
339
340 // Unlink the timer from our list.
341 *T.Prev = T.Next;
342 if (T.Next)
343 T.Next->Prev = T.Prev;
344}
345
346void TimerGroup::addTimer(Timer &T) {
348
349 // Add the timer to our list.
350 if (FirstTimer)
351 FirstTimer->Prev = &T.Next;
352 T.Next = FirstTimer;
353 T.Prev = &FirstTimer;
354 FirstTimer = &T;
355}
356
357void TimerGroup::PrintQueuedTimers(raw_ostream &OS) {
358 // Perhaps sort the timers in descending order by amount of time taken.
359 if (sortTimers())
360 llvm::sort(TimersToPrint);
361
362 TimeRecord Total;
363 for (const PrintRecord &Record : TimersToPrint)
364 Total += Record.Time;
365
366 // Print out timing header.
367 OS << "===" << std::string(73, '-') << "===\n";
368 // Figure out how many spaces to indent TimerGroup name.
369 unsigned Padding = (80-Description.length())/2;
370 if (Padding > 80) Padding = 0; // Don't allow "negative" numbers
371 OS.indent(Padding) << Description << '\n';
372 OS << "===" << std::string(73, '-') << "===\n";
373
374 // If this is not an collection of ungrouped times, print the total time.
375 // Ungrouped timers don't really make sense to add up. We still print the
376 // TOTAL line to make the percentages make sense.
377 if (this != &defaultTimerGroup())
378 OS << format(" Total Execution Time: %5.4f seconds (%5.4f wall clock)\n",
379 Total.getProcessTime(), Total.getWallTime());
380 OS << '\n';
381
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())
390 OS << " ---Mem---";
391 if (Total.getInstructionsExecuted())
392 OS << " ---Instr---";
393 OS << " --- Name ---\n";
394
395 // Loop through all of the timing data, printing it out.
396 for (const PrintRecord &Record : llvm::reverse(TimersToPrint)) {
397 Record.Time.print(Total, OS);
398 OS << Record.Description << '\n';
399 }
400
401 Total.print(Total, OS);
402 OS << "Total\n\n";
403 OS.flush();
404
405 TimersToPrint.clear();
406}
407
408void TimerGroup::prepareToPrintList(bool ResetTime) {
409 // See if any of our timers were started, if so add them to TimersToPrint.
410 for (Timer *T = FirstTimer; T; T = T->Next) {
411 if (!T->hasTriggered()) continue;
412 bool WasRunning = T->isRunning();
413 if (WasRunning)
414 T->stopTimer();
415
416 TimersToPrint.emplace_back(T->Time, T->Name, T->Description);
417
418 if (ResetTime)
419 T->clear();
420
421 if (WasRunning)
422 T->startTimer();
423 }
424}
425
426void TimerGroup::print(raw_ostream &OS, bool ResetAfterPrint) {
427 {
428 // After preparing the timers we can free the lock
430 prepareToPrintList(ResetAfterPrint);
431 }
432
433 // If any timers were started, print the group.
434 if (!TimersToPrint.empty())
435 PrintQueuedTimers(OS);
436}
437
440 for (Timer *T = FirstTimer; T; T = T->Next)
441 T->clear();
442}
443
446
447 for (TimerGroup *TG = TimerGroupList; TG; TG = TG->Next)
448 TG->print(OS);
449}
450
453 for (TimerGroup *TG = TimerGroupList; TG; TG = TG->Next)
454 TG->clear();
455}
456
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);
462}
463
464const char *TimerGroup::printJSONValues(raw_ostream &OS, const char *delim) {
466
467 prepareToPrintList(false);
468 for (const PrintRecord &R : TimersToPrint) {
469 OS << delim;
470 delim = ",\n";
471
472 const TimeRecord &T = R.Time;
473 printJSONValue(OS, R, ".wall", T.getWallTime());
474 OS << delim;
475 printJSONValue(OS, R, ".user", T.getUserTime());
476 OS << delim;
477 printJSONValue(OS, R, ".sys", T.getSystemTime());
478 if (T.getMemUsed()) {
479 OS << delim;
480 printJSONValue(OS, R, ".mem", T.getMemUsed());
481 }
482 if (T.getInstructionsExecuted()) {
483 OS << delim;
484 printJSONValue(OS, R, ".instr", T.getInstructionsExecuted());
485 }
486 }
487 TimersToPrint.clear();
488 return delim;
489}
490
491const char *TimerGroup::printAllJSONValues(raw_ostream &OS, const char *delim) {
493 for (TimerGroup *TG = TimerGroupList; TG; TG = TG->Next)
494 delim = TG->printJSONValues(OS, delim);
495 return delim;
496}
497
498//===----------------------------------------------------------------------===//
499// Timer Globals
500//
501// Previously, these were independent ManagedStatics. This led to bugs because
502// there are dependencies between the globals, but no reliable mechanism to
503// control relative lifetimes.
504//
505// Placing the globals within one class instance lets us control the lifetimes
506// of the various data members and ensure that no global uses another that has
507// been deleted.
508//
509// Globals fall into two categories. First are simple data types and
510// command-line options. These are cheap to construct and/or required early
511// during launch. They are created when the ManagedTimerGlobals singleton is
512// constructed. Second are types that are more expensive to construct or not
513// needed until later during compilation. These are lazily constructed in order
514// to reduce launch time.
515//===----------------------------------------------------------------------===//
517public:
520 "info-output-file", cl::value_desc("filename"),
521 cl::desc("File to append -stats and -timer output to"), cl::Hidden,
524 "track-memory",
525 cl::desc("Enable -time-passes memory tracking (this may be slow)"),
526 cl::Hidden};
528 "sort-timers",
529 cl::desc("In the report, sort the timers in each group in wall clock"
530 " time order"),
531 cl::init(true), cl::Hidden};
532
534 TimerGroup DefaultTimerGroup{"misc", "Miscellaneous Ungrouped Timers",
535 TimerLock, /*PrintOnExit=*/true};
537
538 // Order of these members and initialization below is important. For example
539 // the defaultTimerGroup uses the timerLock. Most of these also depend on the
540 // options above.
541 std::once_flag InitDeferredFlag;
542 std::optional<Name2PairMap> NamedGroupedTimersPtr;
543
545 std::call_once(InitDeferredFlag,
546 [this]() { NamedGroupedTimersPtr.emplace(); });
547 return *this;
548 }
549};
550
552
553static std::string &libSupportInfoOutputFilename() {
554 return ManagedTimerGlobals->LibSupportInfoOutputFilename;
555}
556static bool trackSpace() { return ManagedTimerGlobals->TrackSpace; }
557static bool sortTimers() { return ManagedTimerGlobals->SortTimers; }
558static SignpostEmitter &signposts() { return ManagedTimerGlobals->Signposts; }
560 return ManagedTimerGlobals->TimerLock;
561}
563 return ManagedTimerGlobals->DefaultTimerGroup;
564}
565static Name2PairMap &namedGroupedTimers() {
566 return *ManagedTimerGlobals->initDeferred().NamedGroupedTimersPtr;
567}
568
573
575
577 return ManagedTimerGlobals.isConstructed();
578}
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)
#define I(x, y, z)
Definition MD5.cpp:58
static cl::opt< std::string > OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"), cl::init("-"))
#define T
#define P(N)
Provides a library for accessing information about this process and other processes on the operating ...
static bool PrintOnExit
Definition Statistic.cpp:47
static bool Enabled
Definition Statistic.cpp:46
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
static sys::SmartMutex< true > & timerLock()
Definition Timer.cpp:559
static ManagedStatic< TimerGlobals > ManagedTimerGlobals
Definition Timer.cpp:551
static TimerGroup & defaultTimerGroup()
Definition Timer.cpp:562
static bool isTimerGlobalsConstructed()
Definition Timer.cpp:576
static std::string & libSupportInfoOutputFilename()
Definition Timer.cpp:553
static bool trackSpace()
Definition Timer.cpp:556
static SignpostEmitter & signposts()
Definition Timer.cpp:558
static bool sortTimers()
Definition Timer.cpp:557
static size_t getMemUsage()
Definition Timer.cpp:111
static void printVal(double Val, double Total, raw_ostream &OS)
Definition Timer.cpp:179
static TimerGroup * TimerGroupList
This is the global list of TimerGroups, maintained by the TimerGroup ctor/dtor and is protected by th...
Definition Timer.cpp:271
static uint64_t getCurInstructionsExecuted()
Definition Timer.cpp:117
static Name2PairMap & namedGroupedTimers()
Definition Timer.cpp:565
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.
Definition Signposts.h:28
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",...
Definition StringMap.h:133
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
iterator begin() const
Definition StringRef.h:112
iterator end() const
Definition StringRef.h:114
double getUserTime() const
Definition Timer.h:44
double getProcessTime() const
Definition Timer.h:43
TimeRecord()=default
static LLVM_ABI TimeRecord getCurrentTime(bool Start=true)
Get the current time and memory usage.
Definition Timer.cpp:128
double getWallTime() const
Definition Timer.h:46
ssize_t getMemUsed() const
Definition Timer.h:47
double getSystemTime() const
Definition Timer.h:45
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.
Definition Timer.cpp:186
uint64_t getInstructionsExecuted() const
Definition Timer.h:48
cl::opt< std::string, true > InfoOutputFilename
Definition Timer.cpp:519
cl::opt< bool > SortTimers
Definition Timer.cpp:527
sys::SmartMutex< true > TimerLock
Definition Timer.cpp:533
TimerGlobals & initDeferred()
Definition Timer.cpp:544
std::string LibSupportInfoOutputFilename
Definition Timer.cpp:518
TimerGroup DefaultTimerGroup
Definition Timer.cpp:534
cl::opt< bool > TrackSpace
Definition Timer.cpp:523
std::once_flag InitDeferredFlag
Definition Timer.cpp:541
SignpostEmitter Signposts
Definition Timer.cpp:536
std::optional< Name2PairMap > NamedGroupedTimersPtr
Definition Timer.cpp:542
The TimerGroup class is used to group together related timers into a single report that is printed wh...
Definition Timer.h:192
static LLVM_ABI void printAll(raw_ostream &OS)
This static method prints all timers.
Definition Timer.cpp:444
LLVM_ABI void print(raw_ostream &OS, bool ResetAfterPrint=false)
Print any started timers in this group, optionally resetting timers after printing them.
Definition Timer.cpp:426
friend class Timer
Definition Timer.h:269
static LLVM_ABI void clearAll()
Clear out all timers.
Definition Timer.cpp:451
LLVM_ABI void clear()
Clear all timers in this group.
Definition Timer.cpp:438
LLVM_ABI ~TimerGroup()
Definition Timer.cpp:300
static LLVM_ABI void * acquireTimerGlobals()
This makes the timer globals unmanaged, and lets the user manage the lifetime.
Definition Timer.cpp:574
static LLVM_ABI const char * printAllJSONValues(raw_ostream &OS, const char *delim)
Prints all timers as JSON key/value pairs.
Definition Timer.cpp:491
LLVM_ABI const char * printJSONValues(raw_ostream &OS, const char *delim)
Definition Timer.cpp:464
static LLVM_ABI void constructForStatistics()
Ensure global objects required for statistics printing are initialized.
Definition Timer.cpp:570
This class is used to track the amount of time spent between invocations of its startTimer()/stopTime...
Definition Timer.h:88
LLVM_ABI void yieldTo(Timer &)
Stop the timer and start another timer.
Definition Timer.cpp:174
LLVM_ABI ~Timer()
Definition Timer.cpp:106
LLVM_ABI void stopTimer()
Stop the timer.
Definition Timer.cpp:159
LLVM_ABI void init(StringRef TimerName, StringRef TimerDescription)
Definition Timer.cpp:92
LLVM_ABI void clear()
Clear the timer state.
Definition Timer.cpp:169
friend class TimerGroup
Definition Timer.h:149
const std::string & getName() const
Definition Timer.h:121
Timer(StringRef TimerName, StringRef TimerDescription)
Definition Timer.h:100
LLVM_ABI void startTimer()
Start the timer running.
Definition Timer.cpp:150
LLVM Value Representation.
Definition Value.h:75
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
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 ...
Definition Mutex.h:28
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 '.
Definition FileSystem.h:764
@ OF_Append
The file should be opened in append mode.
Definition FileSystem.h:767
std::lock_guard< SmartMutex< mt_only > > SmartScopedLock
Definition Mutex.h:69
std::chrono::time_point< std::chrono::system_clock, D > TimePoint
A time point on the system clock.
Definition Chrono.h:34
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.
Definition Timer.cpp:66
auto reverse(ContainerTy &&C)
Definition STLExtras.h:406
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1622
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition Format.h:129
void initTimerOptions()
Definition Timer.cpp:569
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
FunctionAddr VTableAddr Next
Definition InstrProf.h:141
LLVM_ABI NamedRegionTimer(StringRef Name, StringRef Description, StringRef GroupName, StringRef GroupDescription, bool Enabled=true)
Definition Timer.cpp:252
static LLVM_ABI TimerGroup & getNamedTimerGroup(StringRef GroupName, StringRef GroupDescription)
Definition Timer.cpp:260