1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 19:12:56 +02:00

Allow signposts to take advantage of deferred string substitution

One nice feature of the os_signpost API is that format string
substitutions happen in the consumer, not the logging
application. LLVM's current Signpost class doesn't take advantage of
this though and instead always uses a static "Begin/End %s" format
string.

This patch uses variadic macros to allow the API to be used as
intended. Unfortunately, the primary use-case I had in mind (the
LLDB_SCOPED_TIMER() macro) does not get much better from this, because
__PRETTY_FUNCTION__ is *not* a macro, but a static string, so
signposts created by LLDB_SCOPED_TIMER() still use a static "%s"
format string. At least LLDB_SCOPED_TIMERF() works as intended.

This reapplies the previsously reverted patch with support for
platforms where signposts are unavailable.

Differential Revision: https://reviews.llvm.org/D103575
This commit is contained in:
Adrian Prantl 2021-06-11 15:18:25 -07:00
parent 5ed934f9e8
commit 5f69f29b5c
3 changed files with 48 additions and 13 deletions

View File

@ -18,8 +18,17 @@
#define LLVM_SUPPORT_SIGNPOSTS_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Config/config.h"
#include <memory>
#if LLVM_SUPPORT_XCODE_SIGNPOSTS
#include <Availability.h>
#include <os/signpost.h>
#endif
#define SIGNPOSTS_AVAILABLE() \
__builtin_available(macos 10.14, iOS 12, tvOS 12, watchOS 5, *)
namespace llvm {
class SignpostEmitterImpl;
@ -36,8 +45,33 @@ public:
/// Begin a signposted interval for a given object.
void startInterval(const void *O, StringRef Name);
#if LLVM_SUPPORT_XCODE_SIGNPOSTS
os_log_t &getLogger() const;
os_signpost_id_t getSignpostForObject(const void *O);
#endif
/// A macro to take advantage of the special format string handling
/// in the os_signpost API. The format string substitution is
/// deferred to the log consumer and done outside of the
/// application.
#if LLVM_SUPPORT_XCODE_SIGNPOSTS
#define SIGNPOST_EMITTER_START_INTERVAL(SIGNPOST_EMITTER, O, ...) \
do { \
if ((SIGNPOST_EMITTER).isEnabled()) \
if (SIGNPOSTS_AVAILABLE()) \
os_signpost_interval_begin((SIGNPOST_EMITTER).getLogger(), \
(SIGNPOST_EMITTER).getSignpostForObject(O), \
"LLVM Timers", __VA_ARGS__); \
} while (0)
#else
#define SIGNPOST_EMITTER_START_INTERVAL(SIGNPOST_EMITTER, O, ...) \
do { \
} while (0)
#endif
/// End a signposted interval for a given object.
void endInterval(const void *O, StringRef Name);
void endInterval(const void *O);
};
} // end namespace llvm

View File

@ -10,19 +10,14 @@
#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 "llvm/Support/Mutex.h"
#include <Availability.h>
#include <os/signpost.h>
#endif // if LLVM_SUPPORT_XCODE_SIGNPOSTS
using namespace llvm;
#if LLVM_SUPPORT_XCODE_SIGNPOSTS
#define SIGNPOSTS_AVAILABLE() \
__builtin_available(macos 10.14, iOS 12, tvOS 12, watchOS 5, *)
namespace {
os_log_t *LogCreator() {
os_log_t *X = new os_log_t;
@ -40,13 +35,13 @@ struct LogDeleter {
namespace llvm {
class SignpostEmitterImpl {
using LogPtrTy = std::unique_ptr<os_log_t, LogDeleter>;
using LogTy = LogPtrTy::element_type;
LogPtrTy SignpostLog;
DenseMap<const void *, os_signpost_id_t> Signposts;
sys::SmartMutex<true> Mutex;
LogTy &getLogger() const { return *SignpostLog; }
public:
os_log_t &getLogger() const { return *SignpostLog; }
os_signpost_id_t getSignpostForObject(const void *O) {
sys::SmartScopedLock<true> Lock(Mutex);
const auto &I = Signposts.find(O);
@ -60,7 +55,6 @@ class SignpostEmitterImpl {
return Inserted.first->second;
}
public:
SignpostEmitterImpl() : SignpostLog(LogCreator()) {}
bool isEnabled() const {
@ -79,7 +73,7 @@ public:
}
}
void endInterval(const void *O, llvm::StringRef Name) {
void endInterval(const void *O) {
if (isEnabled()) {
if (SIGNPOSTS_AVAILABLE()) {
// Both strings used here are required to be constant literal strings.
@ -125,10 +119,17 @@ void SignpostEmitter::startInterval(const void *O, StringRef Name) {
#endif // if !HAVE_ANY_SIGNPOST_IMPL
}
void SignpostEmitter::endInterval(const void *O, StringRef Name) {
#if HAVE_ANY_SIGNPOST_IMPL
os_log_t &SignpostEmitter::getLogger() const { return Impl->getLogger(); }
os_signpost_id_t SignpostEmitter::getSignpostForObject(const void *O) {
return Impl->getSignpostForObject(O);
}
#endif
void SignpostEmitter::endInterval(const void *O) {
#if HAVE_ANY_SIGNPOST_IMPL
if (Impl == nullptr)
return;
Impl->endInterval(O, Name);
Impl->endInterval(O);
#endif // if !HAVE_ANY_SIGNPOST_IMPL
}

View File

@ -174,7 +174,7 @@ void Timer::stopTimer() {
Running = false;
Time += TimeRecord::getCurrentTime(false);
Time -= StartTime;
Signposts->endInterval(this, getName());
Signposts->endInterval(this);
}
void Timer::clear() {