LLVM 17.0.0git
MCPseudoProbe.cpp
Go to the documentation of this file.
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
10#include "llvm/ADT/STLExtras.h"
11#include "llvm/MC/MCAsmInfo.h"
12#include "llvm/MC/MCContext.h"
13#include "llvm/MC/MCExpr.h"
14#include "llvm/MC/MCFragment.h"
17#include "llvm/MC/MCSymbol.h"
18#include "llvm/Support/Endian.h"
19#include "llvm/Support/LEB128.h"
20#include "llvm/Support/MD5.h"
22#include <algorithm>
23#include <cassert>
24#include <limits>
25#include <memory>
26#include <sstream>
27#include <vector>
28
29#define DEBUG_TYPE "mcpseudoprobe"
30
31using namespace llvm;
32using namespace support;
33
34#ifndef NDEBUG
36#endif
37
38static const MCExpr *buildSymbolDiff(MCObjectStreamer *MCOS, const MCSymbol *A,
39 const MCSymbol *B) {
40 MCContext &Context = MCOS->getContext();
42 const MCExpr *ARef = MCSymbolRefExpr::create(A, Variant, Context);
43 const MCExpr *BRef = MCSymbolRefExpr::create(B, Variant, Context);
44 const MCExpr *AddrDelta =
46 return AddrDelta;
47}
48
50 const MCPseudoProbe *LastProbe) const {
51 bool IsSentinel = isSentinelProbe(getAttributes());
52 assert((LastProbe || IsSentinel) &&
53 "Last probe should not be null for non-sentinel probes");
54
55 // Emit Index
57 // Emit Type and the flag:
58 // Type (bit 0 to 3), with bit 4 to 6 for attributes.
59 // Flag (bit 7, 0 - code address, 1 - address delta). This indicates whether
60 // the following field is a symbolic code address or an address delta.
61 assert(Type <= 0xF && "Probe type too big to encode, exceeding 15");
62 assert(Attributes <= 0x7 &&
63 "Probe attributes too big to encode, exceeding 7");
64 uint8_t PackedType = Type | (Attributes << 4);
65 uint8_t Flag =
66 !IsSentinel ? ((int8_t)MCPseudoProbeFlag::AddressDelta << 7) : 0;
67 MCOS->emitInt8(Flag | PackedType);
68
69 if (!IsSentinel) {
70 // Emit the delta between the address label and LastProbe.
71 const MCExpr *AddrDelta =
72 buildSymbolDiff(MCOS, Label, LastProbe->getLabel());
73 int64_t Delta;
74 if (AddrDelta->evaluateAsAbsolute(Delta, MCOS->getAssemblerPtr())) {
75 MCOS->emitSLEB128IntValue(Delta);
76 } else {
77 MCOS->insert(new MCPseudoProbeAddrFragment(AddrDelta));
78 }
79 } else {
80 // Emit the GUID of the split function that the sentinel probe represents.
81 MCOS->emitInt64(Guid);
82 }
83
86 dbgs() << "Probe: " << Index << "\n";
87 });
88}
89
91 const MCPseudoProbe &Probe, const MCPseudoProbeInlineStack &InlineStack) {
92 // The function should not be called on the root.
93 assert(isRoot() && "Should only be called on root");
94
95 // When it comes here, the input look like:
96 // Probe: GUID of C, ...
97 // InlineStack: [88, A], [66, B]
98 // which means, Function A inlines function B at call site with a probe id of
99 // 88, and B inlines C at probe 66. The tri-tree expects a tree path like {[0,
100 // A], [88, B], [66, C]} to locate the tree node where the probe should be
101 // added. Note that the edge [0, A] means A is the top-level function we are
102 // emitting probes for.
103
104 // Make a [0, A] edge.
105 // An empty inline stack means the function that the probe originates from
106 // is a top-level function.
107 InlineSite Top;
108 if (InlineStack.empty()) {
109 Top = InlineSite(Probe.getGuid(), 0);
110 } else {
111 Top = InlineSite(std::get<0>(InlineStack.front()), 0);
112 }
113
114 auto *Cur = getOrAddNode(Top);
115
116 // Make interior edges by walking the inline stack. Once it's done, Cur should
117 // point to the node that the probe originates from.
118 if (!InlineStack.empty()) {
119 auto Iter = InlineStack.begin();
120 auto Index = std::get<1>(*Iter);
121 Iter++;
122 for (; Iter != InlineStack.end(); Iter++) {
123 // Make an edge by using the previous probe id and current GUID.
124 Cur = Cur->getOrAddNode(InlineSite(std::get<0>(*Iter), Index));
125 Index = std::get<1>(*Iter);
126 }
127 Cur = Cur->getOrAddNode(InlineSite(Probe.getGuid(), Index));
128 }
129
130 Cur->Probes.push_back(Probe);
131}
132
134 const MCPseudoProbe *&LastProbe) {
135 LLVM_DEBUG({
137 dbgs() << "Group [\n";
139 });
140 assert(!isRoot() && "Root should be handled seperately");
141
142 // Emit probes grouped by GUID.
143 LLVM_DEBUG({
145 dbgs() << "GUID: " << Guid << "\n";
146 });
147 // Emit Guid
148 MCOS->emitInt64(Guid);
149 // Emit number of probes in this node, including a sentinel probe for
150 // top-level functions if needed.
151 bool NeedSentinel = false;
152 if (Parent->isRoot()) {
153 assert(isSentinelProbe(LastProbe->getAttributes()) &&
154 "Starting probe of a top-level function should be a sentinel probe");
155 // The main body of a split function doesn't need a sentinel probe.
156 if (LastProbe->getGuid() != Guid)
157 NeedSentinel = true;
158 }
159
160 MCOS->emitULEB128IntValue(Probes.size() + NeedSentinel);
161 // Emit number of direct inlinees
162 MCOS->emitULEB128IntValue(Children.size());
163 // Emit sentinel probe for top-level functions
164 if (NeedSentinel)
165 LastProbe->emit(MCOS, nullptr);
166
167 // Emit probes in this group
168 for (const auto &Probe : Probes) {
169 Probe.emit(MCOS, LastProbe);
170 LastProbe = &Probe;
171 }
172
173 // Emit sorted descendant. InlineSite is unique for each pair, so there will
174 // be no ordering of Inlinee based on MCPseudoProbeInlineTree*
175 using InlineeType = std::pair<InlineSite, MCPseudoProbeInlineTree *>;
176 auto Comparer = [](const InlineeType &A, const InlineeType &B) {
177 return A.first < B.first;
178 };
179 std::vector<InlineeType> Inlinees;
180 for (const auto &Child : Children)
181 Inlinees.emplace_back(Child.first, Child.second.get());
182 std::sort(Inlinees.begin(), Inlinees.end(), Comparer);
183
184 for (const auto &Inlinee : Inlinees) {
185 // Emit probe index
186 MCOS->emitULEB128IntValue(std::get<1>(Inlinee.first));
187 LLVM_DEBUG({
189 dbgs() << "InlineSite: " << std::get<1>(Inlinee.first) << "\n";
190 });
191 // Emit the group
192 Inlinee.second->emit(MCOS, LastProbe);
193 }
194
195 LLVM_DEBUG({
198 dbgs() << "]\n";
199 });
200}
201
203 MCContext &Ctx = MCOS->getContext();
204 for (auto &ProbeSec : MCProbeDivisions) {
205 const auto *FuncSym = ProbeSec.first;
206 const auto &Root = ProbeSec.second;
207 if (auto *S = Ctx.getObjectFileInfo()->getPseudoProbeSection(
208 FuncSym->getSection())) {
209 // Switch to the .pseudoprobe section or a comdat group.
210 MCOS->switchSection(S);
211 // Emit probes grouped by GUID.
212 // Emit sorted descendant. InlineSite is unique for each pair, so there
213 // will be no ordering of Inlinee based on MCPseudoProbeInlineTree*
214 using InlineeType = std::pair<InlineSite, MCPseudoProbeInlineTree *>;
215 auto Comparer = [](const InlineeType &A, const InlineeType &B) {
216 return A.first < B.first;
217 };
218 std::vector<InlineeType> Inlinees;
219 for (const auto &Child : Root.getChildren())
220 Inlinees.emplace_back(Child.first, Child.second.get());
221 std::sort(Inlinees.begin(), Inlinees.end(), Comparer);
222
223 for (const auto &Inlinee : Inlinees) {
224 // Emit the group guarded by a sentinel probe.
225 MCPseudoProbe SentinelProbe(const_cast<MCSymbol *>(FuncSym),
226 MD5Hash(FuncSym->getName()),
230 const MCPseudoProbe *Probe = &SentinelProbe;
231 Inlinee.second->emit(MCOS, Probe);
232 }
233 }
234 }
235}
236
237//
238// This emits the pseudo probe tables.
239//
241 MCContext &Ctx = MCOS->getContext();
242 auto &ProbeTable = Ctx.getMCPseudoProbeTable();
243
244 // Bail out early so we don't switch to the pseudo_probe section needlessly
245 // and in doing so create an unnecessary (if empty) section.
246 auto &ProbeSections = ProbeTable.getProbeSections();
247 if (ProbeSections.empty())
248 return;
249
251
252 // Put out the probe.
253 ProbeSections.emit(MCOS);
254}
255
257 uint64_t GUID) {
258 auto It = GUID2FuncMAP.find(GUID);
259 assert(It != GUID2FuncMAP.end() &&
260 "Probe function must exist for a valid GUID");
261 return It->second.FuncName;
262}
263
265 OS << "GUID: " << FuncGUID << " Name: " << FuncName << "\n";
266 OS << "Hash: " << FuncHash << "\n";
267}
268
271 const GUIDProbeFunctionMap &GUID2FuncMAP) const {
272 uint32_t Begin = ContextStack.size();
273 MCDecodedPseudoProbeInlineTree *Cur = InlineTree;
274 // It will add the string of each node's inline site during iteration.
275 // Note that it won't include the probe's belonging function(leaf location)
276 while (Cur->hasInlineSite()) {
277 StringRef FuncName = getProbeFNameForGUID(GUID2FuncMAP, Cur->Parent->Guid);
278 ContextStack.emplace_back(
279 MCPseduoProbeFrameLocation(FuncName, std::get<1>(Cur->ISite)));
280 Cur = static_cast<MCDecodedPseudoProbeInlineTree *>(Cur->Parent);
281 }
282 // Make the ContextStack in caller-callee order
283 std::reverse(ContextStack.begin() + Begin, ContextStack.end());
284}
285
287 const GUIDProbeFunctionMap &GUID2FuncMAP) const {
288 std::ostringstream OContextStr;
290 getInlineContext(ContextStack, GUID2FuncMAP);
291 for (auto &Cxt : ContextStack) {
292 if (OContextStr.str().size())
293 OContextStr << " @ ";
294 OContextStr << Cxt.first.str() << ":" << Cxt.second;
295 }
296 return OContextStr.str();
297}
298
299static const char *PseudoProbeTypeStr[3] = {"Block", "IndirectCall",
300 "DirectCall"};
301
303 const GUIDProbeFunctionMap &GUID2FuncMAP,
304 bool ShowName) const {
305 OS << "FUNC: ";
306 if (ShowName) {
307 StringRef FuncName = getProbeFNameForGUID(GUID2FuncMAP, Guid);
308 OS << FuncName.str() << " ";
309 } else {
310 OS << Guid << " ";
311 }
312 OS << "Index: " << Index << " ";
313 OS << "Type: " << PseudoProbeTypeStr[static_cast<uint8_t>(Type)] << " ";
314 std::string InlineContextStr = getInlineContextStr(GUID2FuncMAP);
315 if (InlineContextStr.size()) {
316 OS << "Inlined: @ ";
317 OS << InlineContextStr;
318 }
319 OS << "\n";
320}
321
322template <typename T> ErrorOr<T> MCPseudoProbeDecoder::readUnencodedNumber() {
323 if (Data + sizeof(T) > End) {
324 return std::error_code();
325 }
326 T Val = endian::readNext<T, little, unaligned>(Data);
327 return ErrorOr<T>(Val);
328}
329
330template <typename T> ErrorOr<T> MCPseudoProbeDecoder::readUnsignedNumber() {
331 unsigned NumBytesRead = 0;
332 uint64_t Val = decodeULEB128(Data, &NumBytesRead);
333 if (Val > std::numeric_limits<T>::max() || (Data + NumBytesRead > End)) {
334 return std::error_code();
335 }
336 Data += NumBytesRead;
337 return ErrorOr<T>(static_cast<T>(Val));
338}
339
340template <typename T> ErrorOr<T> MCPseudoProbeDecoder::readSignedNumber() {
341 unsigned NumBytesRead = 0;
342 int64_t Val = decodeSLEB128(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
350ErrorOr<StringRef> MCPseudoProbeDecoder::readString(uint32_t Size) {
351 StringRef Str(reinterpret_cast<const char *>(Data), Size);
352 if (Data + Size > End) {
353 return std::error_code();
354 }
355 Data += Size;
356 return ErrorOr<StringRef>(Str);
357}
358
360 std::size_t Size) {
361 // The pseudo_probe_desc section has a format like:
362 // .section .pseudo_probe_desc,"",@progbits
363 // .quad -5182264717993193164 // GUID
364 // .quad 4294967295 // Hash
365 // .uleb 3 // Name size
366 // .ascii "foo" // Name
367 // .quad -2624081020897602054
368 // .quad 174696971957
369 // .uleb 34
370 // .ascii "main"
371
372 Data = Start;
373 End = Data + Size;
374
375 while (Data < End) {
376 auto ErrorOrGUID = readUnencodedNumber<uint64_t>();
377 if (!ErrorOrGUID)
378 return false;
379
380 auto ErrorOrHash = readUnencodedNumber<uint64_t>();
381 if (!ErrorOrHash)
382 return false;
383
384 auto ErrorOrNameSize = readUnsignedNumber<uint32_t>();
385 if (!ErrorOrNameSize)
386 return false;
387 uint32_t NameSize = std::move(*ErrorOrNameSize);
388
389 auto ErrorOrName = readString(NameSize);
390 if (!ErrorOrName)
391 return false;
392
393 uint64_t GUID = std::move(*ErrorOrGUID);
394 uint64_t Hash = std::move(*ErrorOrHash);
395 StringRef Name = std::move(*ErrorOrName);
396
397 // Initialize PseudoProbeFuncDesc and populate it into GUID2FuncDescMap
398 GUID2FuncDescMap.emplace(GUID, MCPseudoProbeFuncDesc(GUID, Hash, Name));
399 }
400 assert(Data == End && "Have unprocessed data in pseudo_probe_desc section");
401 return true;
402}
403
406 const Uint64Set &GuidFilter, const Uint64Map &FuncStartAddrs) {
407 // The pseudo_probe section encodes an inline forest and each tree has a
408 // format defined in MCPseudoProbe.h
409
410 uint32_t Index = 0;
411 bool IsTopLevelFunc = Cur == &DummyInlineRoot;
412 if (IsTopLevelFunc) {
413 // Use a sequential id for top level inliner.
414 Index = Cur->getChildren().size();
415 } else {
416 // Read inline site for inlinees
417 auto ErrorOrIndex = readUnsignedNumber<uint32_t>();
418 if (!ErrorOrIndex)
419 return false;
420 Index = std::move(*ErrorOrIndex);
421 }
422
423 // Read guid
424 auto ErrorOrCurGuid = readUnencodedNumber<uint64_t>();
425 if (!ErrorOrCurGuid)
426 return false;
427 uint64_t Guid = std::move(*ErrorOrCurGuid);
428
429 // Decide if top-level node should be disgarded.
430 if (IsTopLevelFunc && !GuidFilter.empty() && !GuidFilter.count(Guid))
431 Cur = nullptr;
432
433 // If the incoming node is null, all its children nodes should be disgarded.
434 if (Cur) {
435 // Switch/add to a new tree node(inlinee)
436 Cur = Cur->getOrAddNode(std::make_tuple(Guid, Index));
437 Cur->Guid = Guid;
438 if (IsTopLevelFunc && !EncodingIsAddrBased) {
439 if (auto V = FuncStartAddrs.lookup(Guid))
440 LastAddr = V;
441 }
442 }
443
444 // Read number of probes in the current node.
445 auto ErrorOrNodeCount = readUnsignedNumber<uint32_t>();
446 if (!ErrorOrNodeCount)
447 return false;
448 uint32_t NodeCount = std::move(*ErrorOrNodeCount);
449 // Read number of direct inlinees
450 auto ErrorOrCurChildrenToProcess = readUnsignedNumber<uint32_t>();
451 if (!ErrorOrCurChildrenToProcess)
452 return false;
453 // Read all probes in this node
454 for (std::size_t I = 0; I < NodeCount; I++) {
455 // Read index
456 auto ErrorOrIndex = readUnsignedNumber<uint32_t>();
457 if (!ErrorOrIndex)
458 return false;
459 uint32_t Index = std::move(*ErrorOrIndex);
460 // Read type | flag.
461 auto ErrorOrValue = readUnencodedNumber<uint8_t>();
462 if (!ErrorOrValue)
463 return false;
464 uint8_t Value = std::move(*ErrorOrValue);
465 uint8_t Kind = Value & 0xf;
466 uint8_t Attr = (Value & 0x70) >> 4;
467 // Read address
468 uint64_t Addr = 0;
469 if (Value & 0x80) {
470 auto ErrorOrOffset = readSignedNumber<int64_t>();
471 if (!ErrorOrOffset)
472 return false;
473 int64_t Offset = std::move(*ErrorOrOffset);
474 Addr = LastAddr + Offset;
475 } else {
476 auto ErrorOrAddr = readUnencodedNumber<int64_t>();
477 if (!ErrorOrAddr)
478 return false;
479 Addr = std::move(*ErrorOrAddr);
480 if (isSentinelProbe(Attr)) {
481 // For sentinel probe, the addr field actually stores the GUID of the
482 // split function. Convert it to the real address.
483 if (auto V = FuncStartAddrs.lookup(Addr))
484 Addr = V;
485 } else {
486 // For now we assume all probe encoding should be either based on
487 // leading probe address or function start address.
488 // The scheme is for downwards compatibility.
489 // TODO: retire this scheme once compatibility is no longer an issue.
490 EncodingIsAddrBased = true;
491 }
492 }
493
494 if (Cur && !isSentinelProbe(Attr)) {
495 // Populate Address2ProbesMap
496 auto &Probes = Address2ProbesMap[Addr];
497 Probes.emplace_back(Addr, Cur->Guid, Index, PseudoProbeType(Kind), Attr,
498 Cur);
499 Cur->addProbes(&Probes.back());
500 }
501 LastAddr = Addr;
502 }
503
504 uint32_t ChildrenToProcess = std::move(*ErrorOrCurChildrenToProcess);
505 for (uint32_t I = 0; I < ChildrenToProcess; I++) {
506 buildAddress2ProbeMap(Cur, LastAddr, GuidFilter, FuncStartAddrs);
507 }
508
509 return true;
510}
511
513 const uint8_t *Start, std::size_t Size, const Uint64Set &GuidFilter,
514 const Uint64Map &FuncStartAddrs) {
515 Data = Start;
516 End = Data + Size;
517 uint64_t LastAddr = 0;
518 while (Data < End)
519 buildAddress2ProbeMap(&DummyInlineRoot, LastAddr, GuidFilter,
520 FuncStartAddrs);
521 assert(Data == End && "Have unprocessed data in pseudo_probe section");
522 return true;
523}
524
526 OS << "Pseudo Probe Desc:\n";
527 // Make the output deterministic
528 std::map<uint64_t, MCPseudoProbeFuncDesc> OrderedMap(GUID2FuncDescMap.begin(),
529 GUID2FuncDescMap.end());
530 for (auto &I : OrderedMap) {
531 I.second.print(OS);
532 }
533}
534
537 auto It = Address2ProbesMap.find(Address);
538 if (It != Address2ProbesMap.end()) {
539 for (auto &Probe : It->second) {
540 OS << " [Probe]:\t";
541 Probe.print(OS, GUID2FuncDescMap, true);
542 }
543 }
544}
545
547 std::vector<uint64_t> Addresses;
548 for (auto Entry : Address2ProbesMap)
549 Addresses.push_back(Entry.first);
550 llvm::sort(Addresses);
551 for (auto K : Addresses) {
552 OS << "Address:\t";
553 OS << K;
554 OS << "\n";
556 }
557}
558
561 auto It = Address2ProbesMap.find(Address);
562 if (It == Address2ProbesMap.end())
563 return nullptr;
564 const auto &Probes = It->second;
565
566 const MCDecodedPseudoProbe *CallProbe = nullptr;
567 for (const auto &Probe : Probes) {
568 if (Probe.isCall()) {
569 assert(!CallProbe &&
570 "There should be only one call probe corresponding to address "
571 "which is a callsite.");
572 CallProbe = &Probe;
573 }
574 }
575 return CallProbe;
576}
577
580 auto It = GUID2FuncDescMap.find(GUID);
581 assert(It != GUID2FuncDescMap.end() && "Function descriptor doesn't exist");
582 return &It->second;
583}
584
586 const MCDecodedPseudoProbe *Probe,
588 bool IncludeLeaf) const {
589 Probe->getInlineContext(InlineContextStack, GUID2FuncDescMap);
590 if (!IncludeLeaf)
591 return;
592 // Note that the context from probe doesn't include leaf frame,
593 // hence we need to retrieve and prepend leaf if requested.
594 const auto *FuncDesc = getFuncDescForGUID(Probe->getGuid());
595 InlineContextStack.emplace_back(
596 MCPseduoProbeFrameLocation(FuncDesc->FuncName, Probe->getIndex()));
597}
598
600 const MCDecodedPseudoProbe *Probe) const {
602 if (!InlinerNode->hasInlineSite())
603 return nullptr;
604 return getFuncDescForGUID(InlinerNode->Parent->Guid);
605}
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_DEBUG(X)
Definition: Debug.h:101
uint64_t Addr
std::string Name
uint64_t Size
static const MCExpr * buildSymbolDiff(MCObjectStreamer &OS, const MCSymbol *A, const MCSymbol *B)
static const char * PseudoProbeTypeStr[3]
static StringRef getProbeFNameForGUID(const GUIDProbeFunctionMap &GUID2FuncMAP, uint64_t GUID)
static const MCExpr * buildSymbolDiff(MCObjectStreamer *MCOS, const MCSymbol *A, const MCSymbol *B)
#define I(x, y, z)
Definition: MD5.cpp:58
LLVMContext & Context
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some templates that are useful if you are working with the STL at all.
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition: DenseMap.h:197
Represents either an error or a value T.
Definition: ErrorOr.h:56
static const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition: MCExpr.cpp:183
@ Sub
Subtraction.
Definition: MCExpr.h:506
Context object for machine code objects.
Definition: MCContext.h:76
MCPseudoProbeTable & getMCPseudoProbeTable()
Definition: MCContext.h:864
const MCObjectFileInfo * getObjectFileInfo() const
Definition: MCContext.h:450
void print(raw_ostream &OS, const GUIDProbeFunctionMap &GUID2FuncMAP, bool ShowName) const
std::string getInlineContextStr(const GUIDProbeFunctionMap &GUID2FuncMAP) const
void getInlineContext(SmallVectorImpl< MCPseduoProbeFrameLocation > &ContextStack, const GUIDProbeFunctionMap &GUID2FuncMAP) const
MCDecodedPseudoProbeInlineTree * getInlineTreeNode() const
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
MCSection * getPseudoProbeSection(const MCSection &TextSec) const
Streaming object file generation interface.
MCAssembler * getAssemblerPtr() override
void insert(MCFragment *F)
uint64_t getGuid() const
uint8_t getAttributes() const
uint64_t getIndex() const
bool buildAddress2ProbeMap(const uint8_t *Start, std::size_t Size, const Uint64Set &GuildFilter, const Uint64Map &FuncStartAddrs)
void getInlineContextForProbe(const MCDecodedPseudoProbe *Probe, SmallVectorImpl< MCPseduoProbeFrameLocation > &InlineContextStack, bool IncludeLeaf) const
void printProbesForAllAddresses(raw_ostream &OS)
bool buildGUID2FuncDescMap(const uint8_t *Start, std::size_t Size)
void printGUID2FuncDescMap(raw_ostream &OS)
void printProbeForAddress(raw_ostream &OS, uint64_t Address)
const MCPseudoProbeFuncDesc * getInlinerDescForProbe(const MCDecodedPseudoProbe *Probe) const
const MCDecodedPseudoProbe * getCallProbeForAddr(uint64_t Address) const
const MCPseudoProbeFuncDesc * getFuncDescForGUID(uint64_t GUID) const
InlinedProbeTreeMap & getChildren()
MCPseudoProbeInlineTreeBase< MCPseudoProbe, MCPseudoProbeInlineTree > * Parent
void addProbes(ProbeType Probe)
MCPseudoProbeInlineTree * getOrAddNode(const InlineSite &Site)
void emit(MCObjectStreamer *MCOS, const MCPseudoProbe *&LastProbe)
void addPseudoProbe(const MCPseudoProbe &Probe, const MCPseudoProbeInlineStack &InlineStack)
void emit(MCObjectStreamer *MCOS)
MCPseudoProbeSections & getProbeSections()
static void emit(MCObjectStreamer *MCOS)
Instances of this class represent a pseudo probe instance for a pseudo probe table entry,...
MCSymbol * getLabel() const
void emit(MCObjectStreamer *MCOS, const MCPseudoProbe *LastProbe) const
MCContext & getContext() const
Definition: MCStreamer.h:297
unsigned emitULEB128IntValue(uint64_t Value, unsigned PadTo=0)
Special case of EmitULEB128Value that avoids the client having to pass in a MCExpr for constant integ...
Definition: MCStreamer.cpp:162
void emitInt64(uint64_t Value)
Definition: MCStreamer.h:749
virtual void switchSection(MCSection *Section, const MCExpr *Subsection=nullptr)
Set the current section where code is being emitted to Section.
unsigned emitSLEB128IntValue(int64_t Value)
Special case of EmitSLEB128Value that avoids the client having to pass in a MCExpr for constant integ...
Definition: MCStreamer.cpp:172
void emitInt8(uint64_t Value)
Definition: MCStreamer.h:746
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:386
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
bool empty() const
Definition: SmallVector.h:94
size_t size() const
Definition: SmallVector.h:91
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:577
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:941
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:222
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:295
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVM Value Representation.
Definition: Value.h:74
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
Definition: DenseSet.h:97
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
constexpr size_t NameSize
Definition: XCOFF.h:29
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:406
PseudoProbeType
Definition: PseudoProbe.h:29
static bool isSentinelProbe(uint32_t Flags)
Definition: PseudoProbe.h:90
std::tuple< uint64_t, uint32_t > InlineSite
Definition: MCPseudoProbe.h:96
uint64_t decodeULEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a ULEB128 value.
Definition: LEB128.h:128
std::pair< StringRef, uint32_t > MCPseduoProbeFrameLocation
int64_t decodeSLEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a SLEB128 value.
Definition: LEB128.h:161
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1683
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
uint64_t MD5Hash(StringRef Str)
Helper to compute and return lower 64 bits of the given string's MD5 hash.
Definition: MD5.h:109
std::unordered_map< uint64_t, MCPseudoProbeFuncDesc > GUIDProbeFunctionMap
void print(raw_ostream &OS)