Skip to content

[Support] Reduce globaal variable overhead after #121663 #122429

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clang/tools/driver/driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ int clang_main(int Argc, char **Argv, const llvm::ToolContext &ToolContext) {
if (!UseNewCC1Process && IsCrash) {
// When crashing in -fintegrated-cc1 mode, bury the timer pointers, because
// the internal linked list might point to already released stack frames.
llvm::BuryPointer(llvm::TimerGroup::aquireDefaultGroup());
llvm::BuryPointer(llvm::TimerGroup::acquireTimerGlobals());
} else {
// If any timers were active but haven't been destroyed yet, print their
// results now. This happens in -disable-free mode.
Expand Down
6 changes: 3 additions & 3 deletions llvm/include/llvm/Support/Timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,9 +240,9 @@ class TimerGroup {
/// global constructors and destructors.
static void constructForStatistics();

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

private:
friend class Timer;
Expand Down
183 changes: 71 additions & 112 deletions llvm/lib/Support/Timer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "llvm/Support/YAMLTraits.h"
#include "llvm/Support/raw_ostream.h"
#include <limits>
#include <optional>

#if HAVE_UNISTD_H
#include <unistd.h>
Expand All @@ -39,7 +40,7 @@
using namespace llvm;

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

namespace mtg {
static std::string &LibSupportInfoOutputFilename();
static const std::string &InfoOutputFilename();
static bool TrackSpace();
static bool SortTimers();
static SignpostEmitter &Signposts();
static sys::SmartMutex<true> &TimerLock();
static TimerGroup &DefaultTimerGroup();
static TimerGroup *claimDefaultTimerGroup();
static Name2PairMap &NamedGroupedTimers();
} // namespace mtg
static std::string &libSupportInfoOutputFilename();
static bool trackSpace();
static bool sortTimers();
static SignpostEmitter &signposts();
static sys::SmartMutex<true> &timerLock();
static TimerGroup &defaultTimerGroup();
static Name2PairMap &namedGroupedTimers();

//===----------------------------------------------------------------------===//
//
//===----------------------------------------------------------------------===//
void llvm::initTimerOptions() {
mtg::TrackSpace();
mtg::InfoOutputFilename();
mtg::SortTimers();
}

std::unique_ptr<raw_ostream> llvm::CreateInfoOutputFile() {
const std::string &OutputFilename = mtg::LibSupportInfoOutputFilename();
const std::string &OutputFilename = libSupportInfoOutputFilename();
if (OutputFilename.empty())
return std::make_unique<raw_fd_ostream>(2, false); // stderr.
if (OutputFilename == "-")
Expand All @@ -97,7 +89,7 @@ std::unique_ptr<raw_ostream> llvm::CreateInfoOutputFile() {
//===----------------------------------------------------------------------===//

void Timer::init(StringRef TimerName, StringRef TimerDescription) {
init(TimerName, TimerDescription, mtg::DefaultTimerGroup());
init(TimerName, TimerDescription, defaultTimerGroup());
}

void Timer::init(StringRef TimerName, StringRef TimerDescription,
Expand All @@ -116,7 +108,7 @@ Timer::~Timer() {
}

static inline size_t getMemUsage() {
if (!mtg::TrackSpace())
if (!trackSpace())
return 0;
return sys::Process::GetMallocUsage();
}
Expand Down Expand Up @@ -157,7 +149,7 @@ TimeRecord TimeRecord::getCurrentTime(bool Start) {
void Timer::startTimer() {
assert(!Running && "Cannot start a running timer");
Running = Triggered = true;
mtg::Signposts().startInterval(this, getName());
signposts().startInterval(this, getName());
StartTime = TimeRecord::getCurrentTime(true);
}

Expand All @@ -166,7 +158,7 @@ void Timer::stopTimer() {
Running = false;
Time += TimeRecord::getCurrentTime(false);
Time -= StartTime;
mtg::Signposts().endInterval(this, getName());
signposts().endInterval(this, getName());
}

void Timer::clear() {
Expand Down Expand Up @@ -218,7 +210,7 @@ class Name2PairMap {

Timer &get(StringRef Name, StringRef Description, StringRef GroupName,
StringRef GroupDescription) {
sys::SmartScopedLock<true> L(mtg::TimerLock());
sys::SmartScopedLock<true> L(timerLock());

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

Expand All @@ -237,17 +229,17 @@ class Name2PairMap {
NamedRegionTimer::NamedRegionTimer(StringRef Name, StringRef Description,
StringRef GroupName,
StringRef GroupDescription, bool Enabled)
: TimeRegion(!Enabled ? nullptr
: &mtg::NamedGroupedTimers().get(Name, Description,
GroupName,
GroupDescription)) {}
: TimeRegion(!Enabled
? nullptr
: &namedGroupedTimers().get(Name, Description, GroupName,
GroupDescription)) {}

//===----------------------------------------------------------------------===//
// TimerGroup Implementation
//===----------------------------------------------------------------------===//

/// This is the global list of TimerGroups, maintained by the TimerGroup
/// ctor/dtor and is protected by the TimerLock lock.
/// ctor/dtor and is protected by the timerLock lock.
static TimerGroup *TimerGroupList = nullptr;

TimerGroup::TimerGroup(StringRef Name, StringRef Description,
Expand All @@ -264,7 +256,7 @@ TimerGroup::TimerGroup(StringRef Name, StringRef Description,
}

TimerGroup::TimerGroup(StringRef Name, StringRef Description)
: TimerGroup(Name, Description, mtg::TimerLock()) {}
: TimerGroup(Name, Description, timerLock()) {}

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

// Remove the group from the TimerGroupList.
sys::SmartScopedLock<true> L(mtg::TimerLock());
sys::SmartScopedLock<true> L(timerLock());
*Prev = Next;
if (Next)
Next->Prev = Prev;
}


void TimerGroup::removeTimer(Timer &T) {
sys::SmartScopedLock<true> L(mtg::TimerLock());
sys::SmartScopedLock<true> L(timerLock());

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

void TimerGroup::addTimer(Timer &T) {
sys::SmartScopedLock<true> L(mtg::TimerLock());
sys::SmartScopedLock<true> L(timerLock());

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

void TimerGroup::PrintQueuedTimers(raw_ostream &OS) {
// Perhaps sort the timers in descending order by amount of time taken.
if (mtg::SortTimers())
if (sortTimers())
llvm::sort(TimersToPrint);

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

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

void TimerGroup::clear() {
sys::SmartScopedLock<true> L(mtg::TimerLock());
sys::SmartScopedLock<true> L(timerLock());
for (Timer *T = FirstTimer; T; T = T->Next)
T->clear();
}

void TimerGroup::printAll(raw_ostream &OS) {
sys::SmartScopedLock<true> L(mtg::TimerLock());
sys::SmartScopedLock<true> L(timerLock());

for (TimerGroup *TG = TimerGroupList; TG; TG = TG->Next)
TG->print(OS);
}

void TimerGroup::clearAll() {
sys::SmartScopedLock<true> L(mtg::TimerLock());
sys::SmartScopedLock<true> L(timerLock());
for (TimerGroup *TG = TimerGroupList; TG; TG = TG->Next)
TG->clear();
}
Expand All @@ -436,7 +428,7 @@ void TimerGroup::printJSONValue(raw_ostream &OS, const PrintRecord &R,
}

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

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

const char *TimerGroup::printAllJSONValues(raw_ostream &OS, const char *delim) {
sys::SmartScopedLock<true> L(mtg::TimerLock());
sys::SmartScopedLock<true> L(timerLock());
for (TimerGroup *TG = TimerGroupList; TG; TG = TG->Next)
delim = TG->printJSONValues(OS, delim);
return delim;
}

void TimerGroup::constructForStatistics() {
mtg::LibSupportInfoOutputFilename();
mtg::NamedGroupedTimers();
}

std::unique_ptr<TimerGroup> TimerGroup::aquireDefaultGroup() {
return std::unique_ptr<TimerGroup>(mtg::claimDefaultTimerGroup());
}

//===----------------------------------------------------------------------===//
// Timer Globals
//
Expand All @@ -499,83 +482,59 @@ std::unique_ptr<TimerGroup> TimerGroup::aquireDefaultGroup() {
class llvm::TimerGlobals {
public:
std::string LibSupportInfoOutputFilename;
cl::opt<std::string, true> InfoOutputFilename;
cl::opt<bool> TrackSpace;
cl::opt<bool> SortTimers;
cl::opt<std::string, true> InfoOutputFilename{
"info-output-file", cl::value_desc("filename"),
cl::desc("File to append -stats and -timer output to"), cl::Hidden,
cl::location(LibSupportInfoOutputFilename)};
cl::opt<bool> TrackSpace{
"track-memory",
cl::desc("Enable -time-passes memory tracking (this may be slow)"),
cl::Hidden};
cl::opt<bool> SortTimers{
"sort-timers",
cl::desc("In the report, sort the timers in each group in wall clock"
" time order"),
cl::init(true), cl::Hidden};

sys::SmartMutex<true> TimerLock;
TimerGroup DefaultTimerGroup{"misc", "Miscellaneous Ungrouped Timers",
TimerLock};
SignpostEmitter Signposts;

private:
// Order of these members and initialization below is important. For example
// the DefaultTimerGroup uses the TimerLock. Most of these also depend on the
// the defaultTimerGroup uses the timerLock. Most of these also depend on the
// options above.
std::once_flag InitDeferredFlag;
std::unique_ptr<SignpostEmitter> SignpostsPtr;
std::unique_ptr<sys::SmartMutex<true>> TimerLockPtr;
std::unique_ptr<TimerGroup> DefaultTimerGroupPtr;
std::unique_ptr<Name2PairMap> NamedGroupedTimersPtr;
std::optional<Name2PairMap> NamedGroupedTimersPtr;

TimerGlobals &initDeferred() {
std::call_once(InitDeferredFlag, [this]() {
SignpostsPtr = std::make_unique<SignpostEmitter>();
TimerLockPtr = std::make_unique<sys::SmartMutex<true>>();
DefaultTimerGroupPtr.reset(new TimerGroup(
"misc", "Miscellaneous Ungrouped Timers", *TimerLockPtr));
NamedGroupedTimersPtr = std::make_unique<Name2PairMap>();
});
std::call_once(InitDeferredFlag,
[this]() { NamedGroupedTimersPtr.emplace(); });
return *this;
}

public:
SignpostEmitter &Signposts() { return *initDeferred().SignpostsPtr; }
sys::SmartMutex<true> &TimerLock() { return *initDeferred().TimerLockPtr; }
TimerGroup &DefaultTimerGroup() {
return *initDeferred().DefaultTimerGroupPtr;
}
TimerGroup *claimDefaultTimerGroup() {
return initDeferred().DefaultTimerGroupPtr.release();
}
Name2PairMap &NamedGroupedTimers() {
return *initDeferred().NamedGroupedTimersPtr;
}

public:
TimerGlobals()
: InfoOutputFilename(
"info-output-file", cl::value_desc("filename"),
cl::desc("File to append -stats and -timer output to"), cl::Hidden,
cl::location(LibSupportInfoOutputFilename)),
TrackSpace(
"track-memory",
cl::desc("Enable -time-passes memory tracking (this may be slow)"),
cl::Hidden),
SortTimers(
"sort-timers",
cl::desc(
"In the report, sort the timers in each group in wall clock"
" time order"),
cl::init(true), cl::Hidden) {}
};

static ManagedStatic<TimerGlobals> ManagedTimerGlobals;

static std::string &mtg::LibSupportInfoOutputFilename() {
static std::string &libSupportInfoOutputFilename() {
return ManagedTimerGlobals->LibSupportInfoOutputFilename;
}
static const std::string &mtg::InfoOutputFilename() {
return ManagedTimerGlobals->InfoOutputFilename.getValue();
}
static bool mtg::TrackSpace() { return ManagedTimerGlobals->TrackSpace; }
static bool mtg::SortTimers() { return ManagedTimerGlobals->SortTimers; }
static SignpostEmitter &mtg::Signposts() {
return ManagedTimerGlobals->Signposts();
static bool trackSpace() { return ManagedTimerGlobals->TrackSpace; }
static bool sortTimers() { return ManagedTimerGlobals->SortTimers; }
static SignpostEmitter &signposts() { return ManagedTimerGlobals->Signposts; }
static sys::SmartMutex<true> &timerLock() {
return ManagedTimerGlobals->TimerLock;
}
static sys::SmartMutex<true> &mtg::TimerLock() {
return ManagedTimerGlobals->TimerLock();
static TimerGroup &defaultTimerGroup() {
return ManagedTimerGlobals->DefaultTimerGroup;
}
static TimerGroup &mtg::DefaultTimerGroup() {
return ManagedTimerGlobals->DefaultTimerGroup();
static Name2PairMap &namedGroupedTimers() {
return *ManagedTimerGlobals->initDeferred().NamedGroupedTimersPtr;
}
static TimerGroup *mtg::claimDefaultTimerGroup() {
return ManagedTimerGlobals->claimDefaultTimerGroup();
}
static Name2PairMap &mtg::NamedGroupedTimers() {
return ManagedTimerGlobals->NamedGroupedTimers();

void llvm::initTimerOptions() { *ManagedTimerGlobals; }
void TimerGroup::constructForStatistics() {
ManagedTimerGlobals->initDeferred();
}

void *TimerGroup::acquireTimerGlobals() { return ManagedTimerGlobals.claim(); }
Loading