diff options
Diffstat (limited to 'include/lld/Core/Instrumentation.h')
-rw-r--r-- | include/lld/Core/Instrumentation.h | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/include/lld/Core/Instrumentation.h b/include/lld/Core/Instrumentation.h new file mode 100644 index 000000000000..162375905e17 --- /dev/null +++ b/include/lld/Core/Instrumentation.h @@ -0,0 +1,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 +/// \brief 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 +/// \brief 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; } +}; + +/// \brief 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; } +}; + +/// \brief 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: + /// \brief 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; + } + + /// \brief Prematurely end this task. + void end() { + if (_domain) + __itt_task_end(_domain); + _domain = nullptr; + } + + ~ScopedTask() { end(); } +}; + +/// \brief 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 |