get_compile_definitions()
option(LLVM_FORCE_ENABLE_STATS "Enable statistics collection for builds that wouldn't normally enable it" OFF)
+
+check_symbol_exists(os_signpost_interval_begin "os/signpost.h" _signposts_available)
+if(_signposts_available)
+ set(LLVM_ENABLE_SUPPORT_XCODE_SIGNPOSTS "WITH_ASSERTS" CACHE STRING
+ "Enable support for Xcode signposts. Can be WITH_ASSERTS, FORCE_ON, FORCE_OFF")
+ string(TOUPPER "${LLVM_ENABLE_SUPPORT_XCODE_SIGNPOSTS}"
+ uppercase_LLVM_ENABLE_SUPPORT_XCODE_SIGNPOSTS)
+ if( uppercase_LLVM_ENABLE_SUPPORT_XCODE_SIGNPOSTS STREQUAL "WITH_ASSERTS" )
+ if( LLVM_ENABLE_ASSERTIONS )
+ set( LLVM_SUPPORT_XCODE_SIGNPOSTS 1 )
+ endif()
+ elseif( uppercase_LLVM_ENABLE_SUPPORT_XCODE_SIGNPOSTS STREQUAL "FORCE_ON" )
+ set( LLVM_SUPPORT_XCODE_SIGNPOSTS 1 )
+ elseif( uppercase_LLVM_ENABLE_SUPPORT_XCODE_SIGNPOSTS STREQUAL "FORCE_OFF" )
+ # We don't need to do anything special to turn off signposts.
+ elseif( NOT DEFINED LLVM_ENABLE_SUPPORT_XCODE_SIGNPOSTS )
+ # Treat LLVM_ENABLE_SUPPORT_XCODE_SIGNPOSTS like "FORCE_OFF" when it has not been
+ # defined.
+ else()
+ message(FATAL_ERROR "Unknown value for LLVM_ENABLE_SUPPORT_XCODE_SIGNPOSTS:"
+ " \"${LLVM_ENABLE_SUPPORT_XCODE_SIGNPOSTS}\"!")
+ endif()
+endif()
--- /dev/null
+//===-- llvm/Support/Signposts.h - Interval debug annotations ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file Some OS's provide profilers that allow applications to provide custom
+/// annotations to the profiler. For example, on Xcode 10 and later 'signposts'
+/// can be emitted by the application and these will be rendered to the Points
+/// of Interest track on the instruments timeline.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_SIGNPOSTS_H
+#define LLVM_SUPPORT_SIGNPOSTS_H
+
+namespace llvm {
+class SignpostEmitterImpl;
+class Timer;
+
+/// Manages the emission of signposts into the recording method supported by
+/// the OS.
+class SignpostEmitter {
+ SignpostEmitterImpl *Impl;
+
+public:
+ SignpostEmitter();
+ ~SignpostEmitter();
+
+ bool isEnabled() const;
+
+ /// Begin a signposted interval for the given timer.
+ void startTimerInterval(Timer *T);
+ /// End a signposted interval for the given timer.
+ void endTimerInterval(Timer *T);
+};
+
+} // end namespace llvm
+
+#endif // ifndef LLVM_SUPPORT_SIGNPOSTS_H
--- /dev/null
+//===-- 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
+}
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/Process.h"
+#include "llvm/Support/Signposts.h"
#include "llvm/Support/YAMLTraits.h"
#include "llvm/Support/raw_ostream.h"
#include <limits>
static ManagedStatic<sys::SmartMutex<true> > TimerLock;
+/// Allows llvm::Timer to emit signposts when supported.
+static ManagedStatic<SignpostEmitter> Signposts;
+
namespace {
static cl::opt<bool>
TrackSpace("track-memory", cl::desc("Enable -time-passes memory "
void Timer::startTimer() {
assert(!Running && "Cannot start a running timer");
Running = Triggered = true;
+ Signposts->startTimerInterval(this);
StartTime = TimeRecord::getCurrentTime(true);
}
Running = false;
Time += TimeRecord::getCurrentTime(false);
Time -= StartTime;
+ Signposts->endTimerInterval(this);
}
void Timer::clear() {