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