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 = new TimerGroup(GroupName, GroupDescription);
244
245 return GroupEntry;
246 }
247};
248
249}
250
252 StringRef GroupName,
253 StringRef GroupDescription, bool Enabled)
254 : TimeRegion(!Enabled
255 ? nullptr
256 : &namedGroupedTimers().get(Name, Description, GroupName,
257 GroupDescription)) {}
258
260 StringRef GroupDescription) {
261 return namedGroupedTimers().getTimerGroup(GroupName, GroupDescription);
262}
263
264//===----------------------------------------------------------------------===//
265// TimerGroup Implementation
266//===----------------------------------------------------------------------===//
267
268/// This is the global list of TimerGroups, maintained by the TimerGroup
269/// ctor/dtor and is protected by the timerLock lock.
270static TimerGroup *TimerGroupList = nullptr;
271
272TimerGroup::TimerGroup(StringRef Name, StringRef Description,
274 : Name(Name.begin(), Name.end()),
275 Description(Description.begin(), Description.end()) {
276 // Add the group to TimerGroupList.
278 if (TimerGroupList)
279 TimerGroupList->Prev = &Next;
281 Prev = &TimerGroupList;
282 TimerGroupList = this;
283}
284
285TimerGroup::TimerGroup(StringRef Name, StringRef Description)
286 : TimerGroup(Name, Description, timerLock()) {}
287
288TimerGroup::TimerGroup(StringRef Name, StringRef Description,
289 const StringMap<TimeRecord> &Records)
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");
296}
297
299 // If the timer group is destroyed before the timers it owns, accumulate and
300 // print the timing data.
301 while (FirstTimer)
302 removeTimer(*FirstTimer);
303
304 if (!TimersToPrint.empty()) {
305 std::unique_ptr<raw_ostream> OutStream = CreateInfoOutputFile();
306 PrintQueuedTimers(*OutStream);
307 }
308
309 auto unlink = [&]() {
310 *Prev = Next;
311 if (Next)
312 Next->Prev = Prev;
313 };
314
315 // TimerGlobals is always created implicity, through a call to timerLock(),
316 // when a TimeGroup is created. On CRT shutdown, the TimerGlobals instance
317 // might have been destroyed already. Avoid re-creating it if calling
318 // timerLock().
320 unlink();
321 return;
322 }
323
324 // Remove the group from the TimerGroupList.
326 unlink();
327}
328
329void TimerGroup::removeTimer(Timer &T) {
331
332 // If the timer was started, move its data to TimersToPrint.
333 if (T.hasTriggered())
334 TimersToPrint.emplace_back(T.Time, T.Name, T.Description);
335
336 T.TG = nullptr;
337
338 // Unlink the timer from our list.
339 *T.Prev = T.Next;
340 if (T.Next)
341 T.Next->Prev = T.Prev;
342}
343
344void TimerGroup::addTimer(Timer &T) {
346
347 // Add the timer to our list.
348 if (FirstTimer)
349 FirstTimer->Prev = &T.Next;
350 T.Next = FirstTimer;
351 T.Prev = &FirstTimer;
352 FirstTimer = &T;
353}
354
355void TimerGroup::PrintQueuedTimers(raw_ostream &OS) {
356 // Perhaps sort the timers in descending order by amount of time taken.
357 if (sortTimers())
358 llvm::sort(TimersToPrint);
359
360 TimeRecord Total;
361 for (const PrintRecord &Record : TimersToPrint)
362 Total += Record.Time;
363
364 // Print out timing header.
365 OS << "===" << std::string(73, '-') << "===\n";
366 // Figure out how many spaces to indent TimerGroup name.
367 unsigned Padding = (80-Description.length())/2;
368 if (Padding > 80) Padding = 0; // Don't allow "negative" numbers
369 OS.indent(Padding) << Description << '\n';
370 OS << "===" << std::string(73, '-') << "===\n";
371
372 // If this is not an collection of ungrouped times, print the total time.
373 // Ungrouped timers don't really make sense to add up. We still print the
374 // TOTAL line to make the percentages make sense.
375 if (this != &defaultTimerGroup())
376 OS << format(" Total Execution Time: %5.4f seconds (%5.4f wall clock)\n",
377 Total.getProcessTime(), Total.getWallTime());
378 OS << '\n';
379
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())
388 OS << " ---Mem---";
389 if (Total.getInstructionsExecuted())
390 OS << " ---Instr---";
391 OS << " --- Name ---\n";
392
393 // Loop through all of the timing data, printing it out.
394 for (const PrintRecord &Record : llvm::reverse(TimersToPrint)) {
395 Record.Time.print(Total, OS);
396 OS << Record.Description << '\n';
397 }
398
399 Total.print(Total, OS);
400 OS << "Total\n\n";
401 OS.flush();
402
403 TimersToPrint.clear();
404}
405
406void TimerGroup::prepareToPrintList(bool ResetTime) {
407 // See if any of our timers were started, if so add them to TimersToPrint.
408 for (Timer *T = FirstTimer; T; T = T->Next) {
409 if (!T->hasTriggered()) continue;
410 bool WasRunning = T->isRunning();
411 if (WasRunning)
412 T->stopTimer();
413
414 TimersToPrint.emplace_back(T->Time, T->Name, T->Description);
415
416 if (ResetTime)
417 T->clear();
418
419 if (WasRunning)
420 T->startTimer();
421 }
422}
423
424void TimerGroup::print(raw_ostream &OS, bool ResetAfterPrint) {
425 {
426 // After preparing the timers we can free the lock
428 prepareToPrintList(ResetAfterPrint);
429 }
430
431 // If any timers were started, print the group.
432 if (!TimersToPrint.empty())
433 PrintQueuedTimers(OS);
434}
435
438 for (Timer *T = FirstTimer; T; T = T->Next)
439 T->clear();
440}
441
444
445 for (TimerGroup *TG = TimerGroupList; TG; TG = TG->Next)
446 TG->print(OS);
447}
448
451 for (TimerGroup *TG = TimerGroupList; TG; TG = TG->Next)
452 TG->clear();
453}
454
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);
460}
461
462const char *TimerGroup::printJSONValues(raw_ostream &OS, const char *delim) {
464
465 prepareToPrintList(false);
466 for (const PrintRecord &R : TimersToPrint) {
467 OS << delim;
468 delim = ",\n";
469
470 const TimeRecord &T = R.Time;
471 printJSONValue(OS, R, ".wall", T.getWallTime());
472 OS << delim;
473 printJSONValue(OS, R, ".user", T.getUserTime());
474 OS << delim;
475 printJSONValue(OS, R, ".sys", T.getSystemTime());
476 if (T.getMemUsed()) {
477 OS << delim;
478 printJSONValue(OS, R, ".mem", T.getMemUsed());
479 }
480 if (T.getInstructionsExecuted()) {
481 OS << delim;
482 printJSONValue(OS, R, ".instr", T.getInstructionsExecuted());
483 }
484 }
485 TimersToPrint.clear();
486 return delim;
487}
488
489const char *TimerGroup::printAllJSONValues(raw_ostream &OS, const char *delim) {
491 for (TimerGroup *TG = TimerGroupList; TG; TG = TG->Next)
492 delim = TG->printJSONValues(OS, delim);
493 return delim;
494}
495
496//===----------------------------------------------------------------------===//
497// Timer Globals
498//
499// Previously, these were independent ManagedStatics. This led to bugs because
500// there are dependencies between the globals, but no reliable mechanism to
501// control relative lifetimes.
502//
503// Placing the globals within one class instance lets us control the lifetimes
504// of the various data members and ensure that no global uses another that has
505// been deleted.
506//
507// Globals fall into two categories. First are simple data types and
508// command-line options. These are cheap to construct and/or required early
509// during launch. They are created when the ManagedTimerGlobals singleton is
510// constructed. Second are types that are more expensive to construct or not
511// needed until later during compilation. These are lazily constructed in order
512// to reduce launch time.
513//===----------------------------------------------------------------------===//
515public:
518 "info-output-file", cl::value_desc("filename"),
519 cl::desc("File to append -stats and -timer output to"), cl::Hidden,
522 "track-memory",
523 cl::desc("Enable -time-passes memory tracking (this may be slow)"),
524 cl::Hidden};
526 "sort-timers",
527 cl::desc("In the report, sort the timers in each group in wall clock"
528 " time order"),
529 cl::init(true), cl::Hidden};
530
532 TimerGroup DefaultTimerGroup{"misc", "Miscellaneous Ungrouped Timers",
533 TimerLock};
535
536 // Order of these members and initialization below is important. For example
537 // the defaultTimerGroup uses the timerLock. Most of these also depend on the
538 // options above.
539 std::once_flag InitDeferredFlag;
540 std::optional<Name2PairMap> NamedGroupedTimersPtr;
541
543 std::call_once(InitDeferredFlag,
544 [this]() { NamedGroupedTimersPtr.emplace(); });
545 return *this;
546 }
547};
548
550
551static std::string &libSupportInfoOutputFilename() {
552 return ManagedTimerGlobals->LibSupportInfoOutputFilename;
553}
554static bool trackSpace() { return ManagedTimerGlobals->TrackSpace; }
555static bool sortTimers() { return ManagedTimerGlobals->SortTimers; }
556static SignpostEmitter &signposts() { return ManagedTimerGlobals->Signposts; }
558 return ManagedTimerGlobals->TimerLock;
559}
561 return ManagedTimerGlobals->DefaultTimerGroup;
562}
563static Name2PairMap &namedGroupedTimers() {
564 return *ManagedTimerGlobals->initDeferred().NamedGroupedTimersPtr;
565}
566
571
573
575 return ManagedTimerGlobals.isConstructed();
576}
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 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:557
static ManagedStatic< TimerGlobals > ManagedTimerGlobals
Definition Timer.cpp:549
static TimerGroup & defaultTimerGroup()
Definition Timer.cpp:560
static bool isTimerGlobalsConstructed()
Definition Timer.cpp:574
static std::string & libSupportInfoOutputFilename()
Definition Timer.cpp:551
static bool trackSpace()
Definition Timer.cpp:554
static SignpostEmitter & signposts()
Definition Timer.cpp:556
static bool sortTimers()
Definition Timer.cpp:555
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:270
static uint64_t getCurInstructionsExecuted()
Definition Timer.cpp:117
static Name2PairMap & namedGroupedTimers()
Definition Timer.cpp:563
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:517
cl::opt< bool > SortTimers
Definition Timer.cpp:525
sys::SmartMutex< true > TimerLock
Definition Timer.cpp:531
TimerGlobals & initDeferred()
Definition Timer.cpp:542
std::string LibSupportInfoOutputFilename
Definition Timer.cpp:516
TimerGroup DefaultTimerGroup
Definition Timer.cpp:532
cl::opt< bool > TrackSpace
Definition Timer.cpp:521
std::once_flag InitDeferredFlag
Definition Timer.cpp:539
SignpostEmitter Signposts
Definition Timer.cpp:534
std::optional< Name2PairMap > NamedGroupedTimersPtr
Definition Timer.cpp:540
The TimerGroup class is used to group together related timers into a single report that is printed wh...
Definition Timer.h:186
static LLVM_ABI void printAll(raw_ostream &OS)
This static method prints all timers.
Definition Timer.cpp:442
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:424
friend class Timer
Definition Timer.h:260
static LLVM_ABI void clearAll()
Clear out all timers.
Definition Timer.cpp:449
LLVM_ABI void clear()
Clear all timers in this group.
Definition Timer.cpp:436
LLVM_ABI ~TimerGroup()
Definition Timer.cpp:298
static LLVM_ABI void * acquireTimerGlobals()
This makes the timer globals unmanaged, and lets the user manage the lifetime.
Definition Timer.cpp:572
static LLVM_ABI const char * printAllJSONValues(raw_ostream &OS, const char *delim)
Prints all timers as JSON key/value pairs.
Definition Timer.cpp:489
LLVM_ABI const char * printJSONValues(raw_ostream &OS, const char *delim)
Definition Timer.cpp:462
static LLVM_ABI void constructForStatistics()
Ensure global objects required for statistics printing are initialized.
Definition Timer.cpp:568
This class is used to track the amount of time spent between invocations of its startTimer()/stopTime...
Definition Timer.h:82
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:143
const std::string & getName() const
Definition Timer.h:115
Timer(StringRef TimerName, StringRef TimerDescription)
Definition Timer.h:94
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:776
@ OF_Append
The file should be opened in append mode.
Definition FileSystem.h:779
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:408
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1624
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition Format.h:126
void initTimerOptions()
Definition Timer.cpp:567
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:251
static LLVM_ABI TimerGroup & getNamedTimerGroup(StringRef GroupName, StringRef GroupDescription)
Definition Timer.cpp:259