xref: /netbsd-src/external/apache2/llvm/dist/llvm/lib/Support/Signposts.cpp (revision 82d56013d7b633d116a93943de88e08335357a7c)
17330f729Sjoerg //===-- Signposts.cpp - Interval debug annotations ------------------------===//
27330f729Sjoerg //
37330f729Sjoerg //                     The LLVM Compiler Infrastructure
47330f729Sjoerg //
57330f729Sjoerg // This file is distributed under the University of Illinois Open Source
67330f729Sjoerg // License. See LICENSE.TXT for details.
77330f729Sjoerg //
87330f729Sjoerg //===----------------------------------------------------------------------===//
97330f729Sjoerg 
107330f729Sjoerg #include "llvm/Support/Signposts.h"
117330f729Sjoerg #include "llvm/Support/Timer.h"
127330f729Sjoerg 
137330f729Sjoerg #include "llvm/Config/config.h"
147330f729Sjoerg #if LLVM_SUPPORT_XCODE_SIGNPOSTS
157330f729Sjoerg #include "llvm/ADT/DenseMap.h"
16*82d56013Sjoerg #include "llvm/Support/Mutex.h"
17*82d56013Sjoerg #include <Availability.h>
187330f729Sjoerg #include <os/signpost.h>
197330f729Sjoerg #endif // if LLVM_SUPPORT_XCODE_SIGNPOSTS
207330f729Sjoerg 
217330f729Sjoerg using namespace llvm;
227330f729Sjoerg 
237330f729Sjoerg #if LLVM_SUPPORT_XCODE_SIGNPOSTS
24*82d56013Sjoerg #define SIGNPOSTS_AVAILABLE()                                                  \
25*82d56013Sjoerg   __builtin_available(macos 10.14, iOS 12, tvOS 12, watchOS 5, *)
267330f729Sjoerg namespace {
LogCreator()277330f729Sjoerg os_log_t *LogCreator() {
287330f729Sjoerg   os_log_t *X = new os_log_t;
297330f729Sjoerg   *X = os_log_create("org.llvm.signposts", OS_LOG_CATEGORY_POINTS_OF_INTEREST);
307330f729Sjoerg   return X;
317330f729Sjoerg }
32*82d56013Sjoerg struct LogDeleter {
operator ()__anon0a2b4bb10111::LogDeleter33*82d56013Sjoerg   void operator()(os_log_t *X) const {
347330f729Sjoerg     os_release(*X);
357330f729Sjoerg     delete X;
367330f729Sjoerg   }
37*82d56013Sjoerg };
387330f729Sjoerg } // end anonymous namespace
397330f729Sjoerg 
407330f729Sjoerg namespace llvm {
417330f729Sjoerg class SignpostEmitterImpl {
42*82d56013Sjoerg   using LogPtrTy = std::unique_ptr<os_log_t, LogDeleter>;
437330f729Sjoerg   using LogTy = LogPtrTy::element_type;
447330f729Sjoerg 
457330f729Sjoerg   LogPtrTy SignpostLog;
46*82d56013Sjoerg   DenseMap<const void *, os_signpost_id_t> Signposts;
47*82d56013Sjoerg   sys::SmartMutex<true> Mutex;
487330f729Sjoerg 
getLogger() const497330f729Sjoerg   LogTy &getLogger() const { return *SignpostLog; }
getSignpostForObject(const void * O)50*82d56013Sjoerg   os_signpost_id_t getSignpostForObject(const void *O) {
51*82d56013Sjoerg     sys::SmartScopedLock<true> Lock(Mutex);
52*82d56013Sjoerg     const auto &I = Signposts.find(O);
537330f729Sjoerg     if (I != Signposts.end())
547330f729Sjoerg       return I->second;
55*82d56013Sjoerg     os_signpost_id_t ID = {};
56*82d56013Sjoerg     if (SIGNPOSTS_AVAILABLE()) {
57*82d56013Sjoerg       ID = os_signpost_id_make_with_pointer(getLogger(), O);
58*82d56013Sjoerg     }
59*82d56013Sjoerg     const auto &Inserted = Signposts.insert(std::make_pair(O, ID));
607330f729Sjoerg     return Inserted.first->second;
617330f729Sjoerg   }
627330f729Sjoerg 
637330f729Sjoerg public:
SignpostEmitterImpl()64*82d56013Sjoerg   SignpostEmitterImpl() : SignpostLog(LogCreator()) {}
657330f729Sjoerg 
isEnabled() const66*82d56013Sjoerg   bool isEnabled() const {
67*82d56013Sjoerg     if (SIGNPOSTS_AVAILABLE())
68*82d56013Sjoerg       return os_signpost_enabled(*SignpostLog);
69*82d56013Sjoerg     return false;
70*82d56013Sjoerg   }
717330f729Sjoerg 
startInterval(const void * O,llvm::StringRef Name)72*82d56013Sjoerg   void startInterval(const void *O, llvm::StringRef Name) {
737330f729Sjoerg     if (isEnabled()) {
74*82d56013Sjoerg       if (SIGNPOSTS_AVAILABLE()) {
75*82d56013Sjoerg         // Both strings used here are required to be constant literal strings.
76*82d56013Sjoerg         os_signpost_interval_begin(getLogger(), getSignpostForObject(O),
77*82d56013Sjoerg                                    "LLVM Timers", "Begin %s", Name.data());
78*82d56013Sjoerg       }
797330f729Sjoerg     }
807330f729Sjoerg   }
817330f729Sjoerg 
endInterval(const void * O,llvm::StringRef Name)82*82d56013Sjoerg   void endInterval(const void *O, llvm::StringRef Name) {
837330f729Sjoerg     if (isEnabled()) {
84*82d56013Sjoerg       if (SIGNPOSTS_AVAILABLE()) {
85*82d56013Sjoerg         // Both strings used here are required to be constant literal strings.
86*82d56013Sjoerg         os_signpost_interval_end(getLogger(), getSignpostForObject(O),
87*82d56013Sjoerg                                  "LLVM Timers", "End %s", Name.data());
88*82d56013Sjoerg       }
897330f729Sjoerg     }
907330f729Sjoerg   }
917330f729Sjoerg };
927330f729Sjoerg } // end namespace llvm
93*82d56013Sjoerg #else
94*82d56013Sjoerg /// Definition necessary for use of std::unique_ptr in SignpostEmitter::Impl.
95*82d56013Sjoerg class llvm::SignpostEmitterImpl {};
967330f729Sjoerg #endif // if LLVM_SUPPORT_XCODE_SIGNPOSTS
977330f729Sjoerg 
987330f729Sjoerg #if LLVM_SUPPORT_XCODE_SIGNPOSTS
997330f729Sjoerg #define HAVE_ANY_SIGNPOST_IMPL 1
1007330f729Sjoerg #else
1017330f729Sjoerg #define HAVE_ANY_SIGNPOST_IMPL 0
1027330f729Sjoerg #endif
1037330f729Sjoerg 
SignpostEmitter()1047330f729Sjoerg SignpostEmitter::SignpostEmitter() {
1057330f729Sjoerg #if HAVE_ANY_SIGNPOST_IMPL
106*82d56013Sjoerg   Impl = std::make_unique<SignpostEmitterImpl>();
1077330f729Sjoerg #endif // if !HAVE_ANY_SIGNPOST_IMPL
1087330f729Sjoerg }
1097330f729Sjoerg 
110*82d56013Sjoerg SignpostEmitter::~SignpostEmitter() = default;
1117330f729Sjoerg 
isEnabled() const1127330f729Sjoerg bool SignpostEmitter::isEnabled() const {
1137330f729Sjoerg #if HAVE_ANY_SIGNPOST_IMPL
1147330f729Sjoerg   return Impl->isEnabled();
1157330f729Sjoerg #else
1167330f729Sjoerg   return false;
1177330f729Sjoerg #endif // if !HAVE_ANY_SIGNPOST_IMPL
1187330f729Sjoerg }
1197330f729Sjoerg 
startInterval(const void * O,StringRef Name)120*82d56013Sjoerg void SignpostEmitter::startInterval(const void *O, StringRef Name) {
1217330f729Sjoerg #if HAVE_ANY_SIGNPOST_IMPL
1227330f729Sjoerg   if (Impl == nullptr)
1237330f729Sjoerg     return;
124*82d56013Sjoerg   return Impl->startInterval(O, Name);
1257330f729Sjoerg #endif // if !HAVE_ANY_SIGNPOST_IMPL
1267330f729Sjoerg }
1277330f729Sjoerg 
endInterval(const void * O,StringRef Name)128*82d56013Sjoerg void SignpostEmitter::endInterval(const void *O, StringRef Name) {
1297330f729Sjoerg #if HAVE_ANY_SIGNPOST_IMPL
1307330f729Sjoerg   if (Impl == nullptr)
1317330f729Sjoerg     return;
132*82d56013Sjoerg   Impl->endInterval(O, Name);
1337330f729Sjoerg #endif // if !HAVE_ANY_SIGNPOST_IMPL
1347330f729Sjoerg }
135