1 //===- SampleProfileProbe.cpp - Pseudo probe Instrumentation -------------===//
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 SampleProfileProber transformation.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "llvm/Transforms/IPO/SampleProfileProbe.h"
14 #include "llvm/ADT/Statistic.h"
15 #include "llvm/Analysis/TargetLibraryInfo.h"
16 #include "llvm/IR/BasicBlock.h"
17 #include "llvm/IR/CFG.h"
18 #include "llvm/IR/Constant.h"
19 #include "llvm/IR/Constants.h"
20 #include "llvm/IR/DebugInfoMetadata.h"
21 #include "llvm/IR/GlobalValue.h"
22 #include "llvm/IR/GlobalVariable.h"
23 #include "llvm/IR/IRBuilder.h"
24 #include "llvm/IR/Instruction.h"
25 #include "llvm/IR/MDBuilder.h"
26 #include "llvm/ProfileData/SampleProf.h"
27 #include "llvm/Support/CRC.h"
28 #include "llvm/Transforms/Instrumentation.h"
29 #include "llvm/Transforms/Utils/ModuleUtils.h"
30 #include <vector>
31 
32 using namespace llvm;
33 #define DEBUG_TYPE "sample-profile-probe"
34 
35 STATISTIC(ArtificialDbgLine,
36           "Number of probes that have an artificial debug line");
37 
SampleProfileProber(Function & Func)38 SampleProfileProber::SampleProfileProber(Function &Func) : F(&Func) {
39   BlockProbeIds.clear();
40   CallProbeIds.clear();
41   LastProbeId = (uint32_t)PseudoProbeReservedId::Last;
42   computeProbeIdForBlocks();
43   computeProbeIdForCallsites();
44 }
45 
computeProbeIdForBlocks()46 void SampleProfileProber::computeProbeIdForBlocks() {
47   for (auto &BB : *F) {
48     BlockProbeIds[&BB] = ++LastProbeId;
49   }
50 }
51 
computeProbeIdForCallsites()52 void SampleProfileProber::computeProbeIdForCallsites() {
53   for (auto &BB : *F) {
54     for (auto &I : BB) {
55       if (!isa<CallBase>(I))
56         continue;
57       if (isa<IntrinsicInst>(&I))
58         continue;
59       CallProbeIds[&I] = ++LastProbeId;
60     }
61   }
62 }
63 
getBlockId(const BasicBlock * BB) const64 uint32_t SampleProfileProber::getBlockId(const BasicBlock *BB) const {
65   auto I = BlockProbeIds.find(const_cast<BasicBlock *>(BB));
66   return I == BlockProbeIds.end() ? 0 : I->second;
67 }
68 
getCallsiteId(const Instruction * Call) const69 uint32_t SampleProfileProber::getCallsiteId(const Instruction *Call) const {
70   auto Iter = CallProbeIds.find(const_cast<Instruction *>(Call));
71   return Iter == CallProbeIds.end() ? 0 : Iter->second;
72 }
73 
instrumentOneFunc(Function & F,TargetMachine * TM)74 void SampleProfileProber::instrumentOneFunc(Function &F, TargetMachine *TM) {
75   Module *M = F.getParent();
76   MDBuilder MDB(F.getContext());
77   // Compute a GUID without considering the function's linkage type. This is
78   // fine since function name is the only key in the profile database.
79   uint64_t Guid = Function::getGUID(F.getName());
80 
81   // Assign an artificial debug line to a probe that doesn't come with a real
82   // line. A probe not having a debug line will get an incomplete inline
83   // context. This will cause samples collected on the probe to be counted
84   // into the base profile instead of a context profile. The line number
85   // itself is not important though.
86   auto AssignDebugLoc = [&](Instruction *I) {
87     assert((isa<PseudoProbeInst>(I) || isa<CallBase>(I)) &&
88            "Expecting pseudo probe or call instructions");
89     if (!I->getDebugLoc()) {
90       if (auto *SP = F.getSubprogram()) {
91         auto DIL = DebugLoc::get(0, 0, SP);
92         I->setDebugLoc(DIL);
93         ArtificialDbgLine++;
94         LLVM_DEBUG({
95           dbgs() << "\nIn Function " << F.getName()
96                  << " Probe gets an artificial debug line\n";
97           I->dump();
98         });
99       }
100     }
101   };
102 
103   // Probe basic blocks.
104   for (auto &I : BlockProbeIds) {
105     BasicBlock *BB = I.first;
106     uint32_t Index = I.second;
107     // Insert a probe before an instruction with a valid debug line number which
108     // will be assigned to the probe. The line number will be used later to
109     // model the inline context when the probe is inlined into other functions.
110     // Debug instructions, phi nodes and lifetime markers do not have an valid
111     // line number. Real instructions generated by optimizations may not come
112     // with a line number either.
113     auto HasValidDbgLine = [](Instruction *J) {
114       return !isa<PHINode>(J) && !isa<DbgInfoIntrinsic>(J) &&
115              !J->isLifetimeStartOrEnd() && J->getDebugLoc();
116     };
117 
118     Instruction *J = &*BB->getFirstInsertionPt();
119     while (J != BB->getTerminator() && !HasValidDbgLine(J)) {
120       J = J->getNextNode();
121     }
122 
123     IRBuilder<> Builder(J);
124     assert(Builder.GetInsertPoint() != BB->end() &&
125            "Cannot get the probing point");
126     Function *ProbeFn =
127         llvm::Intrinsic::getDeclaration(M, Intrinsic::pseudoprobe);
128     Value *Args[] = {Builder.getInt64(Guid), Builder.getInt64(Index),
129                      Builder.getInt32(0)};
130     auto *Probe = Builder.CreateCall(ProbeFn, Args);
131     AssignDebugLoc(Probe);
132   }
133 
134   // Probe both direct calls and indirect calls. Direct calls are probed so that
135   // their probe ID can be used as an call site identifier to represent a
136   // calling context.
137   for (auto &I : CallProbeIds) {
138     auto *Call = I.first;
139     uint32_t Index = I.second;
140     uint32_t Type = cast<CallBase>(Call)->getCalledFunction()
141                         ? (uint32_t)PseudoProbeType::DirectCall
142                         : (uint32_t)PseudoProbeType::IndirectCall;
143     AssignDebugLoc(Call);
144     // Levarge the 32-bit discriminator field of debug data to store the ID and
145     // type of a callsite probe. This gets rid of the dependency on plumbing a
146     // customized metadata through the codegen pipeline.
147     uint32_t V = PseudoProbeDwarfDiscriminator::packProbeData(Index, Type);
148     if (auto DIL = Call->getDebugLoc()) {
149       DIL = DIL->cloneWithDiscriminator(V);
150       Call->setDebugLoc(DIL);
151     }
152   }
153 }
154 
run(Module & M,ModuleAnalysisManager & AM)155 PreservedAnalyses SampleProfileProbePass::run(Module &M,
156                                               ModuleAnalysisManager &AM) {
157   for (auto &F : M) {
158     if (F.isDeclaration())
159       continue;
160     SampleProfileProber ProbeManager(F);
161     ProbeManager.instrumentOneFunc(F, TM);
162   }
163 
164   return PreservedAnalyses::none();
165 }
166