diff options
Diffstat (limited to 'llvm/lib/Support/Signposts.cpp')
-rw-r--r-- | llvm/lib/Support/Signposts.cpp | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/llvm/lib/Support/Signposts.cpp b/llvm/lib/Support/Signposts.cpp new file mode 100644 index 00000000000..d456f41d2fa --- /dev/null +++ b/llvm/lib/Support/Signposts.cpp @@ -0,0 +1,119 @@ +//===-- Signposts.cpp - Interval debug annotations ------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/Signposts.h" +#include "llvm/Support/Timer.h" + +#include "llvm/Config/config.h" +#if LLVM_SUPPORT_XCODE_SIGNPOSTS +#include "llvm/ADT/DenseMap.h" +#include <os/signpost.h> +#endif // if LLVM_SUPPORT_XCODE_SIGNPOSTS + +using namespace llvm; + +#if LLVM_SUPPORT_XCODE_SIGNPOSTS +namespace { +os_log_t *LogCreator() { + os_log_t *X = new os_log_t; + *X = os_log_create("org.llvm.signposts", OS_LOG_CATEGORY_POINTS_OF_INTEREST); + return X; +} +void LogDeleter(os_log_t *X) { + os_release(*X); + delete X; +} +} // end anonymous namespace + +namespace llvm { +class SignpostEmitterImpl { + using LogPtrTy = + std::unique_ptr<os_log_t, std::function<void(os_log_t *)>>; + using LogTy = LogPtrTy::element_type; + + LogPtrTy SignpostLog; + DenseMap<const Timer *, os_signpost_id_t> Signposts; + + LogTy &getLogger() const { return *SignpostLog; } + os_signpost_id_t getSignpostForTimer(const Timer *T) { + const auto &I = Signposts.find(T); + if (I != Signposts.end()) + return I->second; + + const auto &Inserted = Signposts.insert( + std::make_pair(T, os_signpost_id_make_with_pointer(getLogger(), T))); + return Inserted.first->second; + } + +public: + SignpostEmitterImpl() : SignpostLog(LogCreator(), LogDeleter), Signposts() {} + + bool isEnabled() const { return os_signpost_enabled(*SignpostLog); } + + void startTimerInterval(Timer *T) { + if (isEnabled()) { + // Both strings used here are required to be constant literal strings + os_signpost_interval_begin(getLogger(), getSignpostForTimer(T), + "Pass Timers", "Begin %s", + T->getName().c_str()); + } + } + + void endTimerInterval(Timer *T) { + if (isEnabled()) { + // Both strings used here are required to be constant literal strings + os_signpost_interval_end(getLogger(), getSignpostForTimer(T), + "Pass Timers", "End %s", T->getName().c_str()); + } + } +}; +} // end namespace llvm +#endif // if LLVM_SUPPORT_XCODE_SIGNPOSTS + +#if LLVM_SUPPORT_XCODE_SIGNPOSTS +#define HAVE_ANY_SIGNPOST_IMPL 1 +#endif + +SignpostEmitter::SignpostEmitter() { +#if HAVE_ANY_SIGNPOST_IMPL + Impl = new SignpostEmitterImpl(); +#else // if HAVE_ANY_SIGNPOST_IMPL + Impl = nullptr; +#endif // if !HAVE_ANY_SIGNPOST_IMPL +} + +SignpostEmitter::~SignpostEmitter() { +#if HAVE_ANY_SIGNPOST_IMPL + delete Impl; +#endif // if HAVE_ANY_SIGNPOST_IMPL +} + +bool SignpostEmitter::isEnabled() const { +#if HAVE_ANY_SIGNPOST_IMPL + return Impl->isEnabled(); +#else + return false; +#endif // if !HAVE_ANY_SIGNPOST_IMPL +} + +void SignpostEmitter::startTimerInterval(Timer *T) { +#if HAVE_ANY_SIGNPOST_IMPL + if (Impl == nullptr) + return; + return Impl->startTimerInterval(T); +#endif // if !HAVE_ANY_SIGNPOST_IMPL +} + +void SignpostEmitter::endTimerInterval(Timer *T) { +#if HAVE_ANY_SIGNPOST_IMPL + if (Impl == nullptr) + return; + Impl->endTimerInterval(T); +#endif // if !HAVE_ANY_SIGNPOST_IMPL +} |