Signposts.cpp 3.2 KB

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