xref: /freebsd/contrib/llvm-project/llvm/lib/IR/PseudoProbe.cpp (revision 77013d11e6483b970af25e13c9b892075742f7e5)
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