LLVM  14.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/PseudoProbe.h"
22 #include "llvm/InitializePasses.h"
23 #include "llvm/MC/MCPseudoProbe.h"
25 #include <unordered_set>
26 
27 #define DEBUG_TYPE "pseudo-probe-inserter"
28 
29 using namespace llvm;
30 
31 namespace {
32 class PseudoProbeInserter : public MachineFunctionPass {
33 public:
34  static char ID;
35 
36  PseudoProbeInserter() : MachineFunctionPass(ID) {
38  }
39 
40  StringRef getPassName() const override { return "Pseudo Probe Inserter"; }
41 
42  void getAnalysisUsage(AnalysisUsage &AU) const override {
43  AU.setPreservesAll();
45  }
46 
47  bool doInitialization(Module &M) override {
48  ShouldRun = M.getNamedMetadata(PseudoProbeDescMetadataName);
49  return false;
50  }
51 
52  bool runOnMachineFunction(MachineFunction &MF) override {
53  if (!ShouldRun)
54  return false;
56  bool Changed = false;
57  for (MachineBasicBlock &MBB : MF) {
58  MachineInstr *FirstInstr = nullptr;
59  for (MachineInstr &MI : MBB) {
60  if (!MI.isPseudo())
61  FirstInstr = &MI;
62  if (MI.isCall()) {
63  if (DILocation *DL = MI.getDebugLoc()) {
64  auto Value = DL->getDiscriminator();
67  .addImm(getFuncGUID(MF.getFunction().getParent(), DL))
68  .addImm(
70  .addImm(
73  Value));
74  Changed = true;
75  }
76  }
77  }
78  }
79 
80  // Walk the block backwards, move PSEUDO_PROBE before the first real
81  // instruction to fix out-of-order probes. There is a problem with probes
82  // as the terminator of the block. During the offline counts processing,
83  // the samples collected on the first physical instruction following a
84  // probe will be counted towards the probe. This logically equals to
85  // treating the instruction next to a probe as if it is from the same
86  // block of the probe. This is accurate most of the time unless the
87  // instruction can be reached from multiple flows, which means it actually
88  // starts a new block. Samples collected on such probes may cause
89  // imprecision with the counts inference algorithm. Fortunately, if
90  // there are still other native instructions preceding the probe we can
91  // use them as a place holder to collect samples for the probe.
92  if (FirstInstr) {
93  auto MII = MBB.rbegin();
94  while (MII != MBB.rend()) {
95  // Skip all pseudo probes followed by a real instruction since they
96  // are not dangling.
97  if (!MII->isPseudo())
98  break;
99  auto Cur = MII++;
100  if (Cur->getOpcode() != TargetOpcode::PSEUDO_PROBE)
101  continue;
102  // Move the dangling probe before FirstInstr.
103  auto *ProbeInstr = &*Cur;
104  MBB.remove(ProbeInstr);
105  MBB.insert(FirstInstr, ProbeInstr);
106  Changed = true;
107  }
108  } else {
109  // Probes not surrounded by any real instructions in the same block are
110  // called dangling probes. Since there's no good way to pick up a sample
111  // collection point for dangling probes at compile time, they are being
112  // removed so that the profile correlation tool will not report any
113  // samples collected for them and it's up to the counts inference tool
114  // to get them a reasonable count.
115  SmallVector<MachineInstr *, 4> ToBeRemoved;
116  for (MachineInstr &MI : MBB) {
117  if (MI.isPseudoProbe())
118  ToBeRemoved.push_back(&MI);
119  }
120 
121  for (auto *MI : ToBeRemoved)
122  MI->eraseFromParent();
123 
124  Changed |= !ToBeRemoved.empty();
125  }
126  }
127 
128  return Changed;
129  }
130 
131 private:
132  uint64_t getFuncGUID(Module *M, DILocation *DL) {
133  auto *SP = DL->getScope()->getSubprogram();
134  auto Name = SP->getLinkageName();
135  if (Name.empty())
136  Name = SP->getName();
137  return Function::getGUID(Name);
138  }
139 
140  bool ShouldRun = false;
141 };
142 } // namespace
143 
144 char PseudoProbeInserter::ID = 0;
145 INITIALIZE_PASS_BEGIN(PseudoProbeInserter, DEBUG_TYPE,
146  "Insert pseudo probe annotations for value profiling",
147  false, false)
149 INITIALIZE_PASS_END(PseudoProbeInserter, DEBUG_TYPE,
150  "Insert pseudo probe annotations for value profiling",
152 
154  return new PseudoProbeInserter();
155 }
llvm::PseudoProbeDwarfDiscriminator::extractProbeAttributes
static uint32_t extractProbeAttributes(uint32_t Value)
Definition: PseudoProbe.h:62
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:105
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: AllocatorList.h:23
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:92
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:1701
llvm::DILocation
Debug location.
Definition: DebugInfoMetadata.h:1580
llvm::PseudoProbeDwarfDiscriminator::extractProbeType
static uint32_t extractProbeType(uint32_t Value)
Definition: PseudoProbe.h:58
TargetInstrInfo.h
MCPseudoProbe.h
llvm::MachineFunctionPass::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition: MachineFunctionPass.cpp:102
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:1197
llvm::TargetInstrInfo
TargetInstrInfo - Interface to description of machine instruction set.
Definition: TargetInstrInfo.h:97
TargetMachine.h
llvm::MachineBasicBlock::remove
MachineInstr * remove(MachineInstr *I)
Remove the unbundled instruction from the instruction list without deleting it.
Definition: MachineBasicBlock.h:930
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:26
false
Definition: StackSlotColoring.cpp:142
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:129
llvm::MachineBasicBlock::rend
reverse_iterator rend()
Definition: MachineBasicBlock.h:278
llvm::initializePseudoProbeInserterPass
void initializePseudoProbeInserterPass(PassRegistry &)
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
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:634
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
uint64_t
INITIALIZE_PASS_DEPENDENCY
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
profiling
Insert pseudo probe annotations for value profiling
Definition: PseudoProbeInserter.cpp:150
MachineFunctionPass.h
llvm::PseudoProbeDwarfDiscriminator::extractProbeIndex
static uint32_t extractProbeIndex(uint32_t Value)
Definition: PseudoProbe.h:54
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
llvm::MachineFunction
Definition: MachineFunction.h:234
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
llvm::MachineBasicBlock::rbegin
reverse_iterator rbegin()
Definition: MachineBasicBlock.h:272
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
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
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:1314
llvm::GlobalValue::getGUID
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
Definition: GlobalValue.h:517
llvm::createPseudoProbeInserter
FunctionPass * createPseudoProbeInserter()
This pass inserts pseudo probe annotation for callsite profiling.
Definition: PseudoProbeInserter.cpp:153
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:298
InitializePasses.h
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
DEBUG_TYPE
#define DEBUG_TYPE
Definition: PseudoProbeInserter.cpp:27
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38