[clang] [llvm] Use TimeTraceProfilerEntry for Source span (PR #83961)
Takuto Ikuta via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 4 21:42:45 PST 2024
https://github.com/atetubou updated https://github.com/llvm/llvm-project/pull/83961
>From 9a4911ee0732abbe770b98396e166a4d95bc0c95 Mon Sep 17 00:00:00 2001
From: Takuto Ikuta <tikuta at google.com>
Date: Mon, 4 Mar 2024 19:12:31 +0900
Subject: [PATCH 1/2] Expose TimeTraceProfiler for overlapping spans
---
llvm/include/llvm/Support/TimeProfiler.h | 22 ++++++---
llvm/lib/Support/TimeProfiler.cpp | 63 ++++++++++++++----------
2 files changed, 53 insertions(+), 32 deletions(-)
diff --git a/llvm/include/llvm/Support/TimeProfiler.h b/llvm/include/llvm/Support/TimeProfiler.h
index 454a65f70231f4..941af7e3126c11 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,12 +122,15 @@ 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,
- 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();
+void timeTraceProfilerEnd(TimeTraceProfilerEntry *E);
/// 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
@@ -141,20 +146,23 @@ 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();
+ timeTraceProfilerEnd(Entry);
}
+
+private:
+ TimeTraceProfilerEntry *Entry = nullptr;
};
} // end namespace llvm
diff --git a/llvm/lib/Support/TimeProfiler.cpp b/llvm/lib/Support/TimeProfiler.cpp
index 4d625b3eb5b170..b195214cb52960 100644
--- a/llvm/lib/Support/TimeProfiler.cpp
+++ b/llvm/lib/Support/TimeProfiler.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/TimeProfiler.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/JSON.h"
@@ -20,6 +21,7 @@
#include <algorithm>
#include <cassert>
#include <chrono>
+#include <memory>
#include <mutex>
#include <string>
#include <vector>
@@ -64,8 +66,10 @@ 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;
@@ -92,8 +96,6 @@ struct TimeTraceProfilerEntry {
}
};
-} // anonymous namespace
-
struct llvm::TimeTraceProfiler {
TimeTraceProfiler(unsigned TimeTraceGranularity = 0, StringRef ProcName = "")
: BeginningOfTime(system_clock::now()), StartTime(ClockType::now()),
@@ -102,23 +104,22 @@ 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),
- Detail());
+ TimeTraceProfilerEntry *begin(std::string Name,
+ llvm::function_ref<std::string()> Detail) {
+ Stack.emplace_back(std::make_unique<TimeTraceProfilerEntry>(
+ ClockType::now(), TimePointType(), std::move(Name), Detail()));
+ return Stack.back().get();
}
void end() {
+ TimeTraceProfilerEntry *E = Stack.back().get();
+ end(*E);
+ }
+
+ void end(TimeTraceProfilerEntry &E) {
assert(!Stack.empty() && "Must call begin() first");
- TimeTraceProfilerEntry &E = Stack.back();
E.End = ClockType::now();
- // Check that end times monotonically increase.
- assert((Entries.empty() ||
- (E.getFlameGraphStartUs(StartTime) + E.getFlameGraphDurUs() >=
- Entries.back().getFlameGraphStartUs(StartTime) +
- Entries.back().getFlameGraphDurUs())) &&
- "TimeProfiler scope ended earlier than previous scope");
-
// Calculate duration at full precision for overall counts.
DurationType Duration = E.End - E.Start;
@@ -132,15 +133,18 @@ struct llvm::TimeTraceProfiler {
// happens to be the ones that don't have any currently open entries above
// itself.
if (llvm::none_of(llvm::drop_begin(llvm::reverse(Stack)),
- [&](const TimeTraceProfilerEntry &Val) {
- return Val.Name == E.Name;
+ [&](const std::unique_ptr<TimeTraceProfilerEntry> &Val) {
+ return Val->Name == E.Name;
})) {
auto &CountAndTotal = CountAndTotalPerName[E.Name];
CountAndTotal.first++;
CountAndTotal.second += Duration;
- }
+ };
- Stack.pop_back();
+ llvm::erase_if(Stack,
+ [&](const std::unique_ptr<TimeTraceProfilerEntry> &Val) {
+ return Val.get() == &E;
+ });
}
// Write events from this TimeTraceProfilerInstance and
@@ -269,7 +273,7 @@ struct llvm::TimeTraceProfiler {
J.objectEnd();
}
- SmallVector<TimeTraceProfilerEntry, 16> Stack;
+ SmallVector<std::unique_ptr<TimeTraceProfilerEntry>, 16> Stack;
SmallVector<TimeTraceProfilerEntry, 128> Entries;
StringMap<CountAndDurationType> CountAndTotalPerName;
// System clock time when the session was begun.
@@ -341,19 +345,28 @@ Error llvm::timeTraceProfilerWrite(StringRef PreferredFileName,
return Error::success();
}
-void llvm::timeTraceProfilerBegin(StringRef Name, StringRef Detail) {
+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); });
+ return nullptr;
}
-void llvm::timeTraceProfilerBegin(StringRef Name,
- llvm::function_ref<std::string()> Detail) {
+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);
+ return nullptr;
}
void llvm::timeTraceProfilerEnd() {
if (TimeTraceProfilerInstance != nullptr)
TimeTraceProfilerInstance->end();
}
+
+void llvm::timeTraceProfilerEnd(TimeTraceProfilerEntry *E) {
+ if (TimeTraceProfilerInstance != nullptr)
+ TimeTraceProfilerInstance->end(*E);
+}
>From 2de443fbb73e5dd95d0b3184ab4c9c4e9dec3e6e Mon Sep 17 00:00:00 2001
From: Takuto Ikuta <tikuta at google.com>
Date: Mon, 4 Mar 2024 17:02:05 +0900
Subject: [PATCH 2/2] Use TimeTraceProfilerEntry for Source span
---
clang/lib/Sema/Sema.cpp | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index cfb653e665ea03..d416b1403325bc 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -135,6 +135,7 @@ namespace sema {
class SemaPPCallbacks : public PPCallbacks {
Sema *S = nullptr;
llvm::SmallVector<SourceLocation, 8> IncludeStack;
+ llvm::SmallVector<llvm::TimeTraceProfilerEntry *, 8> ProfilerStack;
public:
void set(Sema &S) { this->S = &S; }
@@ -153,8 +154,8 @@ class SemaPPCallbacks : public PPCallbacks {
if (IncludeLoc.isValid()) {
if (llvm::timeTraceProfilerEnabled()) {
OptionalFileEntryRef FE = SM.getFileEntryRefForID(SM.getFileID(Loc));
- llvm::timeTraceProfilerBegin("Source", FE ? FE->getName()
- : StringRef("<unknown>"));
+ ProfilerStack.push_back(llvm::timeTraceProfilerBegin(
+ "Source", FE ? FE->getName() : StringRef("<unknown>")));
}
IncludeStack.push_back(IncludeLoc);
@@ -166,8 +167,9 @@ class SemaPPCallbacks : public PPCallbacks {
}
case ExitFile:
if (!IncludeStack.empty()) {
- if (llvm::timeTraceProfilerEnabled())
- llvm::timeTraceProfilerEnd();
+ if (llvm::timeTraceProfilerEnabled()) {
+ llvm::timeTraceProfilerEnd(ProfilerStack.pop_back_val());
+ }
S->DiagnoseNonDefaultPragmaAlignPack(
Sema::PragmaAlignPackDiagnoseKind::ChangedStateAtExit,
More information about the cfe-commits
mailing list