//===- 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 #ifdef LLD_HAS_VTUNE # include #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 balanced. 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