LLVM 23.0.0git
SampleProfileMatcher.h
Go to the documentation of this file.
1//===- Transforms/IPO/SampleProfileMatcher.h ----------*- C++ -*-===//
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/// \file
10/// This file provides the interface for SampleProfileMatcher.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_TRANSFORMS_IPO_SAMPLEPROFILEMATCHER_H
15#define LLVM_TRANSFORMS_IPO_SAMPLEPROFILEMATCHER_H
16
17#include "llvm/ADT/DenseMap.h"
18#include "llvm/ADT/DenseSet.h"
19#include "llvm/ADT/MapVector.h"
20#include "llvm/ADT/StringSet.h"
22
23namespace llvm {
24
25using AnchorList = std::vector<std::pair<LineLocation, FunctionId>>;
26using AnchorMap = std::map<LineLocation, FunctionId>;
27
28// Sample profile matching - fuzzy match.
30 Module &M;
31 SampleProfileReader &Reader;
32 LazyCallGraph &CG;
33 const PseudoProbeManager *ProbeManager;
34 const ThinOrFullLTOPhase LTOPhase;
35 SampleProfileMap FlattenedProfiles;
36 // For each function, the matcher generates a map, of which each entry is a
37 // mapping from the source location of current build to the source location
38 // in the profile.
39 StringMap<LocToLocMap> FuncMappings;
40 // Hash mapping cache for matched anchor pairs in stale profile matching
42
43 // Match state for an anchor/callsite.
44 enum class MatchState {
45 Unknown = 0,
46 // Initial match between input profile and current IR.
47 InitialMatch = 1,
48 // Initial mismatch between input profile and current IR.
49 InitialMismatch = 2,
50 // InitialMatch stays matched after fuzzy profile matching.
51 UnchangedMatch = 3,
52 // InitialMismatch stays mismatched after fuzzy profile matching.
53 UnchangedMismatch = 4,
54 // InitialMismatch is recovered after fuzzy profile matching.
55 RecoveredMismatch = 5,
56 // InitialMatch is removed and becomes mismatched after fuzzy profile
57 // matching.
58 RemovedMatch = 6,
59 };
60
61 // For each function, store every callsite and its matching state into this
62 // map, of which each entry is a pair of callsite location and MatchState.
63 // This is used for profile staleness computation and report.
64 StringMap<DenseMap<LineLocation, MatchState>> FuncCallsiteMatchStates;
65
66 // A map from a pair of function and profile name to a boolean value
67 // indicating whether they are matched. This is used as a cache for the
68 // matching result.
69 DenseMap<std::pair<const Function *, FunctionId>, bool> FuncProfileMatchCache;
70 // The new functions found by the call graph matching. The map's key is the
71 // the new(renamed) function pointer and the value is old(unused) profile
72 // name.
73 MapVector<Function *, FunctionId> FuncToProfileNameMap;
74
75 // A map pointer to the FuncNameToProfNameMap in SampleProfileLoader,
76 // which maps the function name to the matched profile name. This is used
77 // for sample loader to look up profile using the new name.
79
80 // A map pointer to the SymbolMap in SampleProfileLoader, which stores all
81 // the original matched symbols before the matching. this is to determine if
82 // the profile is unused(to be matched) or not.
84
85 // The new functions from IR.
87
88 // Pointer to the Profile Symbol List in the reader.
89 std::shared_ptr<ProfileSymbolList> PSL;
90
91 // Profile mismatch statstics:
92 uint64_t TotalProfiledFunc = 0;
93 // Num of checksum-mismatched function.
94 uint64_t NumStaleProfileFunc = 0;
95 uint64_t TotalProfiledCallsites = 0;
96 uint64_t NumMismatchedCallsites = 0;
97 uint64_t NumRecoveredCallsites = 0;
98 // Total samples for all profiled functions.
99 uint64_t TotalFunctionSamples = 0;
100 // Total samples for all checksum-mismatched functions.
101 uint64_t MismatchedFunctionSamples = 0;
102 uint64_t MismatchedCallsiteSamples = 0;
103 uint64_t RecoveredCallsiteSamples = 0;
104
105 // Profile call-graph matching statstics:
106 uint64_t NumCallGraphRecoveredProfiledFunc = 0;
107 uint64_t NumCallGraphRecoveredFuncSamples = 0;
108
109 // A dummy name for unknown indirect callee, used to differentiate from a
110 // non-call instruction that also has an empty callee name.
111 static constexpr const char *UnknownIndirectCallee =
112 "unknown.indirect.callee";
113
114public:
117 const PseudoProbeManager *ProbeManager, ThinOrFullLTOPhase LTOPhase,
119 std::shared_ptr<ProfileSymbolList> PSL,
121 : M(M), Reader(Reader), CG(CG), ProbeManager(ProbeManager),
122 LTOPhase(LTOPhase), FuncNameToProfNameMap(&FuncNameToProfNameMap),
123 SymbolMap(&SymMap), PSL(PSL) {};
124 LLVM_ABI void runOnModule();
126 // Do not clear FuncMappings, it stores IRLoc to ProfLoc remappings which
127 // will be used for sample loader.
128 // Do not clear FlattenedProfiles as it contains function names referenced
129 // by FuncNameToProfNameMap. Clearing this memory could lead to a
130 // use-after-free error.
131 freeContainer(FuncCallsiteMatchStates);
132 freeContainer(FunctionsWithoutProfile);
133 freeContainer(FuncToProfileNameMap);
134 }
135
136private:
137 FunctionSamples *getFlattenedSamplesFor(const FunctionId &Fname) {
138 auto It = FlattenedProfiles.find(Fname);
139 if (It != FlattenedProfiles.end())
140 return &It->second;
141 return nullptr;
142 }
143 FunctionSamples *getFlattenedSamplesFor(const Function &F) {
144 StringRef CanonFName = FunctionSamples::getCanonicalFnName(F);
145 return getFlattenedSamplesFor(FunctionId(CanonFName));
146 }
147 template <typename T> inline void freeContainer(T &C) {
148 T Empty;
149 std::swap(C, Empty);
150 }
151 void getFilteredAnchorList(const AnchorMap &IRAnchors,
152 const AnchorMap &ProfileAnchors,
153 AnchorList &FilteredIRAnchorsList,
154 AnchorList &FilteredProfileAnchorList);
155 void runOnFunction(Function &F);
156 void findIRAnchors(const Function &F, AnchorMap &IRAnchors) const;
157 void findProfileAnchors(const FunctionSamples &FS,
158 AnchorMap &ProfileAnchors) const;
159 // Record the callsite match states for profile staleness report, the result
160 // is saved in FuncCallsiteMatchStates.
161 void recordCallsiteMatchStates(const Function &F, const AnchorMap &IRAnchors,
162 const AnchorMap &ProfileAnchors,
163 const LocToLocMap *IRToProfileLocationMap);
164
165 bool isMismatchState(const enum MatchState &State) {
166 return State == MatchState::InitialMismatch ||
167 State == MatchState::UnchangedMismatch ||
168 State == MatchState::RemovedMatch;
169 };
170
171 bool isInitialState(const enum MatchState &State) {
172 return State == MatchState::InitialMatch ||
173 State == MatchState::InitialMismatch;
174 };
175
176 bool isFinalState(const enum MatchState &State) {
177 return State == MatchState::UnchangedMatch ||
178 State == MatchState::UnchangedMismatch ||
179 State == MatchState::RecoveredMismatch ||
180 State == MatchState::RemovedMatch;
181 };
182
183 void
184 countCallGraphRecoveredSamples(const FunctionSamples &FS,
185 DenseSet<FunctionId> &MatchedUnusedProfile);
186 // Count the samples of checksum mismatched function for the top-level
187 // function and all inlinees.
188 void countMismatchedFuncSamples(const FunctionSamples &FS, bool IsTopLevel);
189 // Count the number of mismatched or recovered callsites.
190 void countMismatchCallsites(const FunctionSamples &FS);
191 // Count the samples of mismatched or recovered callsites for top-level
192 // function and all inlinees.
193 void countMismatchedCallsiteSamples(const FunctionSamples &FS);
194 void computeAndReportProfileStaleness();
195 void UpdateWithSalvagedProfiles();
196
197 LocToLocMap &getIRToProfileLocationMap(const FunctionSamples &FS) {
198 return FuncMappings[FS.getFuncName()];
199 }
200 void distributeIRToProfileLocationMap();
201 void distributeIRToProfileLocationMap(FunctionSamples &FS);
202 LocToLocMap longestCommonSequence(const AnchorList &IRCallsiteAnchors,
203 const AnchorList &ProfileCallsiteAnchors,
204 bool MatchUnusedFunction);
205 void matchNonCallsiteLocs(const LocToLocMap &AnchorMatchings,
206 const AnchorMap &IRAnchors,
207 LocToLocMap &IRToProfileLocationMap);
208 void runStaleProfileMatching(const Function &F, const AnchorMap &IRAnchors,
209 const AnchorMap &ProfileAnchors,
210 LocToLocMap &IRToProfileLocationMap,
211 bool RunCFGMatching, bool RunCGMatching);
212 // If the function doesn't have profile, return the pointer to the function.
213 bool functionHasProfile(const FunctionId &IRFuncName,
214 Function *&FuncWithoutProfile);
215 bool isProfileUnused(const FunctionId &ProfileFuncName);
216 bool functionMatchesProfileHelper(const Function &IRFunc,
217 const FunctionId &ProfFunc);
218 // Determine if the function matches profile. If FindMatchedProfileOnly is
219 // set, only search the existing matched function. Otherwise, try matching the
220 // two functions.
221 bool functionMatchesProfile(const FunctionId &IRFuncName,
222 const FunctionId &ProfileFuncName,
223 bool FindMatchedProfileOnly);
224 // Determine if the function matches profile by computing a similarity ratio
225 // between two sequences of callsite anchors extracted from function and
226 // profile. If it's above the threshold, the function matches the profile.
227 bool functionMatchesProfile(Function &IRFunc, const FunctionId &ProfFunc,
228 bool FindMatchedProfileOnly);
229 // Find functions that don't show in the profile or profile symbol list,
230 // which are supposed to be new functions. We use them as the targets for
231 // call graph matching.
232 void findFunctionsWithoutProfile();
233 // Match orphan IR functions to unused top-level profile entries by demangled
234 // basename, without requiring a matched caller in the call graph.
235 void matchFunctionsWithoutProfileByBasename();
236 void reportOrPersistProfileStats();
237};
238} // end namespace llvm
239#endif // LLVM_TRANSFORMS_IPO_SAMPLEPROFILEMATCHER_H
#define LLVM_ABI
Definition Compiler.h:215
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
#define F(x, y, z)
Definition MD5.cpp:54
This file implements a map that provides insertion order iteration.
#define T
This file provides the interface for the sampled PGO profile loader base implementation.
StringSet - A set-like wrapper for the StringMap.
LocallyHashedType DenseMapInfo< LocallyHashedType >::Empty
A lazily constructed view of the call graph of a module.
This class implements a map that also provides access to all stored values in a deterministic order.
Definition MapVector.h:38
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
SampleProfileMatcher(Module &M, SampleProfileReader &Reader, LazyCallGraph &CG, const PseudoProbeManager *ProbeManager, ThinOrFullLTOPhase LTOPhase, HashKeyMap< DenseMap, FunctionId, Function * > &SymMap, std::shared_ptr< ProfileSymbolList > PSL, HashKeyMap< DenseMap, FunctionId, FunctionId > &FuncNameToProfNameMap)
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition StringMap.h:128
This class represents a function that is read from a sample profile.
Definition FunctionId.h:36
Representation of the samples collected for a function.
Definition SampleProf.h:792
static StringRef getCanonicalFnName(const Function &F)
Return the canonical name for a function, taking into account suffix elision policy attributes.
This class is a wrapper to associative container MapT<KeyT, ValueT> using the hash value of the origi...
Definition HashKeyMap.h:52
This class provides operator overloads to the map container using MD5 as the key type,...
iterator find(const SampleContext &Ctx)
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
DenseMap< LineLocation, LineLocation > LocToLocMap
Definition SampleProf.h:785
This is an optimization pass for GlobalISel generic memory operations.
std::map< LineLocation, FunctionId > AnchorMap
ThinOrFullLTOPhase
This enumerates the LLVM full LTO or ThinLTO optimization phases.
Definition Pass.h:77
std::vector< std::pair< LineLocation, FunctionId > > AnchorList
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:862