Skip to content

Commit af4d76d

Browse files
authored
[Support] Reduce globaal variable overhead after #121663
* Construct frequently-accessed TimerLock/DefaultTimerGroup early to reduce overhead. * Rename `aquireDefaultGroup` to `acquireTimerGlobals` and restore ManagedStatic::claim. https://reviews.llvm.org/D76099 * Drop mtg::. We use internal linkage, so mtg:: is unneeded and might mislead users. In addition, llvm/ code almost never introduces a named namespace not in llvm::. Drop mtg::. * Replace some unique_ptr with optional to reduce overhead. * Switch to `functionName()`. * Simplify `llvm::initTimerOptions` and `TimerGroup::constructForStatistics()` Pull Request: #122429
1 parent 99d0780 commit af4d76d

File tree

3 files changed

+75
-116
lines changed

3 files changed

+75
-116
lines changed

clang/tools/driver/driver.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ int clang_main(int Argc, char **Argv, const llvm::ToolContext &ToolContext) {
439439
if (!UseNewCC1Process && IsCrash) {
440440
// When crashing in -fintegrated-cc1 mode, bury the timer pointers, because
441441
// the internal linked list might point to already released stack frames.
442-
llvm::BuryPointer(llvm::TimerGroup::aquireDefaultGroup());
442+
llvm::BuryPointer(llvm::TimerGroup::acquireTimerGlobals());
443443
} else {
444444
// If any timers were active but haven't been destroyed yet, print their
445445
// results now. This happens in -disable-free mode.

llvm/include/llvm/Support/Timer.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -240,9 +240,9 @@ class TimerGroup {
240240
/// global constructors and destructors.
241241
static void constructForStatistics();
242242

243-
/// This makes the default group unmanaged, and lets the user manage the
244-
/// group's lifetime.
245-
static std::unique_ptr<TimerGroup> aquireDefaultGroup();
243+
/// This makes the timer globals unmanaged, and lets the user manage the
244+
/// lifetime.
245+
static void *acquireTimerGlobals();
246246

247247
private:
248248
friend class Timer;

llvm/lib/Support/Timer.cpp

Lines changed: 71 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "llvm/Support/YAMLTraits.h"
2828
#include "llvm/Support/raw_ostream.h"
2929
#include <limits>
30+
#include <optional>
3031

3132
#if HAVE_UNISTD_H
3233
#include <unistd.h>
@@ -39,7 +40,7 @@
3940
using namespace llvm;
4041

4142
//===----------------------------------------------------------------------===//
42-
// Forward declarations for Managed Timer Globals (mtg) getters.
43+
// Forward declarations for Managed Timer Globals getters.
4344
//
4445
// Globals have been placed at the end of the file to restrict direct
4546
// access. Use of getters also has the benefit of making it a bit more explicit
@@ -49,29 +50,20 @@ namespace {
4950
class Name2PairMap;
5051
}
5152

52-
namespace mtg {
53-
static std::string &LibSupportInfoOutputFilename();
54-
static const std::string &InfoOutputFilename();
55-
static bool TrackSpace();
56-
static bool SortTimers();
57-
static SignpostEmitter &Signposts();
58-
static sys::SmartMutex<true> &TimerLock();
59-
static TimerGroup &DefaultTimerGroup();
60-
static TimerGroup *claimDefaultTimerGroup();
61-
static Name2PairMap &NamedGroupedTimers();
62-
} // namespace mtg
53+
static std::string &libSupportInfoOutputFilename();
54+
static bool trackSpace();
55+
static bool sortTimers();
56+
static SignpostEmitter &signposts();
57+
static sys::SmartMutex<true> &timerLock();
58+
static TimerGroup &defaultTimerGroup();
59+
static Name2PairMap &namedGroupedTimers();
6360

6461
//===----------------------------------------------------------------------===//
6562
//
6663
//===----------------------------------------------------------------------===//
67-
void llvm::initTimerOptions() {
68-
mtg::TrackSpace();
69-
mtg::InfoOutputFilename();
70-
mtg::SortTimers();
71-
}
7264

7365
std::unique_ptr<raw_ostream> llvm::CreateInfoOutputFile() {
74-
const std::string &OutputFilename = mtg::LibSupportInfoOutputFilename();
66+
const std::string &OutputFilename = libSupportInfoOutputFilename();
7567
if (OutputFilename.empty())
7668
return std::make_unique<raw_fd_ostream>(2, false); // stderr.
7769
if (OutputFilename == "-")
@@ -97,7 +89,7 @@ std::unique_ptr<raw_ostream> llvm::CreateInfoOutputFile() {
9789
//===----------------------------------------------------------------------===//
9890

9991
void Timer::init(StringRef TimerName, StringRef TimerDescription) {
100-
init(TimerName, TimerDescription, mtg::DefaultTimerGroup());
92+
init(TimerName, TimerDescription, defaultTimerGroup());
10193
}
10294

10395
void Timer::init(StringRef TimerName, StringRef TimerDescription,
@@ -116,7 +108,7 @@ Timer::~Timer() {
116108
}
117109

118110
static inline size_t getMemUsage() {
119-
if (!mtg::TrackSpace())
111+
if (!trackSpace())
120112
return 0;
121113
return sys::Process::GetMallocUsage();
122114
}
@@ -157,7 +149,7 @@ TimeRecord TimeRecord::getCurrentTime(bool Start) {
157149
void Timer::startTimer() {
158150
assert(!Running && "Cannot start a running timer");
159151
Running = Triggered = true;
160-
mtg::Signposts().startInterval(this, getName());
152+
signposts().startInterval(this, getName());
161153
StartTime = TimeRecord::getCurrentTime(true);
162154
}
163155

@@ -166,7 +158,7 @@ void Timer::stopTimer() {
166158
Running = false;
167159
Time += TimeRecord::getCurrentTime(false);
168160
Time -= StartTime;
169-
mtg::Signposts().endInterval(this, getName());
161+
signposts().endInterval(this, getName());
170162
}
171163

172164
void Timer::clear() {
@@ -218,7 +210,7 @@ class Name2PairMap {
218210

219211
Timer &get(StringRef Name, StringRef Description, StringRef GroupName,
220212
StringRef GroupDescription) {
221-
sys::SmartScopedLock<true> L(mtg::TimerLock());
213+
sys::SmartScopedLock<true> L(timerLock());
222214

223215
std::pair<TimerGroup*, Name2TimerMap> &GroupEntry = Map[GroupName];
224216

@@ -237,17 +229,17 @@ class Name2PairMap {
237229
NamedRegionTimer::NamedRegionTimer(StringRef Name, StringRef Description,
238230
StringRef GroupName,
239231
StringRef GroupDescription, bool Enabled)
240-
: TimeRegion(!Enabled ? nullptr
241-
: &mtg::NamedGroupedTimers().get(Name, Description,
242-
GroupName,
243-
GroupDescription)) {}
232+
: TimeRegion(!Enabled
233+
? nullptr
234+
: &namedGroupedTimers().get(Name, Description, GroupName,
235+
GroupDescription)) {}
244236

245237
//===----------------------------------------------------------------------===//
246238
// TimerGroup Implementation
247239
//===----------------------------------------------------------------------===//
248240

249241
/// This is the global list of TimerGroups, maintained by the TimerGroup
250-
/// ctor/dtor and is protected by the TimerLock lock.
242+
/// ctor/dtor and is protected by the timerLock lock.
251243
static TimerGroup *TimerGroupList = nullptr;
252244

253245
TimerGroup::TimerGroup(StringRef Name, StringRef Description,
@@ -264,7 +256,7 @@ TimerGroup::TimerGroup(StringRef Name, StringRef Description,
264256
}
265257

266258
TimerGroup::TimerGroup(StringRef Name, StringRef Description)
267-
: TimerGroup(Name, Description, mtg::TimerLock()) {}
259+
: TimerGroup(Name, Description, timerLock()) {}
268260

269261
TimerGroup::TimerGroup(StringRef Name, StringRef Description,
270262
const StringMap<TimeRecord> &Records)
@@ -283,15 +275,15 @@ TimerGroup::~TimerGroup() {
283275
removeTimer(*FirstTimer);
284276

285277
// Remove the group from the TimerGroupList.
286-
sys::SmartScopedLock<true> L(mtg::TimerLock());
278+
sys::SmartScopedLock<true> L(timerLock());
287279
*Prev = Next;
288280
if (Next)
289281
Next->Prev = Prev;
290282
}
291283

292284

293285
void TimerGroup::removeTimer(Timer &T) {
294-
sys::SmartScopedLock<true> L(mtg::TimerLock());
286+
sys::SmartScopedLock<true> L(timerLock());
295287

296288
// If the timer was started, move its data to TimersToPrint.
297289
if (T.hasTriggered())
@@ -314,7 +306,7 @@ void TimerGroup::removeTimer(Timer &T) {
314306
}
315307

316308
void TimerGroup::addTimer(Timer &T) {
317-
sys::SmartScopedLock<true> L(mtg::TimerLock());
309+
sys::SmartScopedLock<true> L(timerLock());
318310

319311
// Add the timer to our list.
320312
if (FirstTimer)
@@ -326,7 +318,7 @@ void TimerGroup::addTimer(Timer &T) {
326318

327319
void TimerGroup::PrintQueuedTimers(raw_ostream &OS) {
328320
// Perhaps sort the timers in descending order by amount of time taken.
329-
if (mtg::SortTimers())
321+
if (sortTimers())
330322
llvm::sort(TimersToPrint);
331323

332324
TimeRecord Total;
@@ -344,7 +336,7 @@ void TimerGroup::PrintQueuedTimers(raw_ostream &OS) {
344336
// If this is not an collection of ungrouped times, print the total time.
345337
// Ungrouped timers don't really make sense to add up. We still print the
346338
// TOTAL line to make the percentages make sense.
347-
if (this != &mtg::DefaultTimerGroup())
339+
if (this != &defaultTimerGroup())
348340
OS << format(" Total Execution Time: %5.4f seconds (%5.4f wall clock)\n",
349341
Total.getProcessTime(), Total.getWallTime());
350342
OS << '\n';
@@ -396,7 +388,7 @@ void TimerGroup::prepareToPrintList(bool ResetTime) {
396388
void TimerGroup::print(raw_ostream &OS, bool ResetAfterPrint) {
397389
{
398390
// After preparing the timers we can free the lock
399-
sys::SmartScopedLock<true> L(mtg::TimerLock());
391+
sys::SmartScopedLock<true> L(timerLock());
400392
prepareToPrintList(ResetAfterPrint);
401393
}
402394

@@ -406,20 +398,20 @@ void TimerGroup::print(raw_ostream &OS, bool ResetAfterPrint) {
406398
}
407399

408400
void TimerGroup::clear() {
409-
sys::SmartScopedLock<true> L(mtg::TimerLock());
401+
sys::SmartScopedLock<true> L(timerLock());
410402
for (Timer *T = FirstTimer; T; T = T->Next)
411403
T->clear();
412404
}
413405

414406
void TimerGroup::printAll(raw_ostream &OS) {
415-
sys::SmartScopedLock<true> L(mtg::TimerLock());
407+
sys::SmartScopedLock<true> L(timerLock());
416408

417409
for (TimerGroup *TG = TimerGroupList; TG; TG = TG->Next)
418410
TG->print(OS);
419411
}
420412

421413
void TimerGroup::clearAll() {
422-
sys::SmartScopedLock<true> L(mtg::TimerLock());
414+
sys::SmartScopedLock<true> L(timerLock());
423415
for (TimerGroup *TG = TimerGroupList; TG; TG = TG->Next)
424416
TG->clear();
425417
}
@@ -436,7 +428,7 @@ void TimerGroup::printJSONValue(raw_ostream &OS, const PrintRecord &R,
436428
}
437429

438430
const char *TimerGroup::printJSONValues(raw_ostream &OS, const char *delim) {
439-
sys::SmartScopedLock<true> L(mtg::TimerLock());
431+
sys::SmartScopedLock<true> L(timerLock());
440432

441433
prepareToPrintList(false);
442434
for (const PrintRecord &R : TimersToPrint) {
@@ -463,21 +455,12 @@ const char *TimerGroup::printJSONValues(raw_ostream &OS, const char *delim) {
463455
}
464456

465457
const char *TimerGroup::printAllJSONValues(raw_ostream &OS, const char *delim) {
466-
sys::SmartScopedLock<true> L(mtg::TimerLock());
458+
sys::SmartScopedLock<true> L(timerLock());
467459
for (TimerGroup *TG = TimerGroupList; TG; TG = TG->Next)
468460
delim = TG->printJSONValues(OS, delim);
469461
return delim;
470462
}
471463

472-
void TimerGroup::constructForStatistics() {
473-
mtg::LibSupportInfoOutputFilename();
474-
mtg::NamedGroupedTimers();
475-
}
476-
477-
std::unique_ptr<TimerGroup> TimerGroup::aquireDefaultGroup() {
478-
return std::unique_ptr<TimerGroup>(mtg::claimDefaultTimerGroup());
479-
}
480-
481464
//===----------------------------------------------------------------------===//
482465
// Timer Globals
483466
//
@@ -499,83 +482,59 @@ std::unique_ptr<TimerGroup> TimerGroup::aquireDefaultGroup() {
499482
class llvm::TimerGlobals {
500483
public:
501484
std::string LibSupportInfoOutputFilename;
502-
cl::opt<std::string, true> InfoOutputFilename;
503-
cl::opt<bool> TrackSpace;
504-
cl::opt<bool> SortTimers;
485+
cl::opt<std::string, true> InfoOutputFilename{
486+
"info-output-file", cl::value_desc("filename"),
487+
cl::desc("File to append -stats and -timer output to"), cl::Hidden,
488+
cl::location(LibSupportInfoOutputFilename)};
489+
cl::opt<bool> TrackSpace{
490+
"track-memory",
491+
cl::desc("Enable -time-passes memory tracking (this may be slow)"),
492+
cl::Hidden};
493+
cl::opt<bool> SortTimers{
494+
"sort-timers",
495+
cl::desc("In the report, sort the timers in each group in wall clock"
496+
" time order"),
497+
cl::init(true), cl::Hidden};
498+
499+
sys::SmartMutex<true> TimerLock;
500+
TimerGroup DefaultTimerGroup{"misc", "Miscellaneous Ungrouped Timers",
501+
TimerLock};
502+
SignpostEmitter Signposts;
505503

506-
private:
507504
// Order of these members and initialization below is important. For example
508-
// the DefaultTimerGroup uses the TimerLock. Most of these also depend on the
505+
// the defaultTimerGroup uses the timerLock. Most of these also depend on the
509506
// options above.
510507
std::once_flag InitDeferredFlag;
511-
std::unique_ptr<SignpostEmitter> SignpostsPtr;
512-
std::unique_ptr<sys::SmartMutex<true>> TimerLockPtr;
513-
std::unique_ptr<TimerGroup> DefaultTimerGroupPtr;
514-
std::unique_ptr<Name2PairMap> NamedGroupedTimersPtr;
508+
std::optional<Name2PairMap> NamedGroupedTimersPtr;
509+
515510
TimerGlobals &initDeferred() {
516-
std::call_once(InitDeferredFlag, [this]() {
517-
SignpostsPtr = std::make_unique<SignpostEmitter>();
518-
TimerLockPtr = std::make_unique<sys::SmartMutex<true>>();
519-
DefaultTimerGroupPtr.reset(new TimerGroup(
520-
"misc", "Miscellaneous Ungrouped Timers", *TimerLockPtr));
521-
NamedGroupedTimersPtr = std::make_unique<Name2PairMap>();
522-
});
511+
std::call_once(InitDeferredFlag,
512+
[this]() { NamedGroupedTimersPtr.emplace(); });
523513
return *this;
524514
}
525-
526-
public:
527-
SignpostEmitter &Signposts() { return *initDeferred().SignpostsPtr; }
528-
sys::SmartMutex<true> &TimerLock() { return *initDeferred().TimerLockPtr; }
529-
TimerGroup &DefaultTimerGroup() {
530-
return *initDeferred().DefaultTimerGroupPtr;
531-
}
532-
TimerGroup *claimDefaultTimerGroup() {
533-
return initDeferred().DefaultTimerGroupPtr.release();
534-
}
535-
Name2PairMap &NamedGroupedTimers() {
536-
return *initDeferred().NamedGroupedTimersPtr;
537-
}
538-
539-
public:
540-
TimerGlobals()
541-
: InfoOutputFilename(
542-
"info-output-file", cl::value_desc("filename"),
543-
cl::desc("File to append -stats and -timer output to"), cl::Hidden,
544-
cl::location(LibSupportInfoOutputFilename)),
545-
TrackSpace(
546-
"track-memory",
547-
cl::desc("Enable -time-passes memory tracking (this may be slow)"),
548-
cl::Hidden),
549-
SortTimers(
550-
"sort-timers",
551-
cl::desc(
552-
"In the report, sort the timers in each group in wall clock"
553-
" time order"),
554-
cl::init(true), cl::Hidden) {}
555515
};
556516

557517
static ManagedStatic<TimerGlobals> ManagedTimerGlobals;
558518

559-
static std::string &mtg::LibSupportInfoOutputFilename() {
519+
static std::string &libSupportInfoOutputFilename() {
560520
return ManagedTimerGlobals->LibSupportInfoOutputFilename;
561521
}
562-
static const std::string &mtg::InfoOutputFilename() {
563-
return ManagedTimerGlobals->InfoOutputFilename.getValue();
564-
}
565-
static bool mtg::TrackSpace() { return ManagedTimerGlobals->TrackSpace; }
566-
static bool mtg::SortTimers() { return ManagedTimerGlobals->SortTimers; }
567-
static SignpostEmitter &mtg::Signposts() {
568-
return ManagedTimerGlobals->Signposts();
522+
static bool trackSpace() { return ManagedTimerGlobals->TrackSpace; }
523+
static bool sortTimers() { return ManagedTimerGlobals->SortTimers; }
524+
static SignpostEmitter &signposts() { return ManagedTimerGlobals->Signposts; }
525+
static sys::SmartMutex<true> &timerLock() {
526+
return ManagedTimerGlobals->TimerLock;
569527
}
570-
static sys::SmartMutex<true> &mtg::TimerLock() {
571-
return ManagedTimerGlobals->TimerLock();
528+
static TimerGroup &defaultTimerGroup() {
529+
return ManagedTimerGlobals->DefaultTimerGroup;
572530
}
573-
static TimerGroup &mtg::DefaultTimerGroup() {
574-
return ManagedTimerGlobals->DefaultTimerGroup();
531+
static Name2PairMap &namedGroupedTimers() {
532+
return *ManagedTimerGlobals->initDeferred().NamedGroupedTimersPtr;
575533
}
576-
static TimerGroup *mtg::claimDefaultTimerGroup() {
577-
return ManagedTimerGlobals->claimDefaultTimerGroup();
578-
}
579-
static Name2PairMap &mtg::NamedGroupedTimers() {
580-
return ManagedTimerGlobals->NamedGroupedTimers();
534+
535+
void llvm::initTimerOptions() { *ManagedTimerGlobals; }
536+
void TimerGroup::constructForStatistics() {
537+
ManagedTimerGlobals->initDeferred();
581538
}
539+
540+
void *TimerGroup::acquireTimerGlobals() { return ManagedTimerGlobals.claim(); }

0 commit comments

Comments
 (0)