diff options
author | Teresa Johnson <tejohnson@google.com> | 2024-11-20 10:08:58 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-20 10:08:58 -0800 |
commit | e14827f0828d14ef17ab76316e8449d1b76e2617 (patch) | |
tree | cdc599c1cb9f81ae0b58497367f109ff5c1e1ac8 /llvm/lib | |
parent | 6473a36edc571cf0734a2e8d4354e332efb170e9 (diff) | |
download | llvm-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.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/ProfileData/MemProf.cpp | 44 |
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)); |