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