[libcxx-commits] [llvm] [clang] [mlir] [libcxx] [llvm][Support] Enable `TimeTraceProfiler` to accept deferred detail string (PR #74935)

Vlad Serebrennikov via libcxx-commits libcxx-commits at lists.llvm.org
Sat Dec 9 07:17:33 PST 2023


https://github.com/Endilll updated https://github.com/llvm/llvm-project/pull/74935

>From 4e8f48947d59474e07e08cdc98e4a6fb2e3c80c1 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sat, 9 Dec 2023 17:21:35 +0300
Subject: [PATCH 1/2] [llvm][Support] Enable `TimeTraceProfiler` to accept
 deferred detail string

This patch enables `TimeTraceProfiler` and `TimeTraceScope` to accept detail string, which is not yet available at the time new trace entry is created. This is important for Clang parser use cases, e.g. when parsing a class member we don't yet know name of.
---
 llvm/include/llvm/Support/TimeProfiler.h | 35 ++++++++++++++++++++----
 llvm/lib/Support/TimeProfiler.cpp        | 34 +++++++++++++++--------
 2 files changed, 52 insertions(+), 17 deletions(-)

diff --git a/llvm/include/llvm/Support/TimeProfiler.h b/llvm/include/llvm/Support/TimeProfiler.h
index 454a65f70231f..5b8af16ed4a9a 100644
--- a/llvm/include/llvm/Support/TimeProfiler.h
+++ b/llvm/include/llvm/Support/TimeProfiler.h
@@ -86,6 +86,8 @@ class raw_pwrite_stream;
 struct TimeTraceProfiler;
 TimeTraceProfiler *getTimeTraceProfilerInstance();
 
+struct TimeTraceProfilerEntry;
+
 /// Initialize the time trace profiler.
 /// This sets up the global \p TimeTraceProfilerInstance
 /// variable to be the profiler instance.
@@ -120,18 +122,29 @@ Error timeTraceProfilerWrite(StringRef PreferredFileName,
 /// Profiler copies the string data, so the pointers can be given into
 /// temporaries. Time sections can be hierarchical; every Begin must have a
 /// matching End pair but they can nest.
-void timeTraceProfilerBegin(StringRef Name, StringRef Detail);
-void timeTraceProfilerBegin(StringRef Name,
+TimeTraceProfilerEntry* timeTraceProfilerBegin(StringRef Name, StringRef Detail);
+TimeTraceProfilerEntry* timeTraceProfilerBegin(StringRef Name,
                             llvm::function_ref<std::string()> Detail);
 
 /// Manually end the last time section.
 void timeTraceProfilerEnd();
 
+/// Set detail string for an existing trace entry.
+/// This function sets \p Detail string for an entry previously created by
+/// `timeTraceProfilerBegin`. String is handled in the same way as
+/// `timeTraceProfilerBegin` does. This is useful when contents of
+/// \p Detail is not (fully) known at the time trace entry is created.
+void timeTraceProfilerEntrySetDetail(TimeTraceProfilerEntry* Entry, StringRef Detail);
+void timeTraceProfilerEntrySetDetail(TimeTraceProfilerEntry* Entry, llvm::function_ref<std::string()> Detail);
+
 /// The TimeTraceScope is a helper class to call the begin and end functions
 /// of the time trace profiler.  When the object is constructed, it begins
 /// the section; and when it is destroyed, it stops it. If the time profiler
 /// is not initialized, the overhead is a single branch.
-struct TimeTraceScope {
+class TimeTraceScope {
+  TimeTraceProfilerEntry* Entry;
+
+public:
 
   TimeTraceScope() = delete;
   TimeTraceScope(const TimeTraceScope &) = delete;
@@ -141,20 +154,30 @@ struct TimeTraceScope {
 
   TimeTraceScope(StringRef Name) {
     if (getTimeTraceProfilerInstance() != nullptr)
-      timeTraceProfilerBegin(Name, StringRef(""));
+      Entry = timeTraceProfilerBegin(Name, StringRef(""));
   }
   TimeTraceScope(StringRef Name, StringRef Detail) {
     if (getTimeTraceProfilerInstance() != nullptr)
-      timeTraceProfilerBegin(Name, Detail);
+      Entry = timeTraceProfilerBegin(Name, Detail);
   }
   TimeTraceScope(StringRef Name, llvm::function_ref<std::string()> Detail) {
     if (getTimeTraceProfilerInstance() != nullptr)
-      timeTraceProfilerBegin(Name, Detail);
+      Entry = timeTraceProfilerBegin(Name, Detail);
   }
   ~TimeTraceScope() {
     if (getTimeTraceProfilerInstance() != nullptr)
       timeTraceProfilerEnd();
   }
+  void setDetail(StringRef Detail) {
+    if (Entry != nullptr) {
+      timeTraceProfilerEntrySetDetail(Entry, Detail);
+    }
+  }
+  void setDetail(llvm::function_ref<std::string()> Detail) {
+    if (Entry != nullptr) {
+      timeTraceProfilerEntrySetDetail(Entry, Detail);
+    }
+  }
 };
 
 } // end namespace llvm
diff --git a/llvm/lib/Support/TimeProfiler.cpp b/llvm/lib/Support/TimeProfiler.cpp
index 4d625b3eb5b17..bd8a04ed8962d 100644
--- a/llvm/lib/Support/TimeProfiler.cpp
+++ b/llvm/lib/Support/TimeProfiler.cpp
@@ -64,12 +64,14 @@ using CountAndDurationType = std::pair<size_t, DurationType>;
 using NameAndCountAndDurationType =
     std::pair<std::string, CountAndDurationType>;
 
+} // anonymous namespace
+
 /// Represents an open or completed time section entry to be captured.
-struct TimeTraceProfilerEntry {
+struct llvm::TimeTraceProfilerEntry {
   const TimePointType Start;
   TimePointType End;
   const std::string Name;
-  const std::string Detail;
+  std::string Detail;
 
   TimeTraceProfilerEntry(TimePointType &&S, TimePointType &&E, std::string &&N,
                          std::string &&Dt)
@@ -92,8 +94,6 @@ struct TimeTraceProfilerEntry {
   }
 };
 
-} // anonymous namespace
-
 struct llvm::TimeTraceProfiler {
   TimeTraceProfiler(unsigned TimeTraceGranularity = 0, StringRef ProcName = "")
       : BeginningOfTime(system_clock::now()), StartTime(ClockType::now()),
@@ -102,8 +102,8 @@ struct llvm::TimeTraceProfiler {
     llvm::get_thread_name(ThreadName);
   }
 
-  void begin(std::string Name, llvm::function_ref<std::string()> Detail) {
-    Stack.emplace_back(ClockType::now(), TimePointType(), std::move(Name),
+  llvm::TimeTraceProfilerEntry* begin(std::string Name, llvm::function_ref<std::string()> Detail) {
+    return &Stack.emplace_back(ClockType::now(), TimePointType(), std::move(Name),
                        Detail());
   }
 
@@ -341,19 +341,31 @@ Error llvm::timeTraceProfilerWrite(StringRef PreferredFileName,
   return Error::success();
 }
 
-void llvm::timeTraceProfilerBegin(StringRef Name, StringRef Detail) {
+llvm::TimeTraceProfilerEntry* llvm::timeTraceProfilerBegin(StringRef Name, StringRef Detail) {
   if (TimeTraceProfilerInstance != nullptr)
-    TimeTraceProfilerInstance->begin(std::string(Name),
-                                     [&]() { return std::string(Detail); });
+    return TimeTraceProfilerInstance->begin(std::string(Name),
+                                             [&]() { return std::string(Detail); });
 }
 
-void llvm::timeTraceProfilerBegin(StringRef Name,
+llvm::TimeTraceProfilerEntry* llvm::timeTraceProfilerBegin(StringRef Name,
                                   llvm::function_ref<std::string()> Detail) {
   if (TimeTraceProfilerInstance != nullptr)
-    TimeTraceProfilerInstance->begin(std::string(Name), Detail);
+    return TimeTraceProfilerInstance->begin(std::string(Name), Detail);
 }
 
 void llvm::timeTraceProfilerEnd() {
   if (TimeTraceProfilerInstance != nullptr)
     TimeTraceProfilerInstance->end();
 }
+
+void llvm::timeTraceProfilerEntrySetDetail(llvm::TimeTraceProfilerEntry* Entry, StringRef Detail) {
+  if (Entry != nullptr) {
+    Entry->Detail = Detail;
+  }
+}
+
+void llvm::timeTraceProfilerEntrySetDetail(llvm::TimeTraceProfilerEntry* Entry, llvm::function_ref<std::string()> Detail) {
+  if (Entry != nullptr) {
+    Entry->Detail = Detail();
+  }
+}

>From 740fbff0fe9283eec6e09099f1d05f2a67ec8382 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sat, 9 Dec 2023 17:46:21 +0300
Subject: [PATCH 2/2] Run clang-format

---
 llvm/include/llvm/Support/TimeProfiler.h | 17 +++++++++-------
 llvm/lib/Support/TimeProfiler.cpp        | 26 +++++++++++++++---------
 2 files changed, 26 insertions(+), 17 deletions(-)

diff --git a/llvm/include/llvm/Support/TimeProfiler.h b/llvm/include/llvm/Support/TimeProfiler.h
index 5b8af16ed4a9a..f96b3a0fb831f 100644
--- a/llvm/include/llvm/Support/TimeProfiler.h
+++ b/llvm/include/llvm/Support/TimeProfiler.h
@@ -122,9 +122,11 @@ Error timeTraceProfilerWrite(StringRef PreferredFileName,
 /// Profiler copies the string data, so the pointers can be given into
 /// temporaries. Time sections can be hierarchical; every Begin must have a
 /// matching End pair but they can nest.
-TimeTraceProfilerEntry* timeTraceProfilerBegin(StringRef Name, StringRef Detail);
-TimeTraceProfilerEntry* timeTraceProfilerBegin(StringRef Name,
-                            llvm::function_ref<std::string()> Detail);
+TimeTraceProfilerEntry *timeTraceProfilerBegin(StringRef Name,
+                                               StringRef Detail);
+TimeTraceProfilerEntry *
+timeTraceProfilerBegin(StringRef Name,
+                       llvm::function_ref<std::string()> Detail);
 
 /// Manually end the last time section.
 void timeTraceProfilerEnd();
@@ -134,18 +136,19 @@ void timeTraceProfilerEnd();
 /// `timeTraceProfilerBegin`. String is handled in the same way as
 /// `timeTraceProfilerBegin` does. This is useful when contents of
 /// \p Detail is not (fully) known at the time trace entry is created.
-void timeTraceProfilerEntrySetDetail(TimeTraceProfilerEntry* Entry, StringRef Detail);
-void timeTraceProfilerEntrySetDetail(TimeTraceProfilerEntry* Entry, llvm::function_ref<std::string()> Detail);
+void timeTraceProfilerEntrySetDetail(TimeTraceProfilerEntry *Entry,
+                                     StringRef Detail);
+void timeTraceProfilerEntrySetDetail(TimeTraceProfilerEntry *Entry,
+                                     llvm::function_ref<std::string()> Detail);
 
 /// The TimeTraceScope is a helper class to call the begin and end functions
 /// of the time trace profiler.  When the object is constructed, it begins
 /// the section; and when it is destroyed, it stops it. If the time profiler
 /// is not initialized, the overhead is a single branch.
 class TimeTraceScope {
-  TimeTraceProfilerEntry* Entry;
+  TimeTraceProfilerEntry *Entry;
 
 public:
-
   TimeTraceScope() = delete;
   TimeTraceScope(const TimeTraceScope &) = delete;
   TimeTraceScope &operator=(const TimeTraceScope &) = delete;
diff --git a/llvm/lib/Support/TimeProfiler.cpp b/llvm/lib/Support/TimeProfiler.cpp
index bd8a04ed8962d..ebf0f40efaae7 100644
--- a/llvm/lib/Support/TimeProfiler.cpp
+++ b/llvm/lib/Support/TimeProfiler.cpp
@@ -102,9 +102,10 @@ struct llvm::TimeTraceProfiler {
     llvm::get_thread_name(ThreadName);
   }
 
-  llvm::TimeTraceProfilerEntry* begin(std::string Name, llvm::function_ref<std::string()> Detail) {
-    return &Stack.emplace_back(ClockType::now(), TimePointType(), std::move(Name),
-                       Detail());
+  llvm::TimeTraceProfilerEntry *
+  begin(std::string Name, llvm::function_ref<std::string()> Detail) {
+    return &Stack.emplace_back(ClockType::now(), TimePointType(),
+                               std::move(Name), Detail());
   }
 
   void end() {
@@ -341,14 +342,16 @@ Error llvm::timeTraceProfilerWrite(StringRef PreferredFileName,
   return Error::success();
 }
 
-llvm::TimeTraceProfilerEntry* llvm::timeTraceProfilerBegin(StringRef Name, StringRef Detail) {
+llvm::TimeTraceProfilerEntry *llvm::timeTraceProfilerBegin(StringRef Name,
+                                                           StringRef Detail) {
   if (TimeTraceProfilerInstance != nullptr)
-    return TimeTraceProfilerInstance->begin(std::string(Name),
-                                             [&]() { return std::string(Detail); });
+    return TimeTraceProfilerInstance->begin(
+        std::string(Name), [&]() { return std::string(Detail); });
 }
 
-llvm::TimeTraceProfilerEntry* llvm::timeTraceProfilerBegin(StringRef Name,
-                                  llvm::function_ref<std::string()> Detail) {
+llvm::TimeTraceProfilerEntry *
+llvm::timeTraceProfilerBegin(StringRef Name,
+                             llvm::function_ref<std::string()> Detail) {
   if (TimeTraceProfilerInstance != nullptr)
     return TimeTraceProfilerInstance->begin(std::string(Name), Detail);
 }
@@ -358,13 +361,16 @@ void llvm::timeTraceProfilerEnd() {
     TimeTraceProfilerInstance->end();
 }
 
-void llvm::timeTraceProfilerEntrySetDetail(llvm::TimeTraceProfilerEntry* Entry, StringRef Detail) {
+void llvm::timeTraceProfilerEntrySetDetail(llvm::TimeTraceProfilerEntry *Entry,
+                                           StringRef Detail) {
   if (Entry != nullptr) {
     Entry->Detail = Detail;
   }
 }
 
-void llvm::timeTraceProfilerEntrySetDetail(llvm::TimeTraceProfilerEntry* Entry, llvm::function_ref<std::string()> Detail) {
+void llvm::timeTraceProfilerEntrySetDetail(
+    llvm::TimeTraceProfilerEntry *Entry,
+    llvm::function_ref<std::string()> Detail) {
   if (Entry != nullptr) {
     Entry->Detail = Detail();
   }



More information about the libcxx-commits mailing list