diff options
Diffstat (limited to 'llvm/lib/Support/Signposts.cpp')
| -rw-r--r-- | llvm/lib/Support/Signposts.cpp | 121 | 
1 files changed, 121 insertions, 0 deletions
| diff --git a/llvm/lib/Support/Signposts.cpp b/llvm/lib/Support/Signposts.cpp new file mode 100644 index 000000000000..aa159e1da2ae --- /dev/null +++ b/llvm/lib/Support/Signposts.cpp @@ -0,0 +1,121 @@ +//===-- 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 +#else +#define HAVE_ANY_SIGNPOST_IMPL 0 +#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 +} | 
