LLVM  15.0.0git
PseudoProbeInserter.cpp
Go to the documentation of this file.
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 
21 #include "llvm/IR/Module.h"
22 #include "llvm/IR/PseudoProbe.h"
23 #include "llvm/InitializePasses.h"
24 
25 #define DEBUG_TYPE "pseudo-probe-inserter"
26 
27 using namespace llvm;
28 
29 namespace {
30 class PseudoProbeInserter : public MachineFunctionPass {
31 public:
32  static char ID;
33 
34  PseudoProbeInserter() : MachineFunctionPass(ID) {
36  }
37 
38  StringRef getPassName() const override { return "Pseudo Probe Inserter"; }
39 
40  void getAnalysisUsage(AnalysisUsage &AU) const override {
41  AU.setPreservesAll();
43  }
44 
45  bool doInitialization(Module &M) override {
46  ShouldRun = M.getNamedMetadata(PseudoProbeDescMetadataName);
47  return false;
48  }
49 
50  bool runOnMachineFunction(MachineFunction &MF) override {
51  if (!ShouldRun)
52  return false;
54  bool Changed = false;
55  for (MachineBasicBlock &MBB : MF) {
56  MachineInstr *FirstInstr = nullptr;
57  for (MachineInstr &MI : MBB) {
58  if (!MI.isPseudo())
59  FirstInstr = &MI;
60  if (MI.isCall()) {
61  if (DILocation *DL = MI.getDebugLoc()) {
62  auto Value = DL->getDiscriminator();
65  .addImm(getFuncGUID(MF.getFunction().getParent(), DL))
66  .addImm(
68  .addImm(
71  Value));
72  Changed = true;
73  }
74  }
75  }
76  }
77 
78  // Walk the block backwards, move PSEUDO_PROBE before the first real
79  // instruction to fix out-of-order probes. There is a problem with probes
80  // as the terminator of the block. During the offline counts processing,
81  // the samples collected on the first physical instruction following a
82  // probe will be counted towards the probe. This logically equals to
83  // treating the instruction next to a probe as if it is from the same
84  // block of the probe. This is accurate most of the time unless the
85  // instruction can be reached from multiple flows, which means it actually
86  // starts a new block. Samples collected on such probes may cause
87  // imprecision with the counts inference algorithm. Fortunately, if
88  // there are still other native instructions preceding the probe we can
89  // use them as a place holder to collect samples for the probe.
90  if (FirstInstr) {
91  auto MII = MBB.rbegin();
92  while (MII != MBB.rend()) {
93  // Skip all pseudo probes followed by a real instruction since they
94  // are not dangling.
95  if (!MII->isPseudo())
96  break;
97  auto Cur = MII++;
98  if (Cur->getOpcode() != TargetOpcode::PSEUDO_PROBE)
99  continue;
100  // Move the dangling probe before FirstInstr.
101  auto *ProbeInstr = &*Cur;
102  MBB.remove(ProbeInstr);
103  MBB.insert(FirstInstr, ProbeInstr);
104  Changed = true;
105  }
106  } else {
107  // Probes not surrounded by any real instructions in the same block are
108  // called dangling probes. Since there's no good way to pick up a sample
109  // collection point for dangling probes at compile time, they are being
110  // removed so that the profile correlation tool will not report any
111  // samples collected for them and it's up to the counts inference tool
112  // to get them a reasonable count.
113  SmallVector<MachineInstr *, 4> ToBeRemoved;
114  for (MachineInstr &MI : MBB) {
115  if (MI.isPseudoProbe())
116  ToBeRemoved.push_back(&MI);
117  }
118 
119  for (auto *MI : ToBeRemoved)
120  MI->eraseFromParent();
121 
122  Changed |= !ToBeRemoved.empty();
123  }
124  }
125 
126  return Changed;
127  }
128 
129 private:
130  uint64_t getFuncGUID(Module *M, DILocation *DL) {
131  auto *SP = DL->getScope()->getSubprogram();
132  auto Name = SP->getLinkageName();
133  if (Name.empty())
134  Name = SP->getName();
135  return Function::getGUID(Name);
136  }
137 
138  bool ShouldRun = false;
139 };
140 } // namespace
141 
142 char PseudoProbeInserter::ID = 0;
143 INITIALIZE_PASS_BEGIN(PseudoProbeInserter, DEBUG_TYPE,
144  "Insert pseudo probe annotations for value profiling",
145  false, false)
147 INITIALIZE_PASS_END(PseudoProbeInserter, DEBUG_TYPE,
148  "Insert pseudo probe annotations for value profiling",
150 
152  return new PseudoProbeInserter();
153 }
llvm::PseudoProbeDwarfDiscriminator::extractProbeAttributes
static uint32_t extractProbeAttributes(uint32_t Value)
Definition: PseudoProbe.h:61
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:104
MachineInstr.h
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:131
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
INITIALIZE_PASS_BEGIN
INITIALIZE_PASS_BEGIN(PseudoProbeInserter, DEBUG_TYPE, "Insert pseudo probe annotations for value profiling", false, false) INITIALIZE_PASS_END(PseudoProbeInserter
DebugInfoMetadata.h
llvm::TargetSubtargetInfo::getInstrInfo
virtual const TargetInstrInfo * getInstrInfo() const
Definition: TargetSubtargetInfo.h:93
llvm::SmallVector< MachineInstr *, 4 >
llvm::MachineFunctionPass
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Definition: MachineFunctionPass.h:30
MachineBasicBlock.h
llvm::DILocation::isPseudoProbeDiscriminator
static bool isPseudoProbeDiscriminator(unsigned Discriminator)
Definition: DebugInfoMetadata.h:1678
llvm::DILocation
Debug location.
Definition: DebugInfoMetadata.h:1557
llvm::PseudoProbeDwarfDiscriminator::extractProbeType
static uint32_t extractProbeType(uint32_t Value)
Definition: PseudoProbe.h:57
Module.h
TargetInstrInfo.h
llvm::MachineFunctionPass::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition: MachineFunctionPass.cpp:103
llvm::ISD::PSEUDO_PROBE
@ PSEUDO_PROBE
Pseudo probe for AutoFDO, as a place holder in a basic block to improve the sample counts quality.
Definition: ISDOpcodes.h:1242
llvm::TargetInstrInfo
TargetInstrInfo - Interface to description of machine instruction set.
Definition: TargetInstrInfo.h:97
llvm::MachineBasicBlock::remove
MachineInstr * remove(MachineInstr *I)
Remove the unbundled instruction from the instruction list without deleting it.
Definition: MachineBasicBlock.h:962
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:31
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
llvm::PseudoProbeDescMetadataName
constexpr const char * PseudoProbeDescMetadataName
Definition: PseudoProbe.h:25
false
Definition: StackSlotColoring.cpp:141
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:125
llvm::MachineBasicBlock::rend
reverse_iterator rend()
Definition: MachineBasicBlock.h:288
llvm::initializePseudoProbeInserterPass
void initializePseudoProbeInserterPass(PassRegistry &)
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:94
INITIALIZE_PASS_END
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:58
llvm::TargetPassConfig
Target-Independent Code Generator Pass Configuration Options.
Definition: TargetPassConfig.h:84
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:656
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:66
uint64_t
INITIALIZE_PASS_DEPENDENCY
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
MachineFunctionPass.h
llvm::PseudoProbeDwarfDiscriminator::extractProbeIndex
static uint32_t extractProbeIndex(uint32_t Value)
Definition: PseudoProbe.h:53
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
llvm::MachineFunction
Definition: MachineFunction.h:257
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::MachineBasicBlock::rbegin
reverse_iterator rbegin()
Definition: MachineBasicBlock.h:282
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
for
this could be done in SelectionDAGISel along with other special for
Definition: README.txt:104
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
profiling
Insert pseudo probe annotations for value profiling
Definition: PseudoProbeInserter.cpp:148
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
llvm::AnalysisUsage::setPreservesAll
void setPreservesAll()
Set by analyses that do not transform their input at all.
Definition: PassAnalysisSupport.h:130
llvm::MachineBasicBlock::insert
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
Definition: MachineBasicBlock.cpp:1312
llvm::GlobalValue::getGUID
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
Definition: GlobalValue.h:559
llvm::createPseudoProbeInserter
FunctionPass * createPseudoProbeInserter()
This pass inserts pseudo probe annotation for callsite profiling.
Definition: PseudoProbeInserter.cpp:151
PseudoProbe.h
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition: MachineInstrBuilder.h:328
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:308
InitializePasses.h
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
DEBUG_TYPE
#define DEBUG_TYPE
Definition: PseudoProbeInserter.cpp:25
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38