LLVM  13.0.0git
PseudoProbe.cpp
Go to the documentation of this file.
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"
16 #include "llvm/IR/IRBuilder.h"
17 #include "llvm/IR/Instruction.h"
18 #include <unordered_set>
19 
20 using namespace llvm;
21 
22 namespace llvm {
23 
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)) {
32  PseudoProbe Probe;
33  Probe.Id =
35  Probe.Type =
37  Probe.Attr =
39  Probe.Factor =
42  return Probe;
43  }
44  }
45  return None;
46 }
47 
49  if (const auto *II = dyn_cast<PseudoProbeInst>(&Inst)) {
50  PseudoProbe Probe;
51  Probe.Id = II->getIndex()->getZExtValue();
53  Probe.Attr = II->getAttributes()->getZExtValue();
54  Probe.Factor = II->getFactor()->getZExtValue() /
56  return Probe;
57  }
58 
59  if (isa<CallBase>(&Inst) && !isa<IntrinsicInst>(&Inst))
60  return extractProbeFromDiscriminator(Inst);
61 
62  return None;
63 }
64 
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;
71  if (Factor < 1)
72  IntFactor *= Factor;
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)) {
81  auto Index =
83  auto Type =
86  Discriminator);
87  // Round small factors to 0 to avoid over-counting.
88  uint32_t IntFactor =
90  if (Factor < 1)
91  IntFactor *= Factor;
93  Index, Type, Attr, IntFactor);
94  DIL = DIL->cloneWithDiscriminator(V);
95  Inst.setDebugLoc(DIL);
96  }
97  }
98  }
99 }
100 
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));
108 }
109 
110 /// A block emptied (i.e., with all instructions moved out of it) won't be
111 /// sampled at run time. In such cases, AutoFDO will be informed of zero samples
112 /// collected for the block. This is not accurate and could lead to misleading
113 /// weights assigned for the block. A way to mitigate that is to treat such
114 /// block as having unknown counts in the AutoFDO profile loader and allow the
115 /// counts inference tool a chance to calculate a relatively reasonable weight
116 /// for it. This can be done by moving all pseudo probes in the emptied block
117 /// i.e, /c From, to before /c To and tag them dangling. Note that this is
118 /// not needed for dead blocks which really have a zero weight. It's per
119 /// transforms to decide whether to call this function or not.
122  for (auto &I : *From) {
123  if (auto *II = dyn_cast<PseudoProbeInst>(&I)) {
125  ToBeMoved.push_back(II);
126  }
127  }
128 
129  for (auto *I : ToBeMoved)
130  I->moveBefore(To);
131 
132  return !ToBeMoved.empty();
133 }
134 
135 /// Same dangling probes in one blocks are redundant since they all have the
136 /// same semantic that is to rely on the counts inference too to get reasonable
137 /// count for the same original block. Therefore, there's no need to keep
138 /// multiple copies of them.
140 
141  auto Hash = [](const PseudoProbeInst *I) {
142  return std::hash<uint64_t>()(I->getFuncGuid()->getZExtValue()) ^
143  std::hash<uint64_t>()(I->getIndex()->getZExtValue());
144  };
145 
146  auto IsEqual = [](const PseudoProbeInst *Left, const PseudoProbeInst *Right) {
147  return Left->getFuncGuid() == Right->getFuncGuid() &&
148  Left->getIndex() == Right->getIndex() &&
149  Left->getAttributes() == Right->getAttributes() &&
150  Left->getDebugLoc() == Right->getDebugLoc();
151  };
152 
154  std::unordered_set<PseudoProbeInst *, decltype(Hash), decltype(IsEqual)>
155  DanglingProbes(0, Hash, IsEqual);
156 
157  for (auto &I : *Block) {
158  if (auto *II = dyn_cast<PseudoProbeInst>(&I)) {
159  if (II->getAttributes()->getZExtValue() &
161  if (!DanglingProbes.insert(II).second)
162  ToBeRemoved.push_back(II);
163  }
164  }
165 
166  for (auto *I : ToBeRemoved)
167  I->eraseFromParent();
168  return !ToBeRemoved.empty();
169 }
170 } // namespace llvm
llvm::PseudoProbeFullDistributionFactor
constexpr static uint64_t PseudoProbeFullDistributionFactor
Definition: PseudoProbe.h:36
llvm::PseudoProbeDwarfDiscriminator::extractProbeAttributes
static uint32_t extractProbeAttributes(uint32_t Value)
Definition: PseudoProbe.h:67
llvm
Definition: AllocatorList.h:23
llvm::moveAndDanglePseudoProbes
bool moveAndDanglePseudoProbes(BasicBlock *From, Instruction *To)
A block emptied (i.e., with all instructions moved out of it) won't be sampled at run time.
Definition: PseudoProbe.cpp:120
llvm::PseudoProbeInst
Definition: IntrinsicInst.h:1159
llvm::PseudoProbeDwarfDiscriminator::FullDistributionFactor
constexpr static uint8_t FullDistributionFactor
Definition: PseudoProbe.h:76
DebugInfoMetadata.h
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1167
llvm::IRBuilder<>
llvm::DILocation::isPseudoProbeDiscriminator
static bool isPseudoProbeDiscriminator(unsigned Discriminator)
Definition: DebugInfoMetadata.h:1683
Right
Vector Shift Left Right
Definition: README_P9.txt:118
llvm::DILocation
Debug location.
Definition: DebugInfoMetadata.h:1562
llvm::PseudoProbeDwarfDiscriminator::extractProbeType
static uint32_t extractProbeType(uint32_t Value)
Definition: PseudoProbe.h:63
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:46
llvm::PseudoProbeAttributes
PseudoProbeAttributes
Definition: PseudoProbe.h:30
llvm::DILocation::cloneWithDiscriminator
const DILocation * cloneWithDiscriminator(unsigned Discriminator) const
Returns a new DILocation with updated Discriminator.
Definition: DebugInfoMetadata.h:2184
llvm::Optional
Definition: APInt.h:33
llvm::PseudoProbe::Factor
float Factor
Definition: PseudoProbe.h:86
llvm::PseudoProbeDwarfDiscriminator::extractProbeFactor
static uint32_t extractProbeFactor(uint32_t Value)
Definition: PseudoProbe.h:71
llvm::PseudoProbeDwarfDiscriminator::packProbeData
static uint32_t packProbeData(uint32_t Index, uint32_t Type, uint32_t Flags, uint32_t Factor)
Definition: PseudoProbe.h:49
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
llvm::PseudoProbe::Id
uint32_t Id
Definition: PseudoProbe.h:80
llvm::AlignStyle::Left
@ Left
Instruction.h
llvm::addPseudoProbeAttribute
void addPseudoProbeAttribute(PseudoProbeInst &Inst, PseudoProbeAttributes Attr)
Definition: PseudoProbe.cpp:101
llvm::PseudoProbeAttributes::Dangling
@ Dangling
llvm::Instruction
Definition: Instruction.h:45
llvm::setProbeDistributionFactor
void setProbeDistributionFactor(Instruction &Inst, float Factor)
Definition: PseudoProbe.cpp:65
llvm::removeRedundantPseudoProbes
bool removeRedundantPseudoProbes(BasicBlock *Block)
Same dangling probes in one blocks are redundant since they all have the same semantic that is to rel...
Definition: PseudoProbe.cpp:139
llvm::None
const NoneType None
Definition: None.h:23
llvm::PseudoProbe::Type
uint32_t Type
Definition: PseudoProbe.h:81
Index
uint32_t Index
Definition: ELFObjHandler.cpp:84
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::Instruction::setDebugLoc
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
Definition: Instruction.h:367
IRBuilder.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::User::replaceUsesOfWith
void replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Definition: User.cpp:21
llvm::PseudoProbeDwarfDiscriminator::extractProbeIndex
static uint32_t extractProbeIndex(uint32_t Value)
Definition: PseudoProbe.h:59
Builder
assume Assume Builder
Definition: AssumeBundleBuilder.cpp:651
llvm::PseudoProbeInst::getAttributes
ConstantInt * getAttributes() const
Definition: IntrinsicInst.h:1177
uint32_t
llvm::ConstantInt::getZExtValue
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
Definition: Constants.h:140
llvm::extractProbeFromDiscriminator
Optional< PseudoProbe > extractProbeFromDiscriminator(const Instruction &Inst)
Definition: PseudoProbe.cpp:24
PseudoProbe.h
llvm::extractProbe
Optional< PseudoProbe > extractProbe(const Instruction &Inst)
Definition: PseudoProbe.cpp:48
llvm::PseudoProbeType::Block
@ Block
llvm::Instruction::getDebugLoc
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
Definition: Instruction.h:370
llvm::PseudoProbe
Definition: PseudoProbe.h:79
llvm::PseudoProbe::Attr
uint32_t Attr
Definition: PseudoProbe.h:82
From
BlockVerifier::State From
Definition: BlockVerifier.cpp:55
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33