Home | History | Annotate | Download | only in Core
      1 //===- include/Core/Instrumentation.h - Instrumentation API ---------------===//
      2 //
      3 //                             The LLVM Linker
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 ///
     10 /// \file
     11 /// \brief Provide an Instrumentation API that optionally uses VTune interfaces.
     12 ///
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLD_CORE_INSTRUMENTATION_H
     16 #define LLD_CORE_INSTRUMENTATION_H
     17 
     18 #include "llvm/Support/Compiler.h"
     19 #include <utility>
     20 
     21 #ifdef LLD_HAS_VTUNE
     22 # include <ittnotify.h>
     23 #endif
     24 
     25 namespace lld {
     26 #ifdef LLD_HAS_VTUNE
     27 /// \brief A unique global scope for instrumentation data.
     28 ///
     29 /// Domains last for the lifetime of the application and cannot be destroyed.
     30 /// Multiple Domains created with the same name represent the same domain.
     31 class Domain {
     32   __itt_domain *_domain;
     33 
     34 public:
     35   explicit Domain(const char *name) : _domain(__itt_domain_createA(name)) {}
     36 
     37   operator __itt_domain *() const { return _domain; }
     38   __itt_domain *operator->() const { return _domain; }
     39 };
     40 
     41 /// \brief A global reference to a string constant.
     42 ///
     43 /// These are uniqued by the ITT runtime and cannot be deleted. They are not
     44 /// specific to a domain.
     45 ///
     46 /// Prefer reusing a single StringHandle over passing a ntbs when the same
     47 /// string will be used often.
     48 class StringHandle {
     49   __itt_string_handle *_handle;
     50 
     51 public:
     52   StringHandle(const char *name) : _handle(__itt_string_handle_createA(name)) {}
     53 
     54   operator __itt_string_handle *() const { return _handle; }
     55 };
     56 
     57 /// \brief A task on a single thread. Nests within other tasks.
     58 ///
     59 /// Each thread has its own task stack and tasks nest recursively on that stack.
     60 /// A task cannot transfer threads.
     61 ///
     62 /// SBRM is used to ensure task starts and ends are ballanced. The lifetime of
     63 /// a task is either the lifetime of this object, or until end is called.
     64 class ScopedTask {
     65   __itt_domain *_domain;
     66 
     67   ScopedTask(const ScopedTask &) = delete;
     68   ScopedTask &operator=(const ScopedTask &) = delete;
     69 
     70 public:
     71   /// \brief Create a task in Domain \p d named \p s.
     72   ScopedTask(const Domain &d, const StringHandle &s) : _domain(d) {
     73     __itt_task_begin(d, __itt_null, __itt_null, s);
     74   }
     75 
     76   ScopedTask(ScopedTask &&other) {
     77     *this = std::move(other);
     78   }
     79 
     80   ScopedTask &operator=(ScopedTask &&other) {
     81     _domain = other._domain;
     82     other._domain = nullptr;
     83     return *this;
     84   }
     85 
     86   /// \brief Prematurely end this task.
     87   void end() {
     88     if (_domain)
     89       __itt_task_end(_domain);
     90     _domain = nullptr;
     91   }
     92 
     93   ~ScopedTask() { end(); }
     94 };
     95 
     96 /// \brief A specific point in time. Allows metadata to be associated.
     97 class Marker {
     98 public:
     99   Marker(const Domain &d, const StringHandle &s) {
    100     __itt_marker(d, __itt_null, s, __itt_scope_global);
    101   }
    102 };
    103 #else
    104 class Domain {
    105 public:
    106   Domain(const char *name) {}
    107 };
    108 
    109 class StringHandle {
    110 public:
    111   StringHandle(const char *name) {}
    112 };
    113 
    114 class ScopedTask {
    115 public:
    116   ScopedTask(const Domain &d, const StringHandle &s) {}
    117   void end() {}
    118 };
    119 
    120 class Marker {
    121 public:
    122   Marker(const Domain &d, const StringHandle &s) {}
    123 };
    124 #endif
    125 
    126 inline const Domain &getDefaultDomain() {
    127   static Domain domain("org.llvm.lld");
    128   return domain;
    129 }
    130 } // end namespace lld.
    131 
    132 #endif
    133