1e1414d17SDaniel Sanders //===-- Signposts.cpp - Interval debug annotations ------------------------===// 2e1414d17SDaniel Sanders // 3e1414d17SDaniel Sanders // The LLVM Compiler Infrastructure 4e1414d17SDaniel Sanders // 5e1414d17SDaniel Sanders // This file is distributed under the University of Illinois Open Source 6e1414d17SDaniel Sanders // License. See LICENSE.TXT for details. 7e1414d17SDaniel Sanders // 8e1414d17SDaniel Sanders //===----------------------------------------------------------------------===// 9e1414d17SDaniel Sanders 10e1414d17SDaniel Sanders #include "llvm/Support/Signposts.h" 11e1414d17SDaniel Sanders #include "llvm/Support/Timer.h" 12e1414d17SDaniel Sanders 13e1414d17SDaniel Sanders #include "llvm/Config/config.h" 14e1414d17SDaniel Sanders #if LLVM_SUPPORT_XCODE_SIGNPOSTS 15e1414d17SDaniel Sanders #include "llvm/ADT/DenseMap.h" 16e1414d17SDaniel Sanders #include <os/signpost.h> 17e1414d17SDaniel Sanders #endif // if LLVM_SUPPORT_XCODE_SIGNPOSTS 18e1414d17SDaniel Sanders 19e1414d17SDaniel Sanders using namespace llvm; 20e1414d17SDaniel Sanders 21e1414d17SDaniel Sanders #if LLVM_SUPPORT_XCODE_SIGNPOSTS 22e1414d17SDaniel Sanders namespace { 23e1414d17SDaniel Sanders os_log_t *LogCreator() { 24e1414d17SDaniel Sanders os_log_t *X = new os_log_t; 25e1414d17SDaniel Sanders *X = os_log_create("org.llvm.signposts", OS_LOG_CATEGORY_POINTS_OF_INTEREST); 26e1414d17SDaniel Sanders return X; 27e1414d17SDaniel Sanders } 28e1414d17SDaniel Sanders void LogDeleter(os_log_t *X) { 29e1414d17SDaniel Sanders os_release(*X); 30e1414d17SDaniel Sanders delete X; 31e1414d17SDaniel Sanders } 32e1414d17SDaniel Sanders } // end anonymous namespace 33e1414d17SDaniel Sanders 34e1414d17SDaniel Sanders namespace llvm { 35e1414d17SDaniel Sanders class SignpostEmitterImpl { 36*b37de2afSJonas Devlieghere using LogPtrTy = std::unique_ptr<os_log_t, std::function<void(os_log_t *)>>; 37e1414d17SDaniel Sanders using LogTy = LogPtrTy::element_type; 38e1414d17SDaniel Sanders 39e1414d17SDaniel Sanders LogPtrTy SignpostLog; 40*b37de2afSJonas Devlieghere DenseMap<const void *, os_signpost_id_t> Signposts; 41e1414d17SDaniel Sanders 42e1414d17SDaniel Sanders LogTy &getLogger() const { return *SignpostLog; } 43*b37de2afSJonas Devlieghere os_signpost_id_t getSignpostForObject(const void *O) { 44*b37de2afSJonas Devlieghere const auto &I = Signposts.find(O); 45e1414d17SDaniel Sanders if (I != Signposts.end()) 46e1414d17SDaniel Sanders return I->second; 47e1414d17SDaniel Sanders 48e1414d17SDaniel Sanders const auto &Inserted = Signposts.insert( 49*b37de2afSJonas Devlieghere std::make_pair(O, os_signpost_id_make_with_pointer(getLogger(), O))); 50e1414d17SDaniel Sanders return Inserted.first->second; 51e1414d17SDaniel Sanders } 52e1414d17SDaniel Sanders 53e1414d17SDaniel Sanders public: 54e1414d17SDaniel Sanders SignpostEmitterImpl() : SignpostLog(LogCreator(), LogDeleter), Signposts() {} 55e1414d17SDaniel Sanders 56e1414d17SDaniel Sanders bool isEnabled() const { return os_signpost_enabled(*SignpostLog); } 57e1414d17SDaniel Sanders 58*b37de2afSJonas Devlieghere void startInterval(const void *O, llvm::StringRef Name) { 59e1414d17SDaniel Sanders if (isEnabled()) { 60*b37de2afSJonas Devlieghere // Both strings used here are required to be constant literal strings. 61*b37de2afSJonas Devlieghere os_signpost_interval_begin(getLogger(), getSignpostForObject(O), 62*b37de2afSJonas Devlieghere "LLVM Timers", "Begin %s", Name.data()); 63e1414d17SDaniel Sanders } 64e1414d17SDaniel Sanders } 65e1414d17SDaniel Sanders 66*b37de2afSJonas Devlieghere void endInterval(const void *O, llvm::StringRef Name) { 67e1414d17SDaniel Sanders if (isEnabled()) { 68*b37de2afSJonas Devlieghere // Both strings used here are required to be constant literal strings. 69*b37de2afSJonas Devlieghere os_signpost_interval_end(getLogger(), getSignpostForObject(O), 70*b37de2afSJonas Devlieghere "LLVM Timers", "End %s", Name.data()); 71e1414d17SDaniel Sanders } 72e1414d17SDaniel Sanders } 73e1414d17SDaniel Sanders }; 74e1414d17SDaniel Sanders } // end namespace llvm 75e1414d17SDaniel Sanders #endif // if LLVM_SUPPORT_XCODE_SIGNPOSTS 76e1414d17SDaniel Sanders 77e1414d17SDaniel Sanders #if LLVM_SUPPORT_XCODE_SIGNPOSTS 78e1414d17SDaniel Sanders #define HAVE_ANY_SIGNPOST_IMPL 1 790096d193SSven van Haastregt #else 800096d193SSven van Haastregt #define HAVE_ANY_SIGNPOST_IMPL 0 81e1414d17SDaniel Sanders #endif 82e1414d17SDaniel Sanders 83e1414d17SDaniel Sanders SignpostEmitter::SignpostEmitter() { 84e1414d17SDaniel Sanders #if HAVE_ANY_SIGNPOST_IMPL 85e1414d17SDaniel Sanders Impl = new SignpostEmitterImpl(); 86e1414d17SDaniel Sanders #else // if HAVE_ANY_SIGNPOST_IMPL 87e1414d17SDaniel Sanders Impl = nullptr; 88e1414d17SDaniel Sanders #endif // if !HAVE_ANY_SIGNPOST_IMPL 89e1414d17SDaniel Sanders } 90e1414d17SDaniel Sanders 91e1414d17SDaniel Sanders SignpostEmitter::~SignpostEmitter() { 92e1414d17SDaniel Sanders #if HAVE_ANY_SIGNPOST_IMPL 93e1414d17SDaniel Sanders delete Impl; 94e1414d17SDaniel Sanders #endif // if HAVE_ANY_SIGNPOST_IMPL 95e1414d17SDaniel Sanders } 96e1414d17SDaniel Sanders 97e1414d17SDaniel Sanders bool SignpostEmitter::isEnabled() const { 98e1414d17SDaniel Sanders #if HAVE_ANY_SIGNPOST_IMPL 99e1414d17SDaniel Sanders return Impl->isEnabled(); 100e1414d17SDaniel Sanders #else 101e1414d17SDaniel Sanders return false; 102e1414d17SDaniel Sanders #endif // if !HAVE_ANY_SIGNPOST_IMPL 103e1414d17SDaniel Sanders } 104e1414d17SDaniel Sanders 105*b37de2afSJonas Devlieghere void SignpostEmitter::startInterval(const void *O, StringRef Name) { 106e1414d17SDaniel Sanders #if HAVE_ANY_SIGNPOST_IMPL 107e1414d17SDaniel Sanders if (Impl == nullptr) 108e1414d17SDaniel Sanders return; 109*b37de2afSJonas Devlieghere return Impl->startInterval(O, Name); 110e1414d17SDaniel Sanders #endif // if !HAVE_ANY_SIGNPOST_IMPL 111e1414d17SDaniel Sanders } 112e1414d17SDaniel Sanders 113*b37de2afSJonas Devlieghere void SignpostEmitter::endInterval(const void *O, StringRef Name) { 114e1414d17SDaniel Sanders #if HAVE_ANY_SIGNPOST_IMPL 115e1414d17SDaniel Sanders if (Impl == nullptr) 116e1414d17SDaniel Sanders return; 117*b37de2afSJonas Devlieghere Impl->endInterval(O, Name); 118e1414d17SDaniel Sanders #endif // if !HAVE_ANY_SIGNPOST_IMPL 119e1414d17SDaniel Sanders } 120