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