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