1 //===- PseudoProbe.cpp - Pseudo Probe Helpers -----------------------------===// 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 the helpers to manipulate pseudo probe IR intrinsic 10 // calls. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/IR/PseudoProbe.h" 15 #include "llvm/IR/DebugInfoMetadata.h" 16 #include "llvm/IR/IRBuilder.h" 17 #include "llvm/IR/Instruction.h" 18 19 using namespace llvm; 20 21 namespace llvm { 22 23 Optional<PseudoProbe> extractProbeFromDiscriminator(const Instruction &Inst) { 24 assert(isa<CallBase>(&Inst) && !isa<IntrinsicInst>(&Inst) && 25 "Only call instructions should have pseudo probe encodes as their " 26 "Dwarf discriminators"); 27 if (const DebugLoc &DLoc = Inst.getDebugLoc()) { 28 const DILocation *DIL = DLoc; 29 auto Discriminator = DIL->getDiscriminator(); 30 if (DILocation::isPseudoProbeDiscriminator(Discriminator)) { 31 PseudoProbe Probe; 32 Probe.Id = 33 PseudoProbeDwarfDiscriminator::extractProbeIndex(Discriminator); 34 Probe.Type = 35 PseudoProbeDwarfDiscriminator::extractProbeType(Discriminator); 36 Probe.Attr = 37 PseudoProbeDwarfDiscriminator::extractProbeAttributes(Discriminator); 38 Probe.Factor = 39 PseudoProbeDwarfDiscriminator::extractProbeFactor(Discriminator) / 40 (float)PseudoProbeDwarfDiscriminator::FullDistributionFactor; 41 return Probe; 42 } 43 } 44 return None; 45 } 46 47 Optional<PseudoProbe> extractProbe(const Instruction &Inst) { 48 if (const auto *II = dyn_cast<PseudoProbeInst>(&Inst)) { 49 PseudoProbe Probe; 50 Probe.Id = II->getIndex()->getZExtValue(); 51 Probe.Type = (uint32_t)PseudoProbeType::Block; 52 Probe.Attr = II->getAttributes()->getZExtValue(); 53 Probe.Factor = II->getFactor()->getZExtValue() / 54 (float)PseudoProbeFullDistributionFactor; 55 return Probe; 56 } 57 58 if (isa<CallBase>(&Inst) && !isa<IntrinsicInst>(&Inst)) 59 return extractProbeFromDiscriminator(Inst); 60 61 return None; 62 } 63 64 void setProbeDistributionFactor(Instruction &Inst, float Factor) { 65 assert(Factor >= 0 && Factor <= 1 && 66 "Distribution factor must be in [0, 1.0]"); 67 if (auto *II = dyn_cast<PseudoProbeInst>(&Inst)) { 68 IRBuilder<> Builder(&Inst); 69 uint64_t IntFactor = PseudoProbeFullDistributionFactor; 70 if (Factor < 1) 71 IntFactor *= Factor; 72 auto OrigFactor = II->getFactor()->getZExtValue(); 73 if (IntFactor != OrigFactor) 74 II->replaceUsesOfWith(II->getFactor(), Builder.getInt64(IntFactor)); 75 } else if (isa<CallBase>(&Inst) && !isa<IntrinsicInst>(&Inst)) { 76 if (const DebugLoc &DLoc = Inst.getDebugLoc()) { 77 const DILocation *DIL = DLoc; 78 auto Discriminator = DIL->getDiscriminator(); 79 if (DILocation::isPseudoProbeDiscriminator(Discriminator)) { 80 auto Index = 81 PseudoProbeDwarfDiscriminator::extractProbeIndex(Discriminator); 82 auto Type = 83 PseudoProbeDwarfDiscriminator::extractProbeType(Discriminator); 84 auto Attr = PseudoProbeDwarfDiscriminator::extractProbeAttributes( 85 Discriminator); 86 // Round small factors to 0 to avoid over-counting. 87 uint32_t IntFactor = 88 PseudoProbeDwarfDiscriminator::FullDistributionFactor; 89 if (Factor < 1) 90 IntFactor *= Factor; 91 uint32_t V = PseudoProbeDwarfDiscriminator::packProbeData( 92 Index, Type, Attr, IntFactor); 93 DIL = DIL->cloneWithDiscriminator(V); 94 Inst.setDebugLoc(DIL); 95 } 96 } 97 } 98 } 99 } // namespace llvm 100