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