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 
38 SampleProfileProber::SampleProfileProber(Function &Func) : F(&Func) {
39   BlockProbeIds.clear();
40   LastProbeId = (uint32_t)PseudoProbeReservedId::Last;
41   computeProbeIdForBlocks();
42 }
43 
44 void SampleProfileProber::computeProbeIdForBlocks() {
45   for (auto &BB : *F) {
46     BlockProbeIds[&BB] = ++LastProbeId;
47   }
48 }
49 
50 uint32_t SampleProfileProber::getBlockId(const BasicBlock *BB) const {
51   auto I = BlockProbeIds.find(const_cast<BasicBlock *>(BB));
52   return I == BlockProbeIds.end() ? 0 : I->second;
53 }
54 
55 void SampleProfileProber::instrumentOneFunc(Function &F, TargetMachine *TM) {
56   Module *M = F.getParent();
57   MDBuilder MDB(F.getContext());
58   // Compute a GUID without considering the function's linkage type. This is
59   // fine since function name is the only key in the profile database.
60   uint64_t Guid = Function::getGUID(F.getName());
61 
62   // Probe basic blocks.
63   for (auto &I : BlockProbeIds) {
64     BasicBlock *BB = I.first;
65     uint32_t Index = I.second;
66     // Insert a probe before an instruction with a valid debug line number which
67     // will be assigned to the probe. The line number will be used later to
68     // model the inline context when the probe is inlined into other functions.
69     // Debug instructions, phi nodes and lifetime markers do not have an valid
70     // line number. Real instructions generated by optimizations may not come
71     // with a line number either.
72     auto HasValidDbgLine = [](Instruction *J) {
73       return !isa<PHINode>(J) && !isa<DbgInfoIntrinsic>(J) &&
74              !J->isLifetimeStartOrEnd() && J->getDebugLoc();
75     };
76 
77     Instruction *J = &*BB->getFirstInsertionPt();
78     while (J != BB->getTerminator() && !HasValidDbgLine(J)) {
79       J = J->getNextNode();
80     }
81 
82     IRBuilder<> Builder(J);
83     assert(Builder.GetInsertPoint() != BB->end() &&
84            "Cannot get the probing point");
85     Function *ProbeFn =
86         llvm::Intrinsic::getDeclaration(M, Intrinsic::pseudoprobe);
87     Value *Args[] = {Builder.getInt64(Guid), Builder.getInt64(Index),
88                      Builder.getInt32(0)};
89     auto *Probe = Builder.CreateCall(ProbeFn, Args);
90     // Assign an artificial debug line to a probe that doesn't come with a real
91     // line. A probe not having a debug line will get an incomplete inline
92     // context. This will cause samples collected on the probe to be counted
93     // into the base profile instead of a context profile. The line number
94     // itself is not important though.
95     if (!Probe->getDebugLoc()) {
96       if (auto *SP = F.getSubprogram()) {
97         auto DIL = DebugLoc::get(0, 0, SP);
98         Probe->setDebugLoc(DIL);
99         ArtificialDbgLine++;
100         LLVM_DEBUG(dbgs() << "\nIn Function " << F.getName() << " Probe "
101                           << Index << " gets an artificial debug line\n";);
102       }
103     }
104   }
105 }
106 
107 PreservedAnalyses SampleProfileProbePass::run(Module &M,
108                                               ModuleAnalysisManager &AM) {
109   for (auto &F : M) {
110     if (F.isDeclaration())
111       continue;
112     SampleProfileProber ProbeManager(F);
113     ProbeManager.instrumentOneFunc(F, TM);
114   }
115 
116   return PreservedAnalyses::none();
117 }
118