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