1 //===- PseudoProbeInserter.cpp - Insert annotation for callsite profiling -===// 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 implements PseudoProbeInserter pass, which inserts pseudo probe 10 // annotations for call instructions with a pseudo-probe-specific dwarf 11 // discriminator. such discriminator indicates that the call instruction comes 12 // with a pseudo probe, and the discriminator value holds information to 13 // identify the corresponding counter. 14 //===----------------------------------------------------------------------===// 15 16 #include "llvm/CodeGen/MachineBasicBlock.h" 17 #include "llvm/CodeGen/MachineFunctionPass.h" 18 #include "llvm/CodeGen/MachineInstr.h" 19 #include "llvm/CodeGen/TargetInstrInfo.h" 20 #include "llvm/IR/DebugInfoMetadata.h" 21 #include "llvm/IR/PseudoProbe.h" 22 #include "llvm/InitializePasses.h" 23 #include "llvm/Target/TargetMachine.h" 24 #include <unordered_map> 25 26 #define DEBUG_TYPE "pseudo-probe-inserter" 27 28 using namespace llvm; 29 30 namespace { 31 class PseudoProbeInserter : public MachineFunctionPass { 32 public: 33 static char ID; 34 35 PseudoProbeInserter() : MachineFunctionPass(ID) { 36 initializePseudoProbeInserterPass(*PassRegistry::getPassRegistry()); 37 } 38 39 StringRef getPassName() const override { return "Pseudo Probe Inserter"; } 40 41 void getAnalysisUsage(AnalysisUsage &AU) const override { 42 AU.setPreservesAll(); 43 MachineFunctionPass::getAnalysisUsage(AU); 44 } 45 46 bool runOnMachineFunction(MachineFunction &MF) override { 47 const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); 48 bool Changed = false; 49 for (MachineBasicBlock &MBB : MF) { 50 for (MachineInstr &MI : MBB) { 51 if (MI.isCall()) { 52 if (DILocation *DL = MI.getDebugLoc()) { 53 auto Value = DL->getDiscriminator(); 54 if (DILocation::isPseudoProbeDiscriminator(Value)) { 55 BuildMI(MBB, MI, DL, TII->get(TargetOpcode::PSEUDO_PROBE)) 56 .addImm(getFuncGUID(MF.getFunction().getParent(), DL)) 57 .addImm( 58 PseudoProbeDwarfDiscriminator::extractProbeIndex(Value)) 59 .addImm( 60 PseudoProbeDwarfDiscriminator::extractProbeType(Value)) 61 .addImm(PseudoProbeDwarfDiscriminator::extractProbeAttributes( 62 Value)); 63 Changed = true; 64 } 65 } 66 } 67 } 68 } 69 70 return Changed; 71 } 72 73 private: 74 uint64_t getFuncGUID(Module *M, DILocation *DL) { 75 auto *SP = DL->getScope()->getSubprogram(); 76 auto Name = SP->getLinkageName(); 77 if (Name.empty()) 78 Name = SP->getName(); 79 return Function::getGUID(Name); 80 } 81 }; 82 } // namespace 83 84 char PseudoProbeInserter::ID = 0; 85 INITIALIZE_PASS_BEGIN(PseudoProbeInserter, DEBUG_TYPE, 86 "Insert pseudo probe annotations for value profiling", 87 false, false) 88 INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) 89 INITIALIZE_PASS_END(PseudoProbeInserter, DEBUG_TYPE, 90 "Insert pseudo probe annotations for value profiling", 91 false, false) 92 93 FunctionPass *llvm::createPseudoProbeInserter() { 94 return new PseudoProbeInserter(); 95 } 96