@@ -436,10 +436,12 @@ CallStackId hashCallStack(ArrayRef<FrameId> CS) {
436436// To quickly determine the location of the common prefix within RadixArray,
437437// Indexes caches the indexes of the previous call stack's frames within
438438// RadixArray.
439- LinearCallStackId CallStackRadixTreeBuilder::encodeCallStack (
440- const llvm::SmallVector<FrameId> *CallStack,
441- const llvm::SmallVector<FrameId> *Prev,
442- const llvm::DenseMap<FrameId, LinearFrameId> &MemProfFrameIndexes) {
439+ template <typename FrameIdTy>
440+ LinearCallStackId CallStackRadixTreeBuilder<FrameIdTy>::encodeCallStack(
441+ const llvm::SmallVector<FrameIdTy> *CallStack,
442+ const llvm::SmallVector<FrameIdTy> *Prev,
443+ std::optional<const llvm::DenseMap<FrameIdTy, LinearFrameId>>
444+ MemProfFrameIndexes) {
443445 // Compute the length of the common root prefix between Prev and CallStack.
444446 uint32_t CommonLen = 0 ;
445447 if (Prev) {
@@ -464,10 +466,11 @@ LinearCallStackId CallStackRadixTreeBuilder::encodeCallStack(
464466
465467 // Copy the part of the call stack beyond the common prefix to RadixArray.
466468 assert (CommonLen <= CallStack->size ());
467- for (FrameId F : llvm::drop_begin (llvm::reverse (*CallStack), CommonLen)) {
469+ for (FrameIdTy F : llvm::drop_begin (llvm::reverse (*CallStack), CommonLen)) {
468470 // Remember the index of F in RadixArray.
469471 Indexes.push_back (RadixArray.size ());
470- RadixArray.push_back (MemProfFrameIndexes.find (F)->second );
472+ RadixArray.push_back (
473+ MemProfFrameIndexes ? MemProfFrameIndexes->find (F)->second : F);
471474 }
472475 assert (CallStack->size () == Indexes.size ());
473476
@@ -479,11 +482,13 @@ LinearCallStackId CallStackRadixTreeBuilder::encodeCallStack(
479482 return RadixArray.size () - 1 ;
480483}
481484
482- void CallStackRadixTreeBuilder::build (
483- llvm::MapVector<CallStackId, llvm::SmallVector<FrameId>>
485+ template <typename FrameIdTy>
486+ void CallStackRadixTreeBuilder<FrameIdTy>::build(
487+ llvm::MapVector<CallStackId, llvm::SmallVector<FrameIdTy>>
484488 &&MemProfCallStackData,
485- const llvm::DenseMap<FrameId, LinearFrameId> &MemProfFrameIndexes,
486- llvm::DenseMap<FrameId, FrameStat> &FrameHistogram) {
489+ std::optional<const llvm::DenseMap<FrameIdTy, LinearFrameId>>
490+ MemProfFrameIndexes,
491+ llvm::DenseMap<FrameIdTy, FrameStat> &FrameHistogram) {
487492 // Take the vector portion of MemProfCallStackData. The vector is exactly
488493 // what we need to sort. Also, we no longer need its lookup capability.
489494 llvm::SmallVector<CSIdPair, 0 > CallStacks = MemProfCallStackData.takeVector ();
@@ -535,7 +540,7 @@ void CallStackRadixTreeBuilder::build(
535540 // root.
536541 return std::lexicographical_compare (
537542 L.second .rbegin (), L.second .rend (), R.second .rbegin (), R.second .rend (),
538- [&](FrameId F1, FrameId F2) {
543+ [&](FrameIdTy F1, FrameIdTy F2) {
539544 uint64_t H1 = FrameHistogram[F1].Count ;
540545 uint64_t H2 = FrameHistogram[F2].Count ;
541546 // Popular frames should come later because we encode call stacks from
@@ -585,7 +590,7 @@ void CallStackRadixTreeBuilder::build(
585590 // traverse CallStacks in the reverse order, then Call Stack 3 has the
586591 // complete call stack encoded without any pointers. Call Stack 1 and 2 point
587592 // to appropriate prefixes of Call Stack 3.
588- const llvm::SmallVector<FrameId > *Prev = nullptr ;
593+ const llvm::SmallVector<FrameIdTy > *Prev = nullptr ;
589594 for (const auto &[CSId, CallStack] : llvm::reverse (CallStacks)) {
590595 LinearCallStackId Pos =
591596 encodeCallStack (&CallStack, Prev, MemProfFrameIndexes);
@@ -608,10 +613,14 @@ void CallStackRadixTreeBuilder::build(
608613 V = RadixArray.size () - 1 - V;
609614}
610615
611- llvm::DenseMap<FrameId, FrameStat>
612- computeFrameHistogram (llvm::MapVector<CallStackId, llvm::SmallVector<FrameId>>
616+ // Explicitly instantiate class with the utilized FrameIdTy.
617+ template class CallStackRadixTreeBuilder <FrameId>;
618+
619+ template <typename FrameIdTy>
620+ llvm::DenseMap<FrameIdTy, FrameStat>
621+ computeFrameHistogram (llvm::MapVector<CallStackId, llvm::SmallVector<FrameIdTy>>
613622 &MemProfCallStackData) {
614- llvm::DenseMap<FrameId , FrameStat> Histogram;
623+ llvm::DenseMap<FrameIdTy , FrameStat> Histogram;
615624
616625 for (const auto &KV : MemProfCallStackData) {
617626 const auto &CS = KV.second ;
@@ -624,6 +633,11 @@ computeFrameHistogram(llvm::MapVector<CallStackId, llvm::SmallVector<FrameId>>
624633 return Histogram;
625634}
626635
636+ // Explicitly instantiate function with the utilized FrameIdTy.
637+ template llvm::DenseMap<FrameId, FrameStat> computeFrameHistogram<FrameId>(
638+ llvm::MapVector<CallStackId, llvm::SmallVector<FrameId>>
639+ &MemProfCallStackData);
640+
627641void verifyIndexedMemProfRecord (const IndexedMemProfRecord &Record) {
628642 for (const auto &AS : Record.AllocSites ) {
629643 assert (AS.CSId == hashCallStack (AS.CallStack ));
0 commit comments