1 //===- llvm/CodeGen/PseudoProbePrinter.cpp - Pseudo Probe Emission -------===// 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 // This file contains support for writing pseudo probe info into asm files. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "PseudoProbePrinter.h" 14 #include "llvm/CodeGen/AsmPrinter.h" 15 #include "llvm/IR/DebugInfoMetadata.h" 16 #include "llvm/IR/Module.h" 17 #include "llvm/IR/PseudoProbe.h" 18 #include "llvm/MC/MCPseudoProbe.h" 19 #include "llvm/MC/MCStreamer.h" 20 21 using namespace llvm; 22 23 #define DEBUG_TYPE "pseudoprobe" 24 25 PseudoProbeHandler::PseudoProbeHandler(AsmPrinter *A, Module *M) : Asm(A) { 26 NamedMDNode *FuncInfo = M->getNamedMetadata(PseudoProbeDescMetadataName); 27 assert(FuncInfo && "Pseudo probe descriptors are missing"); 28 for (const auto *Operand : FuncInfo->operands()) { 29 const auto *MD = cast<MDNode>(Operand); 30 auto GUID = 31 mdconst::dyn_extract<ConstantInt>(MD->getOperand(0))->getZExtValue(); 32 auto Name = cast<MDString>(MD->getOperand(2))->getString(); 33 // We may see pairs with same name but different GUIDs here in LTO mode, due 34 // to static same-named functions inlined from other modules into this 35 // module. Function profiles with the same name will be merged no matter 36 // whether they are collected on the same function. Therefore we just pick 37 // up the last <Name, GUID> pair here to represent the same-named function 38 // collection and all probes from the collection will be merged into a 39 // single profile eventually. 40 Names[Name] = GUID; 41 } 42 43 LLVM_DEBUG(dump()); 44 } 45 46 void PseudoProbeHandler::emitPseudoProbe(uint64_t Guid, uint64_t Index, 47 uint64_t Type, uint64_t Attr, 48 const DILocation *DebugLoc) { 49 // Gather all the inlined-at nodes. 50 // When it's done ReversedInlineStack looks like ([66, B], [88, A]) 51 // which means, Function A inlines function B at calliste with a probe id 88, 52 // and B inlines C at probe 66 where C is represented by Guid. 53 SmallVector<InlineSite, 8> ReversedInlineStack; 54 auto *InlinedAt = DebugLoc ? DebugLoc->getInlinedAt() : nullptr; 55 while (InlinedAt) { 56 const DISubprogram *SP = InlinedAt->getScope()->getSubprogram(); 57 // Use linkage name for C++ if possible. 58 auto Name = SP->getLinkageName(); 59 if (Name.empty()) 60 Name = SP->getName(); 61 assert(Names.count(Name) && "Pseudo probe descriptor missing for function"); 62 uint64_t CallerGuid = Names[Name]; 63 uint64_t CallerProbeId = PseudoProbeDwarfDiscriminator::extractProbeIndex( 64 InlinedAt->getDiscriminator()); 65 ReversedInlineStack.push_back({CallerGuid, CallerProbeId}); 66 InlinedAt = InlinedAt->getInlinedAt(); 67 } 68 69 SmallVector<InlineSite, 8> InlineStack(ReversedInlineStack.rbegin(), 70 ReversedInlineStack.rend()); 71 Asm->OutStreamer->emitPseudoProbe(Guid, Index, Type, Attr, InlineStack); 72 } 73 74 #ifndef NDEBUG 75 void PseudoProbeHandler::dump() const { 76 dbgs() << "\n=============================\n"; 77 dbgs() << "\nFunction Name to GUID map:\n"; 78 dbgs() << "\n=============================\n"; 79 for (const auto &Item : Names) 80 dbgs() << "Func: " << Item.first << " GUID: " << Item.second << "\n"; 81 } 82 #endif 83