1280461Sdim//===- include/Core/Instrumentation.h - Instrumentation API ---------------===// 2280461Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6280461Sdim// 7280461Sdim//===----------------------------------------------------------------------===// 8280461Sdim/// 9280461Sdim/// \file 10341825Sdim/// Provide an Instrumentation API that optionally uses VTune interfaces. 11280461Sdim/// 12280461Sdim//===----------------------------------------------------------------------===// 13280461Sdim 14280461Sdim#ifndef LLD_CORE_INSTRUMENTATION_H 15280461Sdim#define LLD_CORE_INSTRUMENTATION_H 16280461Sdim 17280461Sdim#include "llvm/Support/Compiler.h" 18280461Sdim#include <utility> 19280461Sdim 20280461Sdim#ifdef LLD_HAS_VTUNE 21280461Sdim# include <ittnotify.h> 22280461Sdim#endif 23280461Sdim 24280461Sdimnamespace lld { 25280461Sdim#ifdef LLD_HAS_VTUNE 26341825Sdim/// A unique global scope for instrumentation data. 27280461Sdim/// 28280461Sdim/// Domains last for the lifetime of the application and cannot be destroyed. 29280461Sdim/// Multiple Domains created with the same name represent the same domain. 30280461Sdimclass Domain { 31280461Sdim __itt_domain *_domain; 32280461Sdim 33280461Sdimpublic: 34280461Sdim explicit Domain(const char *name) : _domain(__itt_domain_createA(name)) {} 35280461Sdim 36280461Sdim operator __itt_domain *() const { return _domain; } 37280461Sdim __itt_domain *operator->() const { return _domain; } 38280461Sdim}; 39280461Sdim 40341825Sdim/// A global reference to a string constant. 41280461Sdim/// 42280461Sdim/// These are uniqued by the ITT runtime and cannot be deleted. They are not 43280461Sdim/// specific to a domain. 44280461Sdim/// 45280461Sdim/// Prefer reusing a single StringHandle over passing a ntbs when the same 46280461Sdim/// string will be used often. 47280461Sdimclass StringHandle { 48280461Sdim __itt_string_handle *_handle; 49280461Sdim 50280461Sdimpublic: 51280461Sdim StringHandle(const char *name) : _handle(__itt_string_handle_createA(name)) {} 52280461Sdim 53280461Sdim operator __itt_string_handle *() const { return _handle; } 54280461Sdim}; 55280461Sdim 56341825Sdim/// A task on a single thread. Nests within other tasks. 57280461Sdim/// 58280461Sdim/// Each thread has its own task stack and tasks nest recursively on that stack. 59280461Sdim/// A task cannot transfer threads. 60280461Sdim/// 61360784Sdim/// SBRM is used to ensure task starts and ends are balanced. The lifetime of 62280461Sdim/// a task is either the lifetime of this object, or until end is called. 63280461Sdimclass ScopedTask { 64280461Sdim __itt_domain *_domain; 65280461Sdim 66280461Sdim ScopedTask(const ScopedTask &) = delete; 67280461Sdim ScopedTask &operator=(const ScopedTask &) = delete; 68280461Sdim 69280461Sdimpublic: 70341825Sdim /// Create a task in Domain \p d named \p s. 71280461Sdim ScopedTask(const Domain &d, const StringHandle &s) : _domain(d) { 72280461Sdim __itt_task_begin(d, __itt_null, __itt_null, s); 73280461Sdim } 74280461Sdim 75280461Sdim ScopedTask(ScopedTask &&other) { 76280461Sdim *this = std::move(other); 77280461Sdim } 78280461Sdim 79280461Sdim ScopedTask &operator=(ScopedTask &&other) { 80280461Sdim _domain = other._domain; 81280461Sdim other._domain = nullptr; 82280461Sdim return *this; 83280461Sdim } 84280461Sdim 85341825Sdim /// Prematurely end this task. 86280461Sdim void end() { 87280461Sdim if (_domain) 88280461Sdim __itt_task_end(_domain); 89280461Sdim _domain = nullptr; 90280461Sdim } 91280461Sdim 92280461Sdim ~ScopedTask() { end(); } 93280461Sdim}; 94280461Sdim 95341825Sdim/// A specific point in time. Allows metadata to be associated. 96280461Sdimclass Marker { 97280461Sdimpublic: 98280461Sdim Marker(const Domain &d, const StringHandle &s) { 99280461Sdim __itt_marker(d, __itt_null, s, __itt_scope_global); 100280461Sdim } 101280461Sdim}; 102280461Sdim#else 103280461Sdimclass Domain { 104280461Sdimpublic: 105280461Sdim Domain(const char *name) {} 106280461Sdim}; 107280461Sdim 108280461Sdimclass StringHandle { 109280461Sdimpublic: 110280461Sdim StringHandle(const char *name) {} 111280461Sdim}; 112280461Sdim 113280461Sdimclass ScopedTask { 114280461Sdimpublic: 115280461Sdim ScopedTask(const Domain &d, const StringHandle &s) {} 116280461Sdim void end() {} 117280461Sdim}; 118280461Sdim 119280461Sdimclass Marker { 120280461Sdimpublic: 121280461Sdim Marker(const Domain &d, const StringHandle &s) {} 122280461Sdim}; 123280461Sdim#endif 124280461Sdim 125280461Sdiminline const Domain &getDefaultDomain() { 126280461Sdim static Domain domain("org.llvm.lld"); 127280461Sdim return domain; 128280461Sdim} 129280461Sdim} // end namespace lld. 130280461Sdim 131280461Sdim#endif 132