1 //===-- Shared/Profile.h - Target independent OpenMP target RTL -*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Macros to provide profile support via LLVM's time profiler. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef OMPTARGET_SHARED_PROFILE_H 14 #define OMPTARGET_SHARED_PROFILE_H 15 16 #include "Shared/Debug.h" 17 #include "Shared/EnvironmentVar.h" 18 19 #include "llvm/ADT/StringRef.h" 20 #include "llvm/Support/Error.h" 21 #include "llvm/Support/TimeProfiler.h" 22 23 /// Class that holds the singleton profiler and allows to start/end events. 24 class Profiler { 25 Profiler()26 Profiler() { 27 if (!ProfileTraceFile.isPresent()) 28 return; 29 30 // TODO: Add an alias without LIBOMPTARGET 31 // Flag to modify the profile granularity (in us). 32 Int32Envar ProfileGranularity = 33 Int32Envar("LIBOMPTARGET_PROFILE_GRANULARITY", 500); 34 35 llvm::timeTraceProfilerInitialize(ProfileGranularity /*us=*/, 36 "libomptarget"); 37 } 38 ~Profiler()39 ~Profiler() { 40 if (!ProfileTraceFile.isPresent()) 41 return; 42 43 if (auto Err = llvm::timeTraceProfilerWrite(ProfileTraceFile.get(), "-")) 44 REPORT("Error writing out the time trace: %s\n", 45 llvm::toString(std::move(Err)).c_str()); 46 47 llvm::timeTraceProfilerCleanup(); 48 } 49 50 // TODO: Add an alias without LIBOMPTARGET 51 /// Flag to enable profiling which also specifies the file profile information 52 /// is stored in. 53 StringEnvar ProfileTraceFile = StringEnvar("LIBOMPTARGET_PROFILE"); 54 55 public: get()56 static Profiler &get() { 57 static Profiler P; 58 return P; 59 } 60 61 /// Manually begin a time section, with the given \p Name and \p Detail. 62 /// Profiler copies the string data, so the pointers can be given into 63 /// temporaries. Time sections can be hierarchical; every Begin must have a 64 /// matching End pair but they can nest. beginSection(llvm::StringRef Name,llvm::StringRef Detail)65 void beginSection(llvm::StringRef Name, llvm::StringRef Detail) { 66 llvm::timeTraceProfilerBegin(Name, Detail); 67 } beginSection(llvm::StringRef Name,llvm::function_ref<std::string ()> Detail)68 void beginSection(llvm::StringRef Name, 69 llvm::function_ref<std::string()> Detail) { 70 llvm::timeTraceProfilerBegin(Name, Detail); 71 } 72 73 /// Manually end the last time section. endSection()74 void endSection() { llvm::timeTraceProfilerEnd(); } 75 }; 76 77 /// Time spend in the current scope, assigned to the function name. 78 #define TIMESCOPE() llvm::TimeTraceScope TimeScope(__PRETTY_FUNCTION__) 79 80 /// Time spend in the current scope, assigned to the function name and source 81 /// info. 82 #define TIMESCOPE_WITH_IDENT(IDENT) \ 83 SourceInfo SI(IDENT); \ 84 llvm::TimeTraceScope TimeScope(__FUNCTION__, SI.getProfileLocation()) 85 86 /// Time spend in the current scope, assigned to the given name and source 87 /// info. 88 #define TIMESCOPE_WITH_NAME_AND_IDENT(NAME, IDENT) \ 89 SourceInfo SI(IDENT); \ 90 llvm::TimeTraceScope TimeScope(NAME, SI.getProfileLocation()) 91 92 /// Time spend in the current scope, assigned to the function name and source 93 /// info and RegionTypeMsg. 94 #define TIMESCOPE_WITH_RTM_AND_IDENT(RegionTypeMsg, IDENT) \ 95 SourceInfo SI(IDENT); \ 96 std::string ProfileLocation = SI.getProfileLocation(); \ 97 std::string RTM = RegionTypeMsg; \ 98 llvm::TimeTraceScope TimeScope(__FUNCTION__, ProfileLocation + RTM) 99 100 /// Time spend in the current scope, assigned to the regionType 101 /// with details from runtime 102 #define TIMESCOPE_WITH_DETAILS_AND_IDENT(RegionTypeMsg, Details, IDENT) \ 103 SourceInfo SI(IDENT); \ 104 std::string ProfileLocation = SI.getProfileLocation(); \ 105 llvm::TimeTraceScope TimeScope(RegionTypeMsg, ProfileLocation + Details) 106 107 /// Time spend in the current scope, assigned to the function name and source 108 /// with details 109 #define TIMESCOPE_WITH_DETAILS(Details) \ 110 llvm::TimeTraceScope TimeScope(__FUNCTION__, Details) 111 112 #endif // OMPTARGET_SHARED_PROFILE_H 113