aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
authorTeresa Johnson <tejohnson@google.com>2024-11-20 10:08:58 -0800
committerGitHub <noreply@github.com>2024-11-20 10:08:58 -0800
commite14827f0828d14ef17ab76316e8449d1b76e2617 (patch)
treecdc599c1cb9f81ae0b58497367f109ff5c1e1ac8 /llvm/lib
parent6473a36edc571cf0734a2e8d4354e332efb170e9 (diff)
downloadllvm-e14827f0828d14ef17ab76316e8449d1b76e2617.zip
llvm-e14827f0828d14ef17ab76316e8449d1b76e2617.tar.gz
llvm-e14827f0828d14ef17ab76316e8449d1b76e2617.tar.bz2
[MemProf] Templatize CallStackRadixTreeBuilder (NFC) (#117014)
Prepare for usage in the bitcode reader/writer where we already have a LinearFrameId: - templatize input frame id type in CallStackRadixTreeBuilder - templatize input frame id type in computeFrameHistogram - make the map from FrameId to LinearFrameId optional We plan to use the same radix format in the ThinLTO summary records, where we already have a LinearFrameId.
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/ProfileData/InstrProfWriter.cpp2
-rw-r--r--llvm/lib/ProfileData/MemProf.cpp44
2 files changed, 30 insertions, 16 deletions
diff --git a/llvm/lib/ProfileData/InstrProfWriter.cpp b/llvm/lib/ProfileData/InstrProfWriter.cpp
index 5580fe0..d90629a 100644
--- a/llvm/lib/ProfileData/InstrProfWriter.cpp
+++ b/llvm/lib/ProfileData/InstrProfWriter.cpp
@@ -635,7 +635,7 @@ writeMemProfCallStackArray(
llvm::DenseMap<memprof::CallStackId, memprof::LinearCallStackId>
MemProfCallStackIndexes;
- memprof::CallStackRadixTreeBuilder Builder;
+ memprof::CallStackRadixTreeBuilder<memprof::FrameId> Builder;
Builder.build(std::move(MemProfCallStackData), MemProfFrameIndexes,
FrameHistogram);
for (auto I : Builder.getRadixArray())
diff --git a/llvm/lib/ProfileData/MemProf.cpp b/llvm/lib/ProfileData/MemProf.cpp
index 6c4bda2..9d5ac74 100644
--- a/llvm/lib/ProfileData/MemProf.cpp
+++ b/llvm/lib/ProfileData/MemProf.cpp
@@ -436,10 +436,12 @@ CallStackId hashCallStack(ArrayRef<FrameId> CS) {
// To quickly determine the location of the common prefix within RadixArray,
// Indexes caches the indexes of the previous call stack's frames within
// RadixArray.
-LinearCallStackId CallStackRadixTreeBuilder::encodeCallStack(
- const llvm::SmallVector<FrameId> *CallStack,
- const llvm::SmallVector<FrameId> *Prev,
- const llvm::DenseMap<FrameId, LinearFrameId> &MemProfFrameIndexes) {
+template <typename FrameIdTy>
+LinearCallStackId CallStackRadixTreeBuilder<FrameIdTy>::encodeCallStack(
+ const llvm::SmallVector<FrameIdTy> *CallStack,
+ const llvm::SmallVector<FrameIdTy> *Prev,
+ std::optional<const llvm::DenseMap<FrameIdTy, LinearFrameId>>
+ MemProfFrameIndexes) {
// Compute the length of the common root prefix between Prev and CallStack.
uint32_t CommonLen = 0;
if (Prev) {
@@ -464,10 +466,11 @@ LinearCallStackId CallStackRadixTreeBuilder::encodeCallStack(
// Copy the part of the call stack beyond the common prefix to RadixArray.
assert(CommonLen <= CallStack->size());
- for (FrameId F : llvm::drop_begin(llvm::reverse(*CallStack), CommonLen)) {
+ for (FrameIdTy F : llvm::drop_begin(llvm::reverse(*CallStack), CommonLen)) {
// Remember the index of F in RadixArray.
Indexes.push_back(RadixArray.size());
- RadixArray.push_back(MemProfFrameIndexes.find(F)->second);
+ RadixArray.push_back(
+ MemProfFrameIndexes ? MemProfFrameIndexes->find(F)->second : F);
}
assert(CallStack->size() == Indexes.size());
@@ -479,11 +482,13 @@ LinearCallStackId CallStackRadixTreeBuilder::encodeCallStack(
return RadixArray.size() - 1;
}
-void CallStackRadixTreeBuilder::build(
- llvm::MapVector<CallStackId, llvm::SmallVector<FrameId>>
+template <typename FrameIdTy>
+void CallStackRadixTreeBuilder<FrameIdTy>::build(
+ llvm::MapVector<CallStackId, llvm::SmallVector<FrameIdTy>>
&&MemProfCallStackData,
- const llvm::DenseMap<FrameId, LinearFrameId> &MemProfFrameIndexes,
- llvm::DenseMap<FrameId, FrameStat> &FrameHistogram) {
+ std::optional<const llvm::DenseMap<FrameIdTy, LinearFrameId>>
+ MemProfFrameIndexes,
+ llvm::DenseMap<FrameIdTy, FrameStat> &FrameHistogram) {
// Take the vector portion of MemProfCallStackData. The vector is exactly
// what we need to sort. Also, we no longer need its lookup capability.
llvm::SmallVector<CSIdPair, 0> CallStacks = MemProfCallStackData.takeVector();
@@ -535,7 +540,7 @@ void CallStackRadixTreeBuilder::build(
// root.
return std::lexicographical_compare(
L.second.rbegin(), L.second.rend(), R.second.rbegin(), R.second.rend(),
- [&](FrameId F1, FrameId F2) {
+ [&](FrameIdTy F1, FrameIdTy F2) {
uint64_t H1 = FrameHistogram[F1].Count;
uint64_t H2 = FrameHistogram[F2].Count;
// Popular frames should come later because we encode call stacks from
@@ -585,7 +590,7 @@ void CallStackRadixTreeBuilder::build(
// traverse CallStacks in the reverse order, then Call Stack 3 has the
// complete call stack encoded without any pointers. Call Stack 1 and 2 point
// to appropriate prefixes of Call Stack 3.
- const llvm::SmallVector<FrameId> *Prev = nullptr;
+ const llvm::SmallVector<FrameIdTy> *Prev = nullptr;
for (const auto &[CSId, CallStack] : llvm::reverse(CallStacks)) {
LinearCallStackId Pos =
encodeCallStack(&CallStack, Prev, MemProfFrameIndexes);
@@ -608,10 +613,14 @@ void CallStackRadixTreeBuilder::build(
V = RadixArray.size() - 1 - V;
}
-llvm::DenseMap<FrameId, FrameStat>
-computeFrameHistogram(llvm::MapVector<CallStackId, llvm::SmallVector<FrameId>>
+// Explicitly instantiate class with the utilized FrameIdTy.
+template class CallStackRadixTreeBuilder<FrameId>;
+
+template <typename FrameIdTy>
+llvm::DenseMap<FrameIdTy, FrameStat>
+computeFrameHistogram(llvm::MapVector<CallStackId, llvm::SmallVector<FrameIdTy>>
&MemProfCallStackData) {
- llvm::DenseMap<FrameId, FrameStat> Histogram;
+ llvm::DenseMap<FrameIdTy, FrameStat> Histogram;
for (const auto &KV : MemProfCallStackData) {
const auto &CS = KV.second;
@@ -624,6 +633,11 @@ computeFrameHistogram(llvm::MapVector<CallStackId, llvm::SmallVector<FrameId>>
return Histogram;
}
+// Explicitly instantiate function with the utilized FrameIdTy.
+template llvm::DenseMap<FrameId, FrameStat> computeFrameHistogram<FrameId>(
+ llvm::MapVector<CallStackId, llvm::SmallVector<FrameId>>
+ &MemProfCallStackData);
+
void verifyIndexedMemProfRecord(const IndexedMemProfRecord &Record) {
for (const auto &AS : Record.AllocSites) {
assert(AS.CSId == hashCallStack(AS.CallStack));