[llvm] [memprof] Add CallStackRadixTreeBuilder (PR #93784)

Teresa Johnson via llvm-commits llvm-commits at lists.llvm.org
Sun Jun 2 08:20:48 PDT 2024


================
@@ -410,6 +410,161 @@ CallStackId hashCallStack(ArrayRef<FrameId> CS) {
   return CSId;
 }
 
+// Returns the sorted list of call stacks.
+std::vector<CallStackRadixTreeBuilder::CSIdPair>
+CallStackRadixTreeBuilder::sortCallStacks(
+    llvm::MapVector<CallStackId, llvm::SmallVector<FrameId>>
+        &MemProfCallStackData) {
+  // Create a list of call stacks to be sorted.
+  std::vector<CSIdPair> CallStacks;
+  CallStacks.reserve(MemProfCallStackData.size());
+  for (auto &[CSId, CallStack] : MemProfCallStackData) {
+    CallStacks.emplace_back(CSId, &CallStack);
+  }
+
+  // Sort the list of call stacks in the dictionary order to maximize the length
+  // of the common prefix between two adjacent call stacks.
+  auto LessThan = [&](const CSIdPair &L, const CSIdPair &R) {
+    // Call stacks are stored from leaf to root.  Perform comparisons from the
+    // root.
+    return std::lexicographical_compare(
+        L.second->rbegin(), L.second->rend(), R.second->rbegin(),
+        R.second->rend(), [&](FrameId F1, FrameId F2) { return F1 < F2; });
+  };
+  llvm::sort(CallStacks, LessThan);
+
+  return CallStacks;
+}
+
+// Encode a call stack into RadixArray.  Return the starting index within
+// RadixArray.  For each call stack we encode, we emit two or three components
+// into RadixArray.  If a given call stack doesn't have a common prefix relative
+// to the previous one, we emit:
+//
+// - the frames in the given call stack in the reverse order
+//
+// - the length of the given call stack
+//
+// If a given call stack has a non-empty common prefix relative to the previous
+// one, we emit:
+//
+// - the relative location of the common prefix, encoded as a negative number.
+//
+// - a portion of the given call stack that's beyond the common prefix
+//
+// - the length of the given call stack, including the length of the common
+//   prefix.
+//
+// To quickly determine the location of the common prefix within RadixArray,
+// Indexes caches the indexes of the previous call stack's frames within
+// RadixArray.
+uint32_t CallStackRadixTreeBuilder::encodeCallStack(
+    const llvm::SmallVector<FrameId> *CallStack,
+    const llvm::SmallVector<FrameId> *Prev,
+    const llvm::DenseMap<FrameId, uint32_t> &MemProfFrameIndexes) {
+  // Compute the length of the common prefix between Prev and CallStack.
----------------
teresajohnson wrote:

maybe "common root prefix"?

https://github.com/llvm/llvm-project/pull/93784


More information about the llvm-commits mailing list