summaryrefslogtreecommitdiffstats
path: root/lld/include/lld/Core/Instrumentation.h
blob: 939d6455758790b2656fcf4d279104c79ab23a72 (plain)
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
132
//===- include/Core/Instrumentation.h - Instrumentation API ---------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \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
OpenPOWER on IntegriCloud