//===-- 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 #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>; using LogTy = LogPtrTy::element_type; LogPtrTy SignpostLog; DenseMap 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 }