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