1 //===- PseudoProbe.cpp - Pseudo Probe Helpers -----------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements the helpers to manipulate pseudo probe IR intrinsic
12 //===----------------------------------------------------------------------===//
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 #include <unordered_set>
24 Optional
<PseudoProbe
> extractProbeFromDiscriminator(const Instruction
&Inst
) {
25 assert(isa
<CallBase
>(&Inst
) && !isa
<IntrinsicInst
>(&Inst
) &&
26 "Only call instructions should have pseudo probe encodes as their "
27 "Dwarf discriminators");
28 if (const DebugLoc
&DLoc
= Inst
.getDebugLoc()) {
29 const DILocation
*DIL
= DLoc
;
30 auto Discriminator
= DIL
->getDiscriminator();
31 if (DILocation::isPseudoProbeDiscriminator(Discriminator
)) {
34 PseudoProbeDwarfDiscriminator::extractProbeIndex(Discriminator
);
36 PseudoProbeDwarfDiscriminator::extractProbeType(Discriminator
);
38 PseudoProbeDwarfDiscriminator::extractProbeAttributes(Discriminator
);
40 PseudoProbeDwarfDiscriminator::extractProbeFactor(Discriminator
) /
41 (float)PseudoProbeDwarfDiscriminator::FullDistributionFactor
;
48 Optional
<PseudoProbe
> extractProbe(const Instruction
&Inst
) {
49 if (const auto *II
= dyn_cast
<PseudoProbeInst
>(&Inst
)) {
51 Probe
.Id
= II
->getIndex()->getZExtValue();
52 Probe
.Type
= (uint32_t)PseudoProbeType::Block
;
53 Probe
.Attr
= II
->getAttributes()->getZExtValue();
54 Probe
.Factor
= II
->getFactor()->getZExtValue() /
55 (float)PseudoProbeFullDistributionFactor
;
59 if (isa
<CallBase
>(&Inst
) && !isa
<IntrinsicInst
>(&Inst
))
60 return extractProbeFromDiscriminator(Inst
);
65 void setProbeDistributionFactor(Instruction
&Inst
, float Factor
) {
66 assert(Factor
>= 0 && Factor
<= 1 &&
67 "Distribution factor must be in [0, 1.0]");
68 if (auto *II
= dyn_cast
<PseudoProbeInst
>(&Inst
)) {
69 IRBuilder
<> Builder(&Inst
);
70 uint64_t IntFactor
= PseudoProbeFullDistributionFactor
;
73 auto OrigFactor
= II
->getFactor()->getZExtValue();
74 if (IntFactor
!= OrigFactor
)
75 II
->replaceUsesOfWith(II
->getFactor(), Builder
.getInt64(IntFactor
));
76 } else if (isa
<CallBase
>(&Inst
) && !isa
<IntrinsicInst
>(&Inst
)) {
77 if (const DebugLoc
&DLoc
= Inst
.getDebugLoc()) {
78 const DILocation
*DIL
= DLoc
;
79 auto Discriminator
= DIL
->getDiscriminator();
80 if (DILocation::isPseudoProbeDiscriminator(Discriminator
)) {
82 PseudoProbeDwarfDiscriminator::extractProbeIndex(Discriminator
);
84 PseudoProbeDwarfDiscriminator::extractProbeType(Discriminator
);
85 auto Attr
= PseudoProbeDwarfDiscriminator::extractProbeAttributes(
87 // Round small factors to 0 to avoid over-counting.
89 PseudoProbeDwarfDiscriminator::FullDistributionFactor
;
92 uint32_t V
= PseudoProbeDwarfDiscriminator::packProbeData(
93 Index
, Type
, Attr
, IntFactor
);
94 DIL
= DIL
->cloneWithDiscriminator(V
);
95 Inst
.setDebugLoc(DIL
);
101 void addPseudoProbeAttribute(PseudoProbeInst
&Inst
,
102 PseudoProbeAttributes Attr
) {
103 IRBuilder
<> Builder(&Inst
);
104 uint32_t OldAttr
= Inst
.getAttributes()->getZExtValue();
105 uint32_t NewAttr
= OldAttr
| (uint32_t)Attr
;
106 if (OldAttr
!= NewAttr
)
107 Inst
.replaceUsesOfWith(Inst
.getAttributes(), Builder
.getInt32(NewAttr
));