LLVM 19.0.0git
SampleProfileMatcher.cpp
Go to the documentation of this file.
1//===- SampleProfileMatcher.cpp - Sampling-based Stale Profile Matcher ----===//
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 SampleProfileMatcher used for stale
10// profile matching.
11//
12//===----------------------------------------------------------------------===//
13
16#include "llvm/IR/MDBuilder.h"
17
18using namespace llvm;
19using namespace sampleprof;
20
21#define DEBUG_TYPE "sample-profile-matcher"
22
26
27void SampleProfileMatcher::findIRAnchors(
28 const Function &F, std::map<LineLocation, StringRef> &IRAnchors) {
29 // For inlined code, recover the original callsite and callee by finding the
30 // top-level inline frame. e.g. For frame stack "main:1 @ foo:2 @ bar:3", the
31 // top-level frame is "main:1", the callsite is "1" and the callee is "foo".
32 auto FindTopLevelInlinedCallsite = [](const DILocation *DIL) {
33 assert((DIL && DIL->getInlinedAt()) && "No inlined callsite");
34 const DILocation *PrevDIL = nullptr;
35 do {
36 PrevDIL = DIL;
37 DIL = DIL->getInlinedAt();
38 } while (DIL->getInlinedAt());
39
41 StringRef CalleeName = PrevDIL->getSubprogramLinkageName();
42 return std::make_pair(Callsite, CalleeName);
43 };
44
45 auto GetCanonicalCalleeName = [](const CallBase *CB) {
46 StringRef CalleeName = UnknownIndirectCallee;
47 if (Function *Callee = CB->getCalledFunction())
48 CalleeName = FunctionSamples::getCanonicalFnName(Callee->getName());
49 return CalleeName;
50 };
51
52 // Extract profile matching anchors in the IR.
53 for (auto &BB : F) {
54 for (auto &I : BB) {
55 DILocation *DIL = I.getDebugLoc();
56 if (!DIL)
57 continue;
58
60 if (auto Probe = extractProbe(I)) {
61 // Flatten inlined IR for the matching.
62 if (DIL->getInlinedAt()) {
63 IRAnchors.emplace(FindTopLevelInlinedCallsite(DIL));
64 } else {
65 // Use empty StringRef for basic block probe.
66 StringRef CalleeName;
67 if (const auto *CB = dyn_cast<CallBase>(&I)) {
68 // Skip the probe inst whose callee name is "llvm.pseudoprobe".
69 if (!isa<IntrinsicInst>(&I))
70 CalleeName = GetCanonicalCalleeName(CB);
71 }
72 IRAnchors.emplace(LineLocation(Probe->Id, 0), CalleeName);
73 }
74 }
75 } else {
76 // TODO: For line-number based profile(AutoFDO), currently only support
77 // find callsite anchors. In future, we need to parse all the non-call
78 // instructions to extract the line locations for profile matching.
79 if (!isa<CallBase>(&I) || isa<IntrinsicInst>(&I))
80 continue;
81
82 if (DIL->getInlinedAt()) {
83 IRAnchors.emplace(FindTopLevelInlinedCallsite(DIL));
84 } else {
86 StringRef CalleeName = GetCanonicalCalleeName(dyn_cast<CallBase>(&I));
87 IRAnchors.emplace(Callsite, CalleeName);
88 }
89 }
90 }
91 }
92}
93
94void SampleProfileMatcher::findProfileAnchors(
95 const FunctionSamples &FS,
96 std::map<LineLocation, std::unordered_set<FunctionId>> &ProfileAnchors) {
97 auto isInvalidLineOffset = [](uint32_t LineOffset) {
98 return LineOffset & 0x8000;
99 };
100
101 for (const auto &I : FS.getBodySamples()) {
102 const LineLocation &Loc = I.first;
103 if (isInvalidLineOffset(Loc.LineOffset))
104 continue;
105 for (const auto &I : I.second.getCallTargets()) {
106 auto Ret =
107 ProfileAnchors.try_emplace(Loc, std::unordered_set<FunctionId>());
108 Ret.first->second.insert(I.first);
109 }
110 }
111
112 for (const auto &I : FS.getCallsiteSamples()) {
113 const LineLocation &Loc = I.first;
114 if (isInvalidLineOffset(Loc.LineOffset))
115 continue;
116 const auto &CalleeMap = I.second;
117 for (const auto &I : CalleeMap) {
118 auto Ret =
119 ProfileAnchors.try_emplace(Loc, std::unordered_set<FunctionId>());
120 Ret.first->second.insert(I.first);
121 }
122 }
123}
124
125// Call target name anchor based profile fuzzy matching.
126// Input:
127// For IR locations, the anchor is the callee name of direct callsite; For
128// profile locations, it's the call target name for BodySamples or inlinee's
129// profile name for CallsiteSamples.
130// Matching heuristic:
131// First match all the anchors in lexical order, then split the non-anchor
132// locations between the two anchors evenly, first half are matched based on the
133// start anchor, second half are matched based on the end anchor.
134// For example, given:
135// IR locations: [1, 2(foo), 3, 5, 6(bar), 7]
136// Profile locations: [1, 2, 3(foo), 4, 7, 8(bar), 9]
137// The matching gives:
138// [1, 2(foo), 3, 5, 6(bar), 7]
139// | | | | | |
140// [1, 2, 3(foo), 4, 7, 8(bar), 9]
141// The output mapping: [2->3, 3->4, 5->7, 6->8, 7->9].
142void SampleProfileMatcher::runStaleProfileMatching(
143 const Function &F, const std::map<LineLocation, StringRef> &IRAnchors,
144 const std::map<LineLocation, std::unordered_set<FunctionId>>
145 &ProfileAnchors,
146 LocToLocMap &IRToProfileLocationMap) {
147 LLVM_DEBUG(dbgs() << "Run stale profile matching for " << F.getName()
148 << "\n");
149 assert(IRToProfileLocationMap.empty() &&
150 "Run stale profile matching only once per function");
151
152 std::unordered_map<FunctionId, std::set<LineLocation>> CalleeToCallsitesMap;
153 for (const auto &I : ProfileAnchors) {
154 const auto &Loc = I.first;
155 const auto &Callees = I.second;
156 // Filter out possible indirect calls, use direct callee name as anchor.
157 if (Callees.size() == 1) {
158 FunctionId CalleeName = *Callees.begin();
159 const auto &Candidates = CalleeToCallsitesMap.try_emplace(
160 CalleeName, std::set<LineLocation>());
161 Candidates.first->second.insert(Loc);
162 }
163 }
164
165 auto InsertMatching = [&](const LineLocation &From, const LineLocation &To) {
166 // Skip the unchanged location mapping to save memory.
167 if (From != To)
168 IRToProfileLocationMap.insert({From, To});
169 };
170
171 // Use function's beginning location as the initial anchor.
172 int32_t LocationDelta = 0;
173 SmallVector<LineLocation> LastMatchedNonAnchors;
174
175 for (const auto &IR : IRAnchors) {
176 const auto &Loc = IR.first;
177 auto CalleeName = IR.second;
178 bool IsMatchedAnchor = false;
179 // Match the anchor location in lexical order.
180 if (!CalleeName.empty()) {
181 auto CandidateAnchors =
182 CalleeToCallsitesMap.find(getRepInFormat(CalleeName));
183 if (CandidateAnchors != CalleeToCallsitesMap.end() &&
184 !CandidateAnchors->second.empty()) {
185 auto CI = CandidateAnchors->second.begin();
186 const auto Candidate = *CI;
187 CandidateAnchors->second.erase(CI);
188 InsertMatching(Loc, Candidate);
189 LLVM_DEBUG(dbgs() << "Callsite with callee:" << CalleeName
190 << " is matched from " << Loc << " to " << Candidate
191 << "\n");
192 LocationDelta = Candidate.LineOffset - Loc.LineOffset;
193
194 // Match backwards for non-anchor locations.
195 // The locations in LastMatchedNonAnchors have been matched forwards
196 // based on the previous anchor, spilt it evenly and overwrite the
197 // second half based on the current anchor.
198 for (size_t I = (LastMatchedNonAnchors.size() + 1) / 2;
199 I < LastMatchedNonAnchors.size(); I++) {
200 const auto &L = LastMatchedNonAnchors[I];
201 uint32_t CandidateLineOffset = L.LineOffset + LocationDelta;
202 LineLocation Candidate(CandidateLineOffset, L.Discriminator);
203 InsertMatching(L, Candidate);
204 LLVM_DEBUG(dbgs() << "Location is rematched backwards from " << L
205 << " to " << Candidate << "\n");
206 }
207
208 IsMatchedAnchor = true;
209 LastMatchedNonAnchors.clear();
210 }
211 }
212
213 // Match forwards for non-anchor locations.
214 if (!IsMatchedAnchor) {
215 uint32_t CandidateLineOffset = Loc.LineOffset + LocationDelta;
216 LineLocation Candidate(CandidateLineOffset, Loc.Discriminator);
217 InsertMatching(Loc, Candidate);
218 LLVM_DEBUG(dbgs() << "Location is matched from " << Loc << " to "
219 << Candidate << "\n");
220 LastMatchedNonAnchors.emplace_back(Loc);
221 }
222 }
223}
224
225void SampleProfileMatcher::runOnFunction(Function &F) {
226 // We need to use flattened function samples for matching.
227 // Unlike IR, which includes all callsites from the source code, the callsites
228 // in profile only show up when they are hit by samples, i,e. the profile
229 // callsites in one context may differ from those in another context. To get
230 // the maximum number of callsites, we merge the function profiles from all
231 // contexts, aka, the flattened profile to find profile anchors.
232 const auto *FSFlattened = getFlattenedSamplesFor(F);
233 if (!FSFlattened)
234 return;
235
236 // Anchors for IR. It's a map from IR location to callee name, callee name is
237 // empty for non-call instruction and use a dummy name(UnknownIndirectCallee)
238 // for unknown indrect callee name.
239 std::map<LineLocation, StringRef> IRAnchors;
240 findIRAnchors(F, IRAnchors);
241 // Anchors for profile. It's a map from callsite location to a set of callee
242 // name.
243 std::map<LineLocation, std::unordered_set<FunctionId>> ProfileAnchors;
244 findProfileAnchors(*FSFlattened, ProfileAnchors);
245
246 // Compute the callsite match states for profile staleness report.
248 recordCallsiteMatchStates(F, IRAnchors, ProfileAnchors, nullptr);
249
250 // For probe-based profiles, run matching only when the current profile is not
251 // valid.
253 !ProbeManager->profileIsValid(F, *FSFlattened))) {
254 // For imported functions, the checksum metadata(pseudo_probe_desc) are
255 // dropped, so we leverage function attribute(profile-checksum-mismatch) to
256 // transfer the info: add the attribute during pre-link phase and check it
257 // during post-link phase(see "profileIsValid").
260 F.addFnAttr("profile-checksum-mismatch");
261
262 // The matching result will be saved to IRToProfileLocationMap, create a
263 // new map for each function.
264 auto &IRToProfileLocationMap = getIRToProfileLocationMap(F);
265 runStaleProfileMatching(F, IRAnchors, ProfileAnchors,
266 IRToProfileLocationMap);
267 // Find and update callsite match states after matching.
269 recordCallsiteMatchStates(F, IRAnchors, ProfileAnchors,
270 &IRToProfileLocationMap);
271 }
272}
273
274void SampleProfileMatcher::recordCallsiteMatchStates(
275 const Function &F, const std::map<LineLocation, StringRef> &IRAnchors,
276 const std::map<LineLocation, std::unordered_set<FunctionId>>
277 &ProfileAnchors,
278 const LocToLocMap *IRToProfileLocationMap) {
279 bool IsPostMatch = IRToProfileLocationMap != nullptr;
280 auto &CallsiteMatchStates =
281 FuncCallsiteMatchStates[FunctionSamples::getCanonicalFnName(F.getName())];
282
283 auto MapIRLocToProfileLoc = [&](const LineLocation &IRLoc) {
284 // IRToProfileLocationMap is null in pre-match phrase.
285 if (!IRToProfileLocationMap)
286 return IRLoc;
287 const auto &ProfileLoc = IRToProfileLocationMap->find(IRLoc);
288 if (ProfileLoc != IRToProfileLocationMap->end())
289 return ProfileLoc->second;
290 else
291 return IRLoc;
292 };
293
294 for (const auto &I : IRAnchors) {
295 // After fuzzy profile matching, use the matching result to remap the
296 // current IR callsite.
297 const auto &ProfileLoc = MapIRLocToProfileLoc(I.first);
298 const auto &IRCalleeName = I.second;
299 const auto &It = ProfileAnchors.find(ProfileLoc);
300 if (It == ProfileAnchors.end())
301 continue;
302 const auto &Callees = It->second;
303
304 bool IsCallsiteMatched = false;
305 // Since indirect call does not have CalleeName, check conservatively if
306 // callsite in the profile is a callsite location. This is to reduce num of
307 // false positive since otherwise all the indirect call samples will be
308 // reported as mismatching.
309 if (IRCalleeName == SampleProfileMatcher::UnknownIndirectCallee)
310 IsCallsiteMatched = true;
311 else if (Callees.size() == 1 && Callees.count(getRepInFormat(IRCalleeName)))
312 IsCallsiteMatched = true;
313
314 if (IsCallsiteMatched) {
315 auto It = CallsiteMatchStates.find(ProfileLoc);
316 if (It == CallsiteMatchStates.end())
317 CallsiteMatchStates.emplace(ProfileLoc, MatchState::InitialMatch);
318 else if (IsPostMatch) {
319 if (It->second == MatchState::InitialMatch)
320 It->second = MatchState::UnchangedMatch;
321 else if (It->second == MatchState::InitialMismatch)
322 It->second = MatchState::RecoveredMismatch;
323 }
324 }
325 }
326
327 // Check if there are any callsites in the profile that does not match to any
328 // IR callsites.
329 for (const auto &I : ProfileAnchors) {
330 const auto &Loc = I.first;
331 [[maybe_unused]] const auto &Callees = I.second;
332 assert(!Callees.empty() && "Callees should not be empty");
333 auto It = CallsiteMatchStates.find(Loc);
334 if (It == CallsiteMatchStates.end())
335 CallsiteMatchStates.emplace(Loc, MatchState::InitialMismatch);
336 else if (IsPostMatch) {
337 // Update the state if it's not matched(UnchangedMatch or
338 // RecoveredMismatch).
339 if (It->second == MatchState::InitialMismatch)
340 It->second = MatchState::UnchangedMismatch;
341 else if (It->second == MatchState::InitialMatch)
342 It->second = MatchState::RemovedMatch;
343 }
344 }
345}
346
347void SampleProfileMatcher::countMismatchedFuncSamples(const FunctionSamples &FS,
348 bool IsTopLevel) {
349 const auto *FuncDesc = ProbeManager->getDesc(FS.getGUID());
350 // Skip the function that is external or renamed.
351 if (!FuncDesc)
352 return;
353
354 if (ProbeManager->profileIsHashMismatched(*FuncDesc, FS)) {
355 if (IsTopLevel)
356 NumStaleProfileFunc++;
357 // Given currently all probe ids are after block probe ids, once the
358 // checksum is mismatched, it's likely all the callites are mismatched and
359 // dropped. We conservatively count all the samples as mismatched and stop
360 // counting the inlinees' profiles.
361 MismatchedFunctionSamples += FS.getTotalSamples();
362 return;
363 }
364
365 // Even the current-level function checksum is matched, it's possible that the
366 // nested inlinees' checksums are mismatched that affect the inlinee's sample
367 // loading, we need to go deeper to check the inlinees' function samples.
368 // Similarly, count all the samples as mismatched if the inlinee's checksum is
369 // mismatched using this recursive function.
370 for (const auto &I : FS.getCallsiteSamples())
371 for (const auto &CS : I.second)
372 countMismatchedFuncSamples(CS.second, false);
373}
374
375void SampleProfileMatcher::countMismatchedCallsiteSamples(
376 const FunctionSamples &FS) {
377 auto It = FuncCallsiteMatchStates.find(FS.getFuncName());
378 // Skip it if no mismatched callsite or this is an external function.
379 if (It == FuncCallsiteMatchStates.end() || It->second.empty())
380 return;
381 const auto &CallsiteMatchStates = It->second;
382
383 auto findMatchState = [&](const LineLocation &Loc) {
384 auto It = CallsiteMatchStates.find(Loc);
385 if (It == CallsiteMatchStates.end())
386 return MatchState::Unknown;
387 return It->second;
388 };
389
390 auto AttributeMismatchedSamples = [&](const enum MatchState &State,
391 uint64_t Samples) {
392 if (isMismatchState(State))
393 MismatchedCallsiteSamples += Samples;
394 else if (State == MatchState::RecoveredMismatch)
395 RecoveredCallsiteSamples += Samples;
396 };
397
398 // The non-inlined callsites are saved in the body samples of function
399 // profile, go through it to count the non-inlined callsite samples.
400 for (const auto &I : FS.getBodySamples())
401 AttributeMismatchedSamples(findMatchState(I.first), I.second.getSamples());
402
403 // Count the inlined callsite samples.
404 for (const auto &I : FS.getCallsiteSamples()) {
405 auto State = findMatchState(I.first);
406 uint64_t CallsiteSamples = 0;
407 for (const auto &CS : I.second)
408 CallsiteSamples += CS.second.getTotalSamples();
409 AttributeMismatchedSamples(State, CallsiteSamples);
410
411 if (isMismatchState(State))
412 continue;
413
414 // When the current level of inlined call site matches the profiled call
415 // site, we need to go deeper along the inline tree to count mismatches from
416 // lower level inlinees.
417 for (const auto &CS : I.second)
418 countMismatchedCallsiteSamples(CS.second);
419 }
420}
421
422void SampleProfileMatcher::countMismatchCallsites(const FunctionSamples &FS) {
423 auto It = FuncCallsiteMatchStates.find(FS.getFuncName());
424 // Skip it if no mismatched callsite or this is an external function.
425 if (It == FuncCallsiteMatchStates.end() || It->second.empty())
426 return;
427 const auto &MatchStates = It->second;
428 [[maybe_unused]] bool OnInitialState =
429 isInitialState(MatchStates.begin()->second);
430 for (const auto &I : MatchStates) {
431 TotalProfiledCallsites++;
432 assert(
433 (OnInitialState ? isInitialState(I.second) : isFinalState(I.second)) &&
434 "Profile matching state is inconsistent");
435
436 if (isMismatchState(I.second))
437 NumMismatchedCallsites++;
438 else if (I.second == MatchState::RecoveredMismatch)
439 NumRecoveredCallsites++;
440 }
441}
442
443void SampleProfileMatcher::computeAndReportProfileStaleness() {
445 return;
446
447 // Count profile mismatches for profile staleness report.
448 for (const auto &F : M) {
450 continue;
451 // As the stats will be merged by linker, skip reporting the metrics for
452 // imported functions to avoid repeated counting.
454 continue;
455 const auto *FS = Reader.getSamplesFor(F);
456 if (!FS)
457 continue;
458 TotalProfiledFunc++;
459 TotalFunctionSamples += FS->getTotalSamples();
460
461 // Checksum mismatch is only used in pseudo-probe mode.
463 countMismatchedFuncSamples(*FS, true);
464
465 // Count mismatches and samples for calliste.
466 countMismatchCallsites(*FS);
467 countMismatchedCallsiteSamples(*FS);
468 }
469
472 errs() << "(" << NumStaleProfileFunc << "/" << TotalProfiledFunc
473 << ") of functions' profile are invalid and ("
474 << MismatchedFunctionSamples << "/" << TotalFunctionSamples
475 << ") of samples are discarded due to function hash mismatch.\n";
476 }
477 errs() << "(" << (NumMismatchedCallsites + NumRecoveredCallsites) << "/"
478 << TotalProfiledCallsites
479 << ") of callsites' profile are invalid and ("
480 << (MismatchedCallsiteSamples + RecoveredCallsiteSamples) << "/"
481 << TotalFunctionSamples
482 << ") of samples are discarded due to callsite location mismatch.\n";
483 errs() << "(" << NumRecoveredCallsites << "/"
484 << (NumRecoveredCallsites + NumMismatchedCallsites)
485 << ") of callsites and (" << RecoveredCallsiteSamples << "/"
486 << (RecoveredCallsiteSamples + MismatchedCallsiteSamples)
487 << ") of samples are recovered by stale profile matching.\n";
488 }
489
491 LLVMContext &Ctx = M.getContext();
492 MDBuilder MDB(Ctx);
493
496 ProfStatsVec.emplace_back("NumStaleProfileFunc", NumStaleProfileFunc);
497 ProfStatsVec.emplace_back("TotalProfiledFunc", TotalProfiledFunc);
498 ProfStatsVec.emplace_back("MismatchedFunctionSamples",
499 MismatchedFunctionSamples);
500 ProfStatsVec.emplace_back("TotalFunctionSamples", TotalFunctionSamples);
501 }
502
503 ProfStatsVec.emplace_back("NumMismatchedCallsites", NumMismatchedCallsites);
504 ProfStatsVec.emplace_back("NumRecoveredCallsites", NumRecoveredCallsites);
505 ProfStatsVec.emplace_back("TotalProfiledCallsites", TotalProfiledCallsites);
506 ProfStatsVec.emplace_back("MismatchedCallsiteSamples",
507 MismatchedCallsiteSamples);
508 ProfStatsVec.emplace_back("RecoveredCallsiteSamples",
509 RecoveredCallsiteSamples);
510
511 auto *MD = MDB.createLLVMStats(ProfStatsVec);
512 auto *NMD = M.getOrInsertNamedMetadata("llvm.stats");
513 NMD->addOperand(MD);
514 }
515}
516
518 ProfileConverter::flattenProfile(Reader.getProfiles(), FlattenedProfiles,
520 for (auto &F : M) {
522 continue;
523 runOnFunction(F);
524 }
526 distributeIRToProfileLocationMap();
527
528 computeAndReportProfileStaleness();
529}
530
531void SampleProfileMatcher::distributeIRToProfileLocationMap(
532 FunctionSamples &FS) {
533 const auto ProfileMappings = FuncMappings.find(FS.getFuncName());
534 if (ProfileMappings != FuncMappings.end()) {
535 FS.setIRToProfileLocationMap(&(ProfileMappings->second));
536 }
537
538 for (auto &Callees :
539 const_cast<CallsiteSampleMap &>(FS.getCallsiteSamples())) {
540 for (auto &FS : Callees.second) {
541 distributeIRToProfileLocationMap(FS.second);
542 }
543 }
544}
545
546// Use a central place to distribute the matching results. Outlined and inlined
547// profile with the function name will be set to the same pointer.
548void SampleProfileMatcher::distributeIRToProfileLocationMap() {
549 for (auto &I : Reader.getProfiles()) {
550 distributeIRToProfileLocationMap(I.second);
551 }
552}
BlockVerifier::State From
#define LLVM_DEBUG(X)
Definition: Debug.h:101
Legalize the Machine IR a function s Machine IR
Definition: Legalizer.cpp:81
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
cl::opt< bool > ReportProfileStaleness
cl::opt< bool > SalvageStaleProfile
cl::opt< bool > PersistProfileStaleness
This file provides the interface for SampleProfileMatcher.
cl::opt< bool > PersistProfileStaleness("persist-profile-staleness", cl::Hidden, cl::init(false), cl::desc("Compute stale profile statistical metrics and write it into the " "native object file(.llvm_stats section)."))
cl::opt< bool > ReportProfileStaleness("report-profile-staleness", cl::Hidden, cl::init(false), cl::desc("Compute and report stale profile statistical metrics."))
cl::opt< bool > SalvageStaleProfile("salvage-stale-profile", cl::Hidden, cl::init(false), cl::desc("Salvage stale profile by fuzzy matching and use the remapped " "location for sample profile query."))
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1494
Debug location.
static bool isAvailableExternallyLinkage(LinkageTypes Linkage)
Definition: GlobalValue.h:379
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
bool profileIsHashMismatched(const PseudoProbeDescriptor &FuncDesc, const FunctionSamples &Samples) const
bool profileIsValid(const Function &F, const FunctionSamples &Samples) const
const PseudoProbeDescriptor * getDesc(uint64_t GUID) const
size_t size() const
Definition: SmallVector.h:91
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:950
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
iterator end()
Definition: StringMap.h:220
iterator find(StringRef Key)
Definition: StringMap.h:233
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
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:744
static StringRef getCanonicalFnName(const Function &F)
Return the canonical name for a function, taking into account suffix elision policy attributes.
Definition: SampleProf.h:1085
static LineLocation getCallSiteIdentifier(const DILocation *DIL, bool ProfileIsFS=false)
Returns a unique call site identifier for a given debug location of a call instruction.
Definition: SampleProf.cpp:221
static void flattenProfile(SampleProfileMap &ProfileMap, bool ProfileIsCS=false)
Definition: SampleProf.h:1417
SampleProfileMap & getProfiles()
Return all the profiles.
FunctionSamples * getSamplesFor(const Function &F)
Return the samples collected for function F.
@ FS
Definition: X86.h:206
static FunctionId getRepInFormat(StringRef Name)
Get the proper representation of a string according to whether the current Format uses MD5 to represe...
Definition: SampleProf.h:1292
std::unordered_map< LineLocation, LineLocation, LineLocationHash > LocToLocMap
Definition: SampleProf.h:737
std::map< LineLocation, FunctionSamplesMap > CallsiteSampleMap
Definition: SampleProf.h:735
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ ThinLTOPreLink
ThinLTO prelink (summary) phase.
std::optional< PseudoProbe > extractProbe(const Instruction &Inst)
Definition: PseudoProbe.cpp:56
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
static bool skipProfileForFunction(const Function &F)
Represents the relative location of an instruction.
Definition: SampleProf.h:280