xref: /llvm-project/llvm/lib/MC/MCPseudoProbe.cpp (revision 7ec682b16b49c754d5b4aa6347f8f5a00bd7dd78)
1 //===- lib/MC/MCPseudoProbe.cpp - Pseudo probe encoding support ----------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/MC/MCPseudoProbe.h"
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/IR/PseudoProbe.h"
12 #include "llvm/MC/MCAsmInfo.h"
13 #include "llvm/MC/MCAssembler.h"
14 #include "llvm/MC/MCContext.h"
15 #include "llvm/MC/MCExpr.h"
16 #include "llvm/MC/MCFragment.h"
17 #include "llvm/MC/MCObjectFileInfo.h"
18 #include "llvm/MC/MCObjectStreamer.h"
19 #include "llvm/MC/MCSymbol.h"
20 #include "llvm/Support/Endian.h"
21 #include "llvm/Support/Error.h"
22 #include "llvm/Support/LEB128.h"
23 #include "llvm/Support/MD5.h"
24 #include "llvm/Support/raw_ostream.h"
25 #include <algorithm>
26 #include <cassert>
27 #include <limits>
28 #include <memory>
29 #include <sstream>
30 #include <vector>
31 
32 #define DEBUG_TYPE "mcpseudoprobe"
33 
34 using namespace llvm;
35 using namespace support;
36 
37 #ifndef NDEBUG
38 int MCPseudoProbeTable::DdgPrintIndent = 0;
39 #endif
40 
41 static const MCExpr *buildSymbolDiff(MCObjectStreamer *MCOS, const MCSymbol *A,
42                                      const MCSymbol *B) {
43   MCContext &Context = MCOS->getContext();
44   MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
45   const MCExpr *ARef = MCSymbolRefExpr::create(A, Variant, Context);
46   const MCExpr *BRef = MCSymbolRefExpr::create(B, Variant, Context);
47   const MCExpr *AddrDelta =
48       MCBinaryExpr::create(MCBinaryExpr::Sub, ARef, BRef, Context);
49   return AddrDelta;
50 }
51 
52 uint64_t MCDecodedPseudoProbe::getGuid() const { return InlineTree->Guid; }
53 
54 void MCPseudoProbe::emit(MCObjectStreamer *MCOS,
55                          const MCPseudoProbe *LastProbe) const {
56   bool IsSentinel = isSentinelProbe(getAttributes());
57   assert((LastProbe || IsSentinel) &&
58          "Last probe should not be null for non-sentinel probes");
59 
60   // Emit Index
61   MCOS->emitULEB128IntValue(Index);
62   // Emit Type and the flag:
63   // Type (bit 0 to 3), with bit 4 to 6 for attributes.
64   // Flag (bit 7, 0 - code address, 1 - address delta). This indicates whether
65   // the following field is a symbolic code address or an address delta.
66   // Emit FS discriminator
67   assert(Type <= 0xF && "Probe type too big to encode, exceeding 15");
68   auto NewAttributes = Attributes;
69   if (Discriminator)
70     NewAttributes |= (uint32_t)PseudoProbeAttributes::HasDiscriminator;
71   assert(NewAttributes <= 0x7 &&
72          "Probe attributes too big to encode, exceeding 7");
73   uint8_t PackedType = Type | (NewAttributes << 4);
74   uint8_t Flag =
75       !IsSentinel ? ((int8_t)MCPseudoProbeFlag::AddressDelta << 7) : 0;
76   MCOS->emitInt8(Flag | PackedType);
77 
78   if (!IsSentinel) {
79     // Emit the delta between the address label and LastProbe.
80     const MCExpr *AddrDelta =
81         buildSymbolDiff(MCOS, Label, LastProbe->getLabel());
82     int64_t Delta;
83     if (AddrDelta->evaluateAsAbsolute(Delta, MCOS->getAssemblerPtr())) {
84       MCOS->emitSLEB128IntValue(Delta);
85     } else {
86       MCOS->insert(MCOS->getContext().allocFragment<MCPseudoProbeAddrFragment>(
87           AddrDelta));
88     }
89   } else {
90     // Emit the GUID of the split function that the sentinel probe represents.
91     MCOS->emitInt64(Guid);
92   }
93 
94   if (Discriminator)
95     MCOS->emitULEB128IntValue(Discriminator);
96 
97   LLVM_DEBUG({
98     dbgs().indent(MCPseudoProbeTable::DdgPrintIndent);
99     dbgs() << "Probe: " << Index << "\n";
100   });
101 }
102 
103 void MCPseudoProbeInlineTree::addPseudoProbe(
104     const MCPseudoProbe &Probe, const MCPseudoProbeInlineStack &InlineStack) {
105   // The function should not be called on the root.
106   assert(isRoot() && "Should only be called on root");
107 
108   // When it comes here, the input look like:
109   //    Probe: GUID of C, ...
110   //    InlineStack: [88, A], [66, B]
111   // which means, Function A inlines function B at call site with a probe id of
112   // 88, and B inlines C at probe 66. The tri-tree expects a tree path like {[0,
113   // A], [88, B], [66, C]} to locate the tree node where the probe should be
114   // added. Note that the edge [0, A] means A is the top-level function we are
115   // emitting probes for.
116 
117   // Make a [0, A] edge.
118   // An empty inline stack means the function that the probe originates from
119   // is a top-level function.
120   InlineSite Top;
121   if (InlineStack.empty()) {
122     Top = InlineSite(Probe.getGuid(), 0);
123   } else {
124     Top = InlineSite(std::get<0>(InlineStack.front()), 0);
125   }
126 
127   auto *Cur = getOrAddNode(Top);
128 
129   // Make interior edges by walking the inline stack. Once it's done, Cur should
130   // point to the node that the probe originates from.
131   if (!InlineStack.empty()) {
132     auto Iter = InlineStack.begin();
133     auto Index = std::get<1>(*Iter);
134     Iter++;
135     for (; Iter != InlineStack.end(); Iter++) {
136       // Make an edge by using the previous probe id and current GUID.
137       Cur = Cur->getOrAddNode(InlineSite(std::get<0>(*Iter), Index));
138       Index = std::get<1>(*Iter);
139     }
140     Cur = Cur->getOrAddNode(InlineSite(Probe.getGuid(), Index));
141   }
142 
143   Cur->Probes.push_back(Probe);
144 }
145 
146 void MCPseudoProbeInlineTree::emit(MCObjectStreamer *MCOS,
147                                    const MCPseudoProbe *&LastProbe) {
148   LLVM_DEBUG({
149     dbgs().indent(MCPseudoProbeTable::DdgPrintIndent);
150     dbgs() << "Group [\n";
151     MCPseudoProbeTable::DdgPrintIndent += 2;
152   });
153   assert(!isRoot() && "Root should be handled separately");
154 
155   // Emit probes grouped by GUID.
156   LLVM_DEBUG({
157     dbgs().indent(MCPseudoProbeTable::DdgPrintIndent);
158     dbgs() << "GUID: " << Guid << "\n";
159   });
160   // Emit Guid
161   MCOS->emitInt64(Guid);
162   // Emit number of probes in this node, including a sentinel probe for
163   // top-level functions if needed.
164   bool NeedSentinel = false;
165   if (Parent->isRoot()) {
166     assert(isSentinelProbe(LastProbe->getAttributes()) &&
167            "Starting probe of a top-level function should be a sentinel probe");
168     // The main body of a split function doesn't need a sentinel probe.
169     if (LastProbe->getGuid() != Guid)
170       NeedSentinel = true;
171   }
172 
173   MCOS->emitULEB128IntValue(Probes.size() + NeedSentinel);
174   // Emit number of direct inlinees
175   MCOS->emitULEB128IntValue(Children.size());
176   // Emit sentinel probe for top-level functions
177   if (NeedSentinel)
178     LastProbe->emit(MCOS, nullptr);
179 
180   // Emit probes in this group
181   for (const auto &Probe : Probes) {
182     Probe.emit(MCOS, LastProbe);
183     LastProbe = &Probe;
184   }
185 
186   // Emit sorted descendant. InlineSite is unique for each pair, so there will
187   // be no ordering of Inlinee based on MCPseudoProbeInlineTree*
188   using InlineeType = std::pair<InlineSite, MCPseudoProbeInlineTree *>;
189   std::vector<InlineeType> Inlinees;
190   for (const auto &Child : Children)
191     Inlinees.emplace_back(Child.first, Child.second.get());
192   llvm::sort(Inlinees, llvm::less_first());
193 
194   for (const auto &Inlinee : Inlinees) {
195     // Emit probe index
196     MCOS->emitULEB128IntValue(std::get<1>(Inlinee.first));
197     LLVM_DEBUG({
198       dbgs().indent(MCPseudoProbeTable::DdgPrintIndent);
199       dbgs() << "InlineSite: " << std::get<1>(Inlinee.first) << "\n";
200     });
201     // Emit the group
202     Inlinee.second->emit(MCOS, LastProbe);
203   }
204 
205   LLVM_DEBUG({
206     MCPseudoProbeTable::DdgPrintIndent -= 2;
207     dbgs().indent(MCPseudoProbeTable::DdgPrintIndent);
208     dbgs() << "]\n";
209   });
210 }
211 
212 void MCPseudoProbeSections::emit(MCObjectStreamer *MCOS) {
213   MCContext &Ctx = MCOS->getContext();
214   SmallVector<std::pair<MCSymbol *, MCPseudoProbeInlineTree *>> Vec;
215   Vec.reserve(MCProbeDivisions.size());
216   for (auto &ProbeSec : MCProbeDivisions)
217     Vec.emplace_back(ProbeSec.first, &ProbeSec.second);
218   for (auto I : llvm::enumerate(MCOS->getAssembler()))
219     I.value().setOrdinal(I.index());
220   llvm::sort(Vec, [](auto A, auto B) {
221     return A.first->getSection().getOrdinal() <
222            B.first->getSection().getOrdinal();
223   });
224   for (auto [FuncSym, RootPtr] : Vec) {
225     const auto &Root = *RootPtr;
226     if (auto *S = Ctx.getObjectFileInfo()->getPseudoProbeSection(
227             FuncSym->getSection())) {
228       // Switch to the .pseudoprobe section or a comdat group.
229       MCOS->switchSection(S);
230       // Emit probes grouped by GUID.
231       // Emit sorted descendant. InlineSite is unique for each pair, so there
232       // will be no ordering of Inlinee based on MCPseudoProbeInlineTree*
233       using InlineeType = std::pair<InlineSite, MCPseudoProbeInlineTree *>;
234       std::vector<InlineeType> Inlinees;
235       for (const auto &Child : Root.getChildren())
236         Inlinees.emplace_back(Child.first, Child.second.get());
237       llvm::sort(Inlinees, llvm::less_first());
238 
239       for (const auto &Inlinee : Inlinees) {
240         // Emit the group guarded by a sentinel probe.
241         MCPseudoProbe SentinelProbe(
242             const_cast<MCSymbol *>(FuncSym), MD5Hash(FuncSym->getName()),
243             (uint32_t)PseudoProbeReservedId::Invalid,
244             (uint32_t)PseudoProbeType::Block,
245             (uint32_t)PseudoProbeAttributes::Sentinel, 0);
246         const MCPseudoProbe *Probe = &SentinelProbe;
247         Inlinee.second->emit(MCOS, Probe);
248       }
249     }
250   }
251 }
252 
253 //
254 // This emits the pseudo probe tables.
255 //
256 void MCPseudoProbeTable::emit(MCObjectStreamer *MCOS) {
257   MCContext &Ctx = MCOS->getContext();
258   auto &ProbeTable = Ctx.getMCPseudoProbeTable();
259 
260   // Bail out early so we don't switch to the pseudo_probe section needlessly
261   // and in doing so create an unnecessary (if empty) section.
262   auto &ProbeSections = ProbeTable.getProbeSections();
263   if (ProbeSections.empty())
264     return;
265 
266   LLVM_DEBUG(MCPseudoProbeTable::DdgPrintIndent = 0);
267 
268   // Put out the probe.
269   ProbeSections.emit(MCOS);
270 }
271 
272 static StringRef getProbeFNameForGUID(const GUIDProbeFunctionMap &GUID2FuncMAP,
273                                       uint64_t GUID) {
274   auto It = GUID2FuncMAP.find(GUID);
275   assert(It != GUID2FuncMAP.end() &&
276          "Probe function must exist for a valid GUID");
277   return It->FuncName;
278 }
279 
280 void MCPseudoProbeFuncDesc::print(raw_ostream &OS) {
281   OS << "GUID: " << FuncGUID << " Name: " << FuncName << "\n";
282   OS << "Hash: " << FuncHash << "\n";
283 }
284 
285 void MCDecodedPseudoProbe::getInlineContext(
286     SmallVectorImpl<MCPseudoProbeFrameLocation> &ContextStack,
287     const GUIDProbeFunctionMap &GUID2FuncMAP) const {
288   uint32_t Begin = ContextStack.size();
289   MCDecodedPseudoProbeInlineTree *Cur = InlineTree;
290   // It will add the string of each node's inline site during iteration.
291   // Note that it won't include the probe's belonging function(leaf location)
292   while (Cur->hasInlineSite()) {
293     StringRef FuncName = getProbeFNameForGUID(GUID2FuncMAP, Cur->Parent->Guid);
294     ContextStack.emplace_back(MCPseudoProbeFrameLocation(
295         FuncName, std::get<1>(Cur->getInlineSite())));
296     Cur = static_cast<MCDecodedPseudoProbeInlineTree *>(Cur->Parent);
297   }
298   // Make the ContextStack in caller-callee order
299   std::reverse(ContextStack.begin() + Begin, ContextStack.end());
300 }
301 
302 std::string MCDecodedPseudoProbe::getInlineContextStr(
303     const GUIDProbeFunctionMap &GUID2FuncMAP) const {
304   std::ostringstream OContextStr;
305   SmallVector<MCPseudoProbeFrameLocation, 16> ContextStack;
306   getInlineContext(ContextStack, GUID2FuncMAP);
307   for (auto &Cxt : ContextStack) {
308     if (OContextStr.str().size())
309       OContextStr << " @ ";
310     OContextStr << Cxt.first.str() << ":" << Cxt.second;
311   }
312   return OContextStr.str();
313 }
314 
315 static const char *PseudoProbeTypeStr[3] = {"Block", "IndirectCall",
316                                             "DirectCall"};
317 
318 void MCDecodedPseudoProbe::print(raw_ostream &OS,
319                                  const GUIDProbeFunctionMap &GUID2FuncMAP,
320                                  bool ShowName) const {
321   OS << "FUNC: ";
322   if (ShowName) {
323     StringRef FuncName = getProbeFNameForGUID(GUID2FuncMAP, getGuid());
324     OS << FuncName.str() << " ";
325   } else {
326     OS << getGuid() << " ";
327   }
328   OS << "Index: " << Index << "  ";
329   if (Discriminator)
330     OS << "Discriminator: " << Discriminator << "  ";
331   OS << "Type: " << PseudoProbeTypeStr[static_cast<uint8_t>(Type)] << "  ";
332   std::string InlineContextStr = getInlineContextStr(GUID2FuncMAP);
333   if (InlineContextStr.size()) {
334     OS << "Inlined: @ ";
335     OS << InlineContextStr;
336   }
337   OS << "\n";
338 }
339 
340 template <typename T> ErrorOr<T> MCPseudoProbeDecoder::readUnencodedNumber() {
341   if (Data + sizeof(T) > End) {
342     return std::error_code();
343   }
344   T Val = endian::readNext<T, llvm::endianness::little>(Data);
345   return ErrorOr<T>(Val);
346 }
347 
348 template <typename T> ErrorOr<T> MCPseudoProbeDecoder::readUnsignedNumber() {
349   unsigned NumBytesRead = 0;
350   uint64_t Val = decodeULEB128(Data, &NumBytesRead);
351   if (Val > std::numeric_limits<T>::max() || (Data + NumBytesRead > End)) {
352     return std::error_code();
353   }
354   Data += NumBytesRead;
355   return ErrorOr<T>(static_cast<T>(Val));
356 }
357 
358 template <typename T> ErrorOr<T> MCPseudoProbeDecoder::readSignedNumber() {
359   unsigned NumBytesRead = 0;
360   int64_t Val = decodeSLEB128(Data, &NumBytesRead);
361   if (Val > std::numeric_limits<T>::max() || (Data + NumBytesRead > End)) {
362     return std::error_code();
363   }
364   Data += NumBytesRead;
365   return ErrorOr<T>(static_cast<T>(Val));
366 }
367 
368 ErrorOr<StringRef> MCPseudoProbeDecoder::readString(uint32_t Size) {
369   StringRef Str(reinterpret_cast<const char *>(Data), Size);
370   if (Data + Size > End) {
371     return std::error_code();
372   }
373   Data += Size;
374   return ErrorOr<StringRef>(Str);
375 }
376 
377 bool MCPseudoProbeDecoder::buildGUID2FuncDescMap(const uint8_t *Start,
378                                                  std::size_t Size,
379                                                  bool IsMMapped) {
380   // The pseudo_probe_desc section has a format like:
381   // .section .pseudo_probe_desc,"",@progbits
382   // .quad -5182264717993193164   // GUID
383   // .quad 4294967295             // Hash
384   // .uleb 3                      // Name size
385   // .ascii "foo"                 // Name
386   // .quad -2624081020897602054
387   // .quad 174696971957
388   // .uleb 34
389   // .ascii "main"
390 
391   Data = Start;
392   End = Data + Size;
393 
394   uint32_t FuncDescCount = 0;
395   while (Data < End) {
396     // GUID
397     if (!readUnencodedNumber<uint64_t>())
398       return false;
399     // Hash
400     if (!readUnencodedNumber<uint64_t>())
401       return false;
402 
403     auto ErrorOrNameSize = readUnsignedNumber<uint32_t>();
404     if (!ErrorOrNameSize)
405       return false;
406     // Function name
407     if (!readString(*ErrorOrNameSize))
408       return false;
409     ++FuncDescCount;
410   }
411   assert(Data == End && "Have unprocessed data in pseudo_probe_desc section");
412   GUID2FuncDescMap.reserve(FuncDescCount);
413 
414   Data = Start;
415   End = Data + Size;
416   while (Data < End) {
417     uint64_t GUID =
418         cantFail(errorOrToExpected(readUnencodedNumber<uint64_t>()));
419     uint64_t Hash =
420         cantFail(errorOrToExpected(readUnencodedNumber<uint64_t>()));
421     uint32_t NameSize =
422         cantFail(errorOrToExpected(readUnsignedNumber<uint32_t>()));
423     StringRef Name = cantFail(errorOrToExpected(readString(NameSize)));
424 
425     // Initialize PseudoProbeFuncDesc and populate it into GUID2FuncDescMap
426     GUID2FuncDescMap.emplace_back(
427         GUID, Hash, IsMMapped ? Name : Name.copy(FuncNameAllocator));
428   }
429   assert(Data == End && "Have unprocessed data in pseudo_probe_desc section");
430   assert(GUID2FuncDescMap.size() == FuncDescCount &&
431          "Mismatching function description count pre- and post-parsing");
432   llvm::sort(GUID2FuncDescMap, [](const auto &LHS, const auto &RHS) {
433     return LHS.FuncGUID < RHS.FuncGUID;
434   });
435   return true;
436 }
437 
438 template <bool IsTopLevelFunc>
439 bool MCPseudoProbeDecoder::buildAddress2ProbeMap(
440     MCDecodedPseudoProbeInlineTree *Cur, uint64_t &LastAddr,
441     const Uint64Set &GuidFilter, const Uint64Map &FuncStartAddrs,
442     const uint32_t CurChildIndex) {
443   // The pseudo_probe section encodes an inline forest and each tree has a
444   // format defined in MCPseudoProbe.h
445 
446   uint32_t Index = 0;
447   if (IsTopLevelFunc) {
448     // Use a sequential id for top level inliner.
449     Index = CurChildIndex;
450   } else {
451     // Read inline site for inlinees
452     Index = cantFail(errorOrToExpected(readUnsignedNumber<uint32_t>()));
453   }
454 
455   // Read guid
456   uint64_t Guid = cantFail(errorOrToExpected(readUnencodedNumber<uint64_t>()));
457 
458   // Decide if top-level node should be disgarded.
459   if (IsTopLevelFunc && !GuidFilter.empty() && !GuidFilter.count(Guid))
460     Cur = nullptr;
461 
462   // If the incoming node is null, all its children nodes should be disgarded.
463   if (Cur) {
464     // Switch/add to a new tree node(inlinee)
465     Cur->getChildren()[CurChildIndex] =
466         MCDecodedPseudoProbeInlineTree(InlineSite(Guid, Index), Cur);
467     Cur = &Cur->getChildren()[CurChildIndex];
468     if (IsTopLevelFunc && !EncodingIsAddrBased) {
469       if (auto V = FuncStartAddrs.lookup(Guid))
470         LastAddr = V;
471     }
472   }
473 
474   // Read number of probes in the current node.
475   uint32_t NodeCount =
476       cantFail(errorOrToExpected(readUnsignedNumber<uint32_t>()));
477   uint32_t CurrentProbeCount = 0;
478   // Read number of direct inlinees
479   uint32_t ChildrenToProcess =
480       cantFail(errorOrToExpected(readUnsignedNumber<uint32_t>()));
481   // Read all probes in this node
482   for (std::size_t I = 0; I < NodeCount; I++) {
483     // Read index
484     uint32_t Index =
485         cantFail(errorOrToExpected(readUnsignedNumber<uint32_t>()));
486     // Read type | flag.
487     uint8_t Value = cantFail(errorOrToExpected(readUnencodedNumber<uint8_t>()));
488     uint8_t Kind = Value & 0xf;
489     uint8_t Attr = (Value & 0x70) >> 4;
490     // Read address
491     uint64_t Addr = 0;
492     if (Value & 0x80) {
493       int64_t Offset = cantFail(errorOrToExpected(readSignedNumber<int64_t>()));
494       Addr = LastAddr + Offset;
495     } else {
496       Addr = cantFail(errorOrToExpected(readUnencodedNumber<int64_t>()));
497       if (isSentinelProbe(Attr)) {
498         // For sentinel probe, the addr field actually stores the GUID of the
499         // split function. Convert it to the real address.
500         if (auto V = FuncStartAddrs.lookup(Addr))
501           Addr = V;
502       } else {
503         // For now we assume all probe encoding should be either based on
504         // leading probe address or function start address.
505         // The scheme is for downwards compatibility.
506         // TODO: retire this scheme once compatibility is no longer an issue.
507         EncodingIsAddrBased = true;
508       }
509     }
510 
511     uint32_t Discriminator = 0;
512     if (hasDiscriminator(Attr)) {
513       Discriminator =
514           cantFail(errorOrToExpected(readUnsignedNumber<uint32_t>()));
515     }
516 
517     if (Cur && !isSentinelProbe(Attr)) {
518       PseudoProbeVec.emplace_back(Addr, Index, PseudoProbeType(Kind), Attr,
519                                   Discriminator, Cur);
520       ++CurrentProbeCount;
521     }
522     LastAddr = Addr;
523   }
524 
525   if (Cur) {
526     Cur->setProbes(
527         MutableArrayRef(PseudoProbeVec).take_back(CurrentProbeCount));
528     InlineTreeVec.resize(InlineTreeVec.size() + ChildrenToProcess);
529     Cur->getChildren() =
530         MutableArrayRef(InlineTreeVec).take_back(ChildrenToProcess);
531   }
532   for (uint32_t I = 0; I < ChildrenToProcess; I++) {
533     buildAddress2ProbeMap<false>(Cur, LastAddr, GuidFilter, FuncStartAddrs, I);
534   }
535   return Cur;
536 }
537 
538 template <bool IsTopLevelFunc>
539 bool MCPseudoProbeDecoder::countRecords(bool &Discard, uint32_t &ProbeCount,
540                                         uint32_t &InlinedCount,
541                                         const Uint64Set &GuidFilter) {
542   if (!IsTopLevelFunc)
543     // Read inline site for inlinees
544     if (!readUnsignedNumber<uint32_t>())
545       return false;
546 
547   // Read guid
548   auto ErrorOrCurGuid = readUnencodedNumber<uint64_t>();
549   if (!ErrorOrCurGuid)
550     return false;
551   uint64_t Guid = std::move(*ErrorOrCurGuid);
552 
553   // Decide if top-level node should be disgarded.
554   if (IsTopLevelFunc) {
555     Discard = !GuidFilter.empty() && !GuidFilter.count(Guid);
556     if (!Discard)
557       // Allocate an entry for top-level function record.
558       ++InlinedCount;
559   }
560 
561   // Read number of probes in the current node.
562   auto ErrorOrNodeCount = readUnsignedNumber<uint32_t>();
563   if (!ErrorOrNodeCount)
564     return false;
565   uint32_t NodeCount = std::move(*ErrorOrNodeCount);
566   uint32_t CurrentProbeCount = 0;
567 
568   // Read number of direct inlinees
569   auto ErrorOrCurChildrenToProcess = readUnsignedNumber<uint32_t>();
570   if (!ErrorOrCurChildrenToProcess)
571     return false;
572   uint32_t ChildrenToProcess = std::move(*ErrorOrCurChildrenToProcess);
573 
574   // Read all probes in this node
575   for (std::size_t I = 0; I < NodeCount; I++) {
576     // Read index
577     if (!readUnsignedNumber<uint32_t>())
578       return false;
579 
580     // Read type | flag.
581     auto ErrorOrValue = readUnencodedNumber<uint8_t>();
582     if (!ErrorOrValue)
583       return false;
584     uint8_t Value = std::move(*ErrorOrValue);
585 
586     uint8_t Attr = (Value & 0x70) >> 4;
587     if (Value & 0x80) {
588       // Offset
589       if (!readSignedNumber<int64_t>())
590         return false;
591     } else {
592       // Addr
593       if (!readUnencodedNumber<int64_t>())
594         return false;
595     }
596 
597     if (hasDiscriminator(Attr))
598       // Discriminator
599       if (!readUnsignedNumber<uint32_t>())
600         return false;
601 
602     if (!Discard && !isSentinelProbe(Attr))
603       ++CurrentProbeCount;
604   }
605 
606   if (!Discard) {
607     ProbeCount += CurrentProbeCount;
608     InlinedCount += ChildrenToProcess;
609   }
610 
611   for (uint32_t I = 0; I < ChildrenToProcess; I++)
612     if (!countRecords<false>(Discard, ProbeCount, InlinedCount, GuidFilter))
613       return false;
614   return true;
615 }
616 
617 bool MCPseudoProbeDecoder::buildAddress2ProbeMap(
618     const uint8_t *Start, std::size_t Size, const Uint64Set &GuidFilter,
619     const Uint64Map &FuncStartAddrs) {
620   // For function records in the order of their appearance in the encoded data
621   // (DFS), count the number of contained probes and inlined function records.
622   uint32_t ProbeCount = 0;
623   uint32_t InlinedCount = 0;
624   uint32_t TopLevelFuncs = 0;
625   Data = Start;
626   End = Data + Size;
627   bool Discard = false;
628   while (Data < End) {
629     if (!countRecords<true>(Discard, ProbeCount, InlinedCount, GuidFilter))
630       return false;
631     TopLevelFuncs += !Discard;
632   }
633   assert(Data == End && "Have unprocessed data in pseudo_probe section");
634   PseudoProbeVec.reserve(ProbeCount);
635   InlineTreeVec.reserve(InlinedCount);
636 
637   // Allocate top-level function records as children of DummyInlineRoot.
638   InlineTreeVec.resize(TopLevelFuncs);
639   DummyInlineRoot.getChildren() = MutableArrayRef(InlineTreeVec);
640 
641   Data = Start;
642   End = Data + Size;
643   uint64_t LastAddr = 0;
644   uint32_t CurChildIndex = 0;
645   while (Data < End)
646     CurChildIndex += buildAddress2ProbeMap<true>(
647         &DummyInlineRoot, LastAddr, GuidFilter, FuncStartAddrs, CurChildIndex);
648   assert(Data == End && "Have unprocessed data in pseudo_probe section");
649   assert(PseudoProbeVec.size() == ProbeCount &&
650          "Mismatching probe count pre- and post-parsing");
651   assert(InlineTreeVec.size() == InlinedCount &&
652          "Mismatching function records count pre- and post-parsing");
653 
654   std::vector<std::pair<uint64_t, uint32_t>> SortedA2P(ProbeCount);
655   for (const auto &[I, Probe] : llvm::enumerate(PseudoProbeVec))
656     SortedA2P[I] = {Probe.getAddress(), I};
657   llvm::sort(SortedA2P);
658   Address2ProbesMap.reserve(ProbeCount);
659   for (const uint32_t I : llvm::make_second_range(SortedA2P))
660     Address2ProbesMap.emplace_back(PseudoProbeVec[I]);
661   SortedA2P.clear();
662   return true;
663 }
664 
665 void MCPseudoProbeDecoder::printGUID2FuncDescMap(raw_ostream &OS) {
666   OS << "Pseudo Probe Desc:\n";
667   for (auto &I : GUID2FuncDescMap)
668     I.print(OS);
669 }
670 
671 void MCPseudoProbeDecoder::printProbeForAddress(raw_ostream &OS,
672                                                 uint64_t Address) {
673   for (const MCDecodedPseudoProbe &Probe : Address2ProbesMap.find(Address)) {
674     OS << " [Probe]:\t";
675     Probe.print(OS, GUID2FuncDescMap, true);
676   }
677 }
678 
679 void MCPseudoProbeDecoder::printProbesForAllAddresses(raw_ostream &OS) {
680   uint64_t PrevAddress = INT64_MAX;
681   for (MCDecodedPseudoProbe &Probe : Address2ProbesMap) {
682     uint64_t Address = Probe.getAddress();
683     if (Address != PrevAddress) {
684       PrevAddress = Address;
685       OS << "Address:\t" << Address << '\n';
686     }
687     OS << " [Probe]:\t";
688     Probe.print(OS, GUID2FuncDescMap, true);
689   }
690 }
691 
692 const MCDecodedPseudoProbe *
693 MCPseudoProbeDecoder::getCallProbeForAddr(uint64_t Address) const {
694   const MCDecodedPseudoProbe *CallProbe = nullptr;
695   for (const MCDecodedPseudoProbe &Probe : Address2ProbesMap.find(Address)) {
696     if (Probe.isCall()) {
697       // Disabling the assert and returning first call probe seen so far.
698       // Subsequent call probes, if any, are ignored. Due to the the way
699       // .pseudo_probe section is decoded, probes of the same-named independent
700       // static functions are merged thus multiple call probes may be seen for a
701       // callsite. This should only happen to compiler-generated statics, with
702       // -funique-internal-linkage-names where user statics get unique names.
703       //
704       // TODO: re-enable or narrow down the assert to static functions only.
705       //
706       // assert(!CallProbe &&
707       //        "There should be only one call probe corresponding to address "
708       //        "which is a callsite.");
709       CallProbe = &Probe;
710       break;
711     }
712   }
713   return CallProbe;
714 }
715 
716 const MCPseudoProbeFuncDesc *
717 MCPseudoProbeDecoder::getFuncDescForGUID(uint64_t GUID) const {
718   auto It = GUID2FuncDescMap.find(GUID);
719   assert(It != GUID2FuncDescMap.end() && "Function descriptor doesn't exist");
720   return &*It;
721 }
722 
723 void MCPseudoProbeDecoder::getInlineContextForProbe(
724     const MCDecodedPseudoProbe *Probe,
725     SmallVectorImpl<MCPseudoProbeFrameLocation> &InlineContextStack,
726     bool IncludeLeaf) const {
727   Probe->getInlineContext(InlineContextStack, GUID2FuncDescMap);
728   if (!IncludeLeaf)
729     return;
730   // Note that the context from probe doesn't include leaf frame,
731   // hence we need to retrieve and prepend leaf if requested.
732   const auto *FuncDesc = getFuncDescForGUID(Probe->getGuid());
733   InlineContextStack.emplace_back(
734       MCPseudoProbeFrameLocation(FuncDesc->FuncName, Probe->getIndex()));
735 }
736 
737 const MCPseudoProbeFuncDesc *MCPseudoProbeDecoder::getInlinerDescForProbe(
738     const MCDecodedPseudoProbe *Probe) const {
739   MCDecodedPseudoProbeInlineTree *InlinerNode = Probe->getInlineTreeNode();
740   if (!InlinerNode->hasInlineSite())
741     return nullptr;
742   return getFuncDescForGUID(InlinerNode->Parent->Guid);
743 }
744