LLVM 20.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/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"
19#include "llvm/MC/MCSymbol.h"
20#include "llvm/Support/Endian.h"
21#include "llvm/Support/LEB128.h"
22#include "llvm/Support/MD5.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
33using namespace llvm;
34using namespace support;
35
36#ifndef NDEBUG
38#endif
39
40static const MCExpr *buildSymbolDiff(MCObjectStreamer *MCOS, const MCSymbol *A,
41 const MCSymbol *B) {
42 MCContext &Context = MCOS->getContext();
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
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
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)
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 {
84 AddrDelta));
85 }
86 } else {
87 // Emit the GUID of the split function that the sentinel probe represents.
88 MCOS->emitInt64(Guid);
89 }
90
91 if (Discriminator)
93
96 dbgs() << "Probe: " << Index << "\n";
97 });
98}
99
101 const MCPseudoProbe &Probe, const MCPseudoProbeInlineStack &InlineStack) {
102 // The function should not be called on the root.
103 assert(isRoot() && "Should only be called on root");
104
105 // When it comes here, the input look like:
106 // Probe: GUID of C, ...
107 // InlineStack: [88, A], [66, B]
108 // which means, Function A inlines function B at call site with a probe id of
109 // 88, and B inlines C at probe 66. The tri-tree expects a tree path like {[0,
110 // A], [88, B], [66, C]} to locate the tree node where the probe should be
111 // added. Note that the edge [0, A] means A is the top-level function we are
112 // emitting probes for.
113
114 // Make a [0, A] edge.
115 // An empty inline stack means the function that the probe originates from
116 // is a top-level function.
117 InlineSite Top;
118 if (InlineStack.empty()) {
119 Top = InlineSite(Probe.getGuid(), 0);
120 } else {
121 Top = InlineSite(std::get<0>(InlineStack.front()), 0);
122 }
123
124 auto *Cur = getOrAddNode(Top);
125
126 // Make interior edges by walking the inline stack. Once it's done, Cur should
127 // point to the node that the probe originates from.
128 if (!InlineStack.empty()) {
129 auto Iter = InlineStack.begin();
130 auto Index = std::get<1>(*Iter);
131 Iter++;
132 for (; Iter != InlineStack.end(); Iter++) {
133 // Make an edge by using the previous probe id and current GUID.
134 Cur = Cur->getOrAddNode(InlineSite(std::get<0>(*Iter), Index));
135 Index = std::get<1>(*Iter);
136 }
137 Cur = Cur->getOrAddNode(InlineSite(Probe.getGuid(), Index));
138 }
139
140 Cur->Probes.push_back(Probe);
141}
142
144 const MCPseudoProbe *&LastProbe) {
145 LLVM_DEBUG({
147 dbgs() << "Group [\n";
149 });
150 assert(!isRoot() && "Root should be handled separately");
151
152 // Emit probes grouped by GUID.
153 LLVM_DEBUG({
155 dbgs() << "GUID: " << Guid << "\n";
156 });
157 // Emit Guid
158 MCOS->emitInt64(Guid);
159 // Emit number of probes in this node, including a sentinel probe for
160 // top-level functions if needed.
161 bool NeedSentinel = false;
162 if (Parent->isRoot()) {
163 assert(isSentinelProbe(LastProbe->getAttributes()) &&
164 "Starting probe of a top-level function should be a sentinel probe");
165 // The main body of a split function doesn't need a sentinel probe.
166 if (LastProbe->getGuid() != Guid)
167 NeedSentinel = true;
168 }
169
170 MCOS->emitULEB128IntValue(Probes.size() + NeedSentinel);
171 // Emit number of direct inlinees
172 MCOS->emitULEB128IntValue(Children.size());
173 // Emit sentinel probe for top-level functions
174 if (NeedSentinel)
175 LastProbe->emit(MCOS, nullptr);
176
177 // Emit probes in this group
178 for (const auto &Probe : Probes) {
179 Probe.emit(MCOS, LastProbe);
180 LastProbe = &Probe;
181 }
182
183 // Emit sorted descendant. InlineSite is unique for each pair, so there will
184 // be no ordering of Inlinee based on MCPseudoProbeInlineTree*
185 using InlineeType = std::pair<InlineSite, MCPseudoProbeInlineTree *>;
186 std::vector<InlineeType> Inlinees;
187 for (const auto &Child : Children)
188 Inlinees.emplace_back(Child.first, Child.second.get());
189 llvm::sort(Inlinees, llvm::less_first());
190
191 for (const auto &Inlinee : Inlinees) {
192 // Emit probe index
193 MCOS->emitULEB128IntValue(std::get<1>(Inlinee.first));
194 LLVM_DEBUG({
196 dbgs() << "InlineSite: " << std::get<1>(Inlinee.first) << "\n";
197 });
198 // Emit the group
199 Inlinee.second->emit(MCOS, LastProbe);
200 }
201
202 LLVM_DEBUG({
205 dbgs() << "]\n";
206 });
207}
208
210 MCContext &Ctx = MCOS->getContext();
212 Vec.reserve(MCProbeDivisions.size());
213 for (auto &ProbeSec : MCProbeDivisions)
214 Vec.emplace_back(ProbeSec.first, &ProbeSec.second);
215 for (auto I : llvm::enumerate(MCOS->getAssembler()))
216 I.value().setOrdinal(I.index());
217 llvm::sort(Vec, [](auto A, auto B) {
218 return A.first->getSection().getOrdinal() <
219 B.first->getSection().getOrdinal();
220 });
221 for (auto [FuncSym, RootPtr] : Vec) {
222 const auto &Root = *RootPtr;
223 if (auto *S = Ctx.getObjectFileInfo()->getPseudoProbeSection(
224 FuncSym->getSection())) {
225 // Switch to the .pseudoprobe section or a comdat group.
226 MCOS->switchSection(S);
227 // Emit probes grouped by GUID.
228 // Emit sorted descendant. InlineSite is unique for each pair, so there
229 // will be no ordering of Inlinee based on MCPseudoProbeInlineTree*
230 using InlineeType = std::pair<InlineSite, MCPseudoProbeInlineTree *>;
231 std::vector<InlineeType> Inlinees;
232 for (const auto &Child : Root.getChildren())
233 Inlinees.emplace_back(Child.first, Child.second.get());
234 llvm::sort(Inlinees, llvm::less_first());
235
236 for (const auto &Inlinee : Inlinees) {
237 // Emit the group guarded by a sentinel probe.
238 MCPseudoProbe SentinelProbe(
239 const_cast<MCSymbol *>(FuncSym), MD5Hash(FuncSym->getName()),
243 const MCPseudoProbe *Probe = &SentinelProbe;
244 Inlinee.second->emit(MCOS, Probe);
245 }
246 }
247 }
248}
249
250//
251// This emits the pseudo probe tables.
252//
254 MCContext &Ctx = MCOS->getContext();
255 auto &ProbeTable = Ctx.getMCPseudoProbeTable();
256
257 // Bail out early so we don't switch to the pseudo_probe section needlessly
258 // and in doing so create an unnecessary (if empty) section.
259 auto &ProbeSections = ProbeTable.getProbeSections();
260 if (ProbeSections.empty())
261 return;
262
264
265 // Put out the probe.
266 ProbeSections.emit(MCOS);
267}
268
270 uint64_t GUID) {
271 auto It = GUID2FuncMAP.find(GUID);
272 assert(It != GUID2FuncMAP.end() &&
273 "Probe function must exist for a valid GUID");
274 return It->second.FuncName;
275}
276
278 OS << "GUID: " << FuncGUID << " Name: " << FuncName << "\n";
279 OS << "Hash: " << FuncHash << "\n";
280}
281
284 const GUIDProbeFunctionMap &GUID2FuncMAP) const {
285 uint32_t Begin = ContextStack.size();
286 MCDecodedPseudoProbeInlineTree *Cur = InlineTree;
287 // It will add the string of each node's inline site during iteration.
288 // Note that it won't include the probe's belonging function(leaf location)
289 while (Cur->hasInlineSite()) {
290 StringRef FuncName = getProbeFNameForGUID(GUID2FuncMAP, Cur->Parent->Guid);
291 ContextStack.emplace_back(
292 MCPseudoProbeFrameLocation(FuncName, std::get<1>(Cur->ISite)));
293 Cur = static_cast<MCDecodedPseudoProbeInlineTree *>(Cur->Parent);
294 }
295 // Make the ContextStack in caller-callee order
296 std::reverse(ContextStack.begin() + Begin, ContextStack.end());
297}
298
300 const GUIDProbeFunctionMap &GUID2FuncMAP) const {
301 std::ostringstream OContextStr;
303 getInlineContext(ContextStack, GUID2FuncMAP);
304 for (auto &Cxt : ContextStack) {
305 if (OContextStr.str().size())
306 OContextStr << " @ ";
307 OContextStr << Cxt.first.str() << ":" << Cxt.second;
308 }
309 return OContextStr.str();
310}
311
312static const char *PseudoProbeTypeStr[3] = {"Block", "IndirectCall",
313 "DirectCall"};
314
316 const GUIDProbeFunctionMap &GUID2FuncMAP,
317 bool ShowName) const {
318 OS << "FUNC: ";
319 if (ShowName) {
320 StringRef FuncName = getProbeFNameForGUID(GUID2FuncMAP, Guid);
321 OS << FuncName.str() << " ";
322 } else {
323 OS << Guid << " ";
324 }
325 OS << "Index: " << Index << " ";
326 if (Discriminator)
327 OS << "Discriminator: " << Discriminator << " ";
328 OS << "Type: " << PseudoProbeTypeStr[static_cast<uint8_t>(Type)] << " ";
329 std::string InlineContextStr = getInlineContextStr(GUID2FuncMAP);
330 if (InlineContextStr.size()) {
331 OS << "Inlined: @ ";
332 OS << InlineContextStr;
333 }
334 OS << "\n";
335}
336
337template <typename T> ErrorOr<T> MCPseudoProbeDecoder::readUnencodedNumber() {
338 if (Data + sizeof(T) > End) {
339 return std::error_code();
340 }
341 T Val = endian::readNext<T, llvm::endianness::little>(Data);
342 return ErrorOr<T>(Val);
343}
344
345template <typename T> ErrorOr<T> MCPseudoProbeDecoder::readUnsignedNumber() {
346 unsigned NumBytesRead = 0;
347 uint64_t Val = decodeULEB128(Data, &NumBytesRead);
348 if (Val > std::numeric_limits<T>::max() || (Data + NumBytesRead > End)) {
349 return std::error_code();
350 }
351 Data += NumBytesRead;
352 return ErrorOr<T>(static_cast<T>(Val));
353}
354
355template <typename T> ErrorOr<T> MCPseudoProbeDecoder::readSignedNumber() {
356 unsigned NumBytesRead = 0;
357 int64_t Val = decodeSLEB128(Data, &NumBytesRead);
358 if (Val > std::numeric_limits<T>::max() || (Data + NumBytesRead > End)) {
359 return std::error_code();
360 }
361 Data += NumBytesRead;
362 return ErrorOr<T>(static_cast<T>(Val));
363}
364
365ErrorOr<StringRef> MCPseudoProbeDecoder::readString(uint32_t Size) {
366 StringRef Str(reinterpret_cast<const char *>(Data), Size);
367 if (Data + Size > End) {
368 return std::error_code();
369 }
370 Data += Size;
371 return ErrorOr<StringRef>(Str);
372}
373
375 std::size_t Size) {
376 // The pseudo_probe_desc section has a format like:
377 // .section .pseudo_probe_desc,"",@progbits
378 // .quad -5182264717993193164 // GUID
379 // .quad 4294967295 // Hash
380 // .uleb 3 // Name size
381 // .ascii "foo" // Name
382 // .quad -2624081020897602054
383 // .quad 174696971957
384 // .uleb 34
385 // .ascii "main"
386
387 Data = Start;
388 End = Data + Size;
389
390 while (Data < End) {
391 auto ErrorOrGUID = readUnencodedNumber<uint64_t>();
392 if (!ErrorOrGUID)
393 return false;
394
395 auto ErrorOrHash = readUnencodedNumber<uint64_t>();
396 if (!ErrorOrHash)
397 return false;
398
399 auto ErrorOrNameSize = readUnsignedNumber<uint32_t>();
400 if (!ErrorOrNameSize)
401 return false;
402 uint32_t NameSize = std::move(*ErrorOrNameSize);
403
404 auto ErrorOrName = readString(NameSize);
405 if (!ErrorOrName)
406 return false;
407
408 uint64_t GUID = std::move(*ErrorOrGUID);
409 uint64_t Hash = std::move(*ErrorOrHash);
410 StringRef Name = std::move(*ErrorOrName);
411
412 // Initialize PseudoProbeFuncDesc and populate it into GUID2FuncDescMap
413 GUID2FuncDescMap.emplace(GUID, MCPseudoProbeFuncDesc(GUID, Hash, Name));
414 }
415 assert(Data == End && "Have unprocessed data in pseudo_probe_desc section");
416 return true;
417}
418
421 const Uint64Set &GuidFilter, const Uint64Map &FuncStartAddrs) {
422 // The pseudo_probe section encodes an inline forest and each tree has a
423 // format defined in MCPseudoProbe.h
424
425 uint32_t Index = 0;
426 bool IsTopLevelFunc = Cur == &DummyInlineRoot;
427 if (IsTopLevelFunc) {
428 // Use a sequential id for top level inliner.
429 Index = Cur->getChildren().size();
430 } else {
431 // Read inline site for inlinees
432 auto ErrorOrIndex = readUnsignedNumber<uint32_t>();
433 if (!ErrorOrIndex)
434 return false;
435 Index = std::move(*ErrorOrIndex);
436 }
437
438 // Read guid
439 auto ErrorOrCurGuid = readUnencodedNumber<uint64_t>();
440 if (!ErrorOrCurGuid)
441 return false;
442 uint64_t Guid = std::move(*ErrorOrCurGuid);
443
444 // Decide if top-level node should be disgarded.
445 if (IsTopLevelFunc && !GuidFilter.empty() && !GuidFilter.count(Guid))
446 Cur = nullptr;
447
448 // If the incoming node is null, all its children nodes should be disgarded.
449 if (Cur) {
450 // Switch/add to a new tree node(inlinee)
451 Cur = Cur->getOrAddNode(std::make_tuple(Guid, Index));
452 Cur->Guid = Guid;
453 if (IsTopLevelFunc && !EncodingIsAddrBased) {
454 if (auto V = FuncStartAddrs.lookup(Guid))
455 LastAddr = V;
456 }
457 }
458
459 // Read number of probes in the current node.
460 auto ErrorOrNodeCount = readUnsignedNumber<uint32_t>();
461 if (!ErrorOrNodeCount)
462 return false;
463 uint32_t NodeCount = std::move(*ErrorOrNodeCount);
464 // Read number of direct inlinees
465 auto ErrorOrCurChildrenToProcess = readUnsignedNumber<uint32_t>();
466 if (!ErrorOrCurChildrenToProcess)
467 return false;
468 // Read all probes in this node
469 for (std::size_t I = 0; I < NodeCount; I++) {
470 // Read index
471 auto ErrorOrIndex = readUnsignedNumber<uint32_t>();
472 if (!ErrorOrIndex)
473 return false;
474 uint32_t Index = std::move(*ErrorOrIndex);
475 // Read type | flag.
476 auto ErrorOrValue = readUnencodedNumber<uint8_t>();
477 if (!ErrorOrValue)
478 return false;
479 uint8_t Value = std::move(*ErrorOrValue);
480 uint8_t Kind = Value & 0xf;
481 uint8_t Attr = (Value & 0x70) >> 4;
482 // Read address
483 uint64_t Addr = 0;
484 if (Value & 0x80) {
485 auto ErrorOrOffset = readSignedNumber<int64_t>();
486 if (!ErrorOrOffset)
487 return false;
488 int64_t Offset = std::move(*ErrorOrOffset);
489 Addr = LastAddr + Offset;
490 } else {
491 auto ErrorOrAddr = readUnencodedNumber<int64_t>();
492 if (!ErrorOrAddr)
493 return false;
494 Addr = std::move(*ErrorOrAddr);
495 if (isSentinelProbe(Attr)) {
496 // For sentinel probe, the addr field actually stores the GUID of the
497 // split function. Convert it to the real address.
498 if (auto V = FuncStartAddrs.lookup(Addr))
499 Addr = V;
500 } else {
501 // For now we assume all probe encoding should be either based on
502 // leading probe address or function start address.
503 // The scheme is for downwards compatibility.
504 // TODO: retire this scheme once compatibility is no longer an issue.
505 EncodingIsAddrBased = true;
506 }
507 }
508
509 uint32_t Discriminator = 0;
510 if (hasDiscriminator(Attr)) {
511 auto ErrorOrDiscriminator = readUnsignedNumber<uint32_t>();
512 if (!ErrorOrDiscriminator)
513 return false;
514 Discriminator = std::move(*ErrorOrDiscriminator);
515 }
516
517 if (Cur && !isSentinelProbe(Attr)) {
518 // Populate Address2ProbesMap
519 auto &Probes = Address2ProbesMap[Addr];
520 Probes.emplace_back(Addr, Cur->Guid, Index, PseudoProbeType(Kind), Attr,
521 Discriminator, Cur);
522 Cur->addProbes(&Probes.back());
523 }
524 LastAddr = Addr;
525 }
526
527 uint32_t ChildrenToProcess = std::move(*ErrorOrCurChildrenToProcess);
528 for (uint32_t I = 0; I < ChildrenToProcess; I++) {
529 buildAddress2ProbeMap(Cur, LastAddr, GuidFilter, FuncStartAddrs);
530 }
531
532 return true;
533}
534
536 const uint8_t *Start, std::size_t Size, const Uint64Set &GuidFilter,
537 const Uint64Map &FuncStartAddrs) {
538 Data = Start;
539 End = Data + Size;
540 uint64_t LastAddr = 0;
541 while (Data < End)
542 buildAddress2ProbeMap(&DummyInlineRoot, LastAddr, GuidFilter,
543 FuncStartAddrs);
544 assert(Data == End && "Have unprocessed data in pseudo_probe section");
545 return true;
546}
547
549 OS << "Pseudo Probe Desc:\n";
550 // Make the output deterministic
551 std::map<uint64_t, MCPseudoProbeFuncDesc> OrderedMap(GUID2FuncDescMap.begin(),
552 GUID2FuncDescMap.end());
553 for (auto &I : OrderedMap) {
554 I.second.print(OS);
555 }
556}
557
560 auto It = Address2ProbesMap.find(Address);
561 if (It != Address2ProbesMap.end()) {
562 for (const MCDecodedPseudoProbe &Probe : It->second) {
563 OS << " [Probe]:\t";
564 Probe.print(OS, GUID2FuncDescMap, true);
565 }
566 }
567}
568
570 auto Entries = make_first_range(Address2ProbesMap);
571 SmallVector<uint64_t, 0> Addresses(Entries.begin(), Entries.end());
572 llvm::sort(Addresses);
573 for (auto K : Addresses) {
574 OS << "Address:\t";
575 OS << K;
576 OS << "\n";
578 }
579}
580
583 auto It = Address2ProbesMap.find(Address);
584 if (It == Address2ProbesMap.end())
585 return nullptr;
586 const auto &Probes = It->second;
587
588 const MCDecodedPseudoProbe *CallProbe = nullptr;
589 for (const MCDecodedPseudoProbe &Probe : Probes) {
590 if (Probe.isCall()) {
591 // Disabling the assert and returning first call probe seen so far.
592 // Subsequent call probes, if any, are ignored. Due to the the way
593 // .pseudo_probe section is decoded, probes of the same-named independent
594 // static functions are merged thus multiple call probes may be seen for a
595 // callsite. This should only happen to compiler-generated statics, with
596 // -funique-internal-linkage-names where user statics get unique names.
597 //
598 // TODO: re-enable or narrow down the assert to static functions only.
599 //
600 // assert(!CallProbe &&
601 // "There should be only one call probe corresponding to address "
602 // "which is a callsite.");
603 CallProbe = &Probe;
604 break;
605 }
606 }
607 return CallProbe;
608}
609
612 auto It = GUID2FuncDescMap.find(GUID);
613 assert(It != GUID2FuncDescMap.end() && "Function descriptor doesn't exist");
614 return &It->second;
615}
616
618 const MCDecodedPseudoProbe *Probe,
620 bool IncludeLeaf) const {
621 Probe->getInlineContext(InlineContextStack, GUID2FuncDescMap);
622 if (!IncludeLeaf)
623 return;
624 // Note that the context from probe doesn't include leaf frame,
625 // hence we need to retrieve and prepend leaf if requested.
626 const auto *FuncDesc = getFuncDescForGUID(Probe->getGuid());
627 InlineContextStack.emplace_back(
628 MCPseudoProbeFrameLocation(FuncDesc->FuncName, Probe->getIndex()));
629}
630
632 const MCDecodedPseudoProbe *Probe) const {
634 if (!InlinerNode->hasInlineSite())
635 return nullptr;
636 return getFuncDescForGUID(InlinerNode->Parent->Guid);
637}
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, SMLoc Loc)
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
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some templates that are useful if you are working with the STL at all.
raw_pwrite_stream & OS
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:194
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:182
@ Sub
Subtraction.
Definition: MCExpr.h:513
Context object for machine code objects.
Definition: MCContext.h:83
MCPseudoProbeTable & getMCPseudoProbeTable()
Definition: MCContext.h:844
const MCObjectFileInfo * getObjectFileInfo() const
Definition: MCContext.h:416
F * allocFragment(Args &&...args)
Definition: MCContext.h:440
void print(raw_ostream &OS, const GUIDProbeFunctionMap &GUID2FuncMAP, bool ShowName) const
std::string getInlineContextStr(const GUIDProbeFunctionMap &GUID2FuncMAP) const
MCDecodedPseudoProbeInlineTree * getInlineTreeNode() const
void getInlineContext(SmallVectorImpl< MCPseudoProbeFrameLocation > &ContextStack, const GUIDProbeFunctionMap &GUID2FuncMAP) const
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:34
MCSection * getPseudoProbeSection(const MCSection &TextSec) const
Streaming object file generation interface.
MCAssembler & getAssembler()
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 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)
void getInlineContextForProbe(const MCDecodedPseudoProbe *Probe, SmallVectorImpl< MCPseudoProbeFrameLocation > &InlineContextStack, bool IncludeLeaf) const
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:300
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:161
void emitInt64(uint64_t Value)
Definition: MCStreamer.h:720
virtual void switchSection(MCSection *Section, uint32_t Subsec=0)
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:171
void emitInt8(uint64_t Value)
Definition: MCStreamer.h:717
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:393
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:586
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:950
void reserve(size_type N)
Definition: SmallVector.h:676
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
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:215
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:282
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
uint64_t MD5Hash(const FunctionId &Obj)
Definition: FunctionId.h:167
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
PseudoProbeType
Definition: PseudoProbe.h:29
static bool isSentinelProbe(uint32_t Flags)
Definition: PseudoProbe.h:128
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition: STLExtras.h:2431
std::tuple< uint64_t, uint32_t > InlineSite
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:131
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:165
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1647
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
auto make_first_range(ContainerTy &&c)
Given a container of pairs, return a range over the first elements.
Definition: STLExtras.h:1422
static bool hasDiscriminator(uint32_t Flags)
Definition: PseudoProbe.h:132
std::pair< StringRef, uint32_t > MCPseudoProbeFrameLocation
std::unordered_map< uint64_t, MCPseudoProbeFuncDesc > GUIDProbeFunctionMap
void print(raw_ostream &OS)
Function object to check whether the first component of a container supported by std::get (like std::...
Definition: STLExtras.h:1450