Movatterモバイル変換


[0]ホーム

URL:


LLVM 20.0.0git
SampleProfReader.cpp
Go to the documentation of this file.
1//===- SampleProfReader.cpp - Read LLVM sample profile data ---------------===//
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 class that reads LLVM sample profiles. It
10// supports three file formats: text, binary and gcov.
11//
12// The textual representation is useful for debugging and testing purposes. The
13// binary representation is more compact, resulting in smaller file sizes.
14//
15// The gcov encoding is the one generated by GCC's AutoFDO profile creation
16// tool (https://github.com/google/autofdo)
17//
18// All three encodings can be used interchangeably as an input sample profile.
19//
20//===----------------------------------------------------------------------===//
21
22#include "llvm/ProfileData/SampleProfReader.h"
23#include "llvm/ADT/DenseMap.h"
24#include "llvm/ADT/STLExtras.h"
25#include "llvm/ADT/StringRef.h"
26#include "llvm/IR/Module.h"
27#include "llvm/IR/ProfileSummary.h"
28#include "llvm/ProfileData/ProfileCommon.h"
29#include "llvm/ProfileData/SampleProf.h"
30#include "llvm/Support/CommandLine.h"
31#include "llvm/Support/Compression.h"
32#include "llvm/Support/ErrorOr.h"
33#include "llvm/Support/JSON.h"
34#include "llvm/Support/LEB128.h"
35#include "llvm/Support/LineIterator.h"
36#include "llvm/Support/MD5.h"
37#include "llvm/Support/MemoryBuffer.h"
38#include "llvm/Support/VirtualFileSystem.h"
39#include "llvm/Support/raw_ostream.h"
40#include <algorithm>
41#include <cstddef>
42#include <cstdint>
43#include <limits>
44#include <memory>
45#include <system_error>
46#include <vector>
47
48using namespacellvm;
49using namespacesampleprof;
50
51#define DEBUG_TYPE "samplepgo-reader"
52
53// This internal option specifies if the profile uses FS discriminators.
54// It only applies to text, and binary format profiles.
55// For ext-binary format profiles, the flag is set in the summary.
56staticcl::opt<bool>ProfileIsFSDisciminator(
57"profile-isfs",cl::Hidden,cl::init(false),
58cl::desc("Profile uses flow sensitive discriminators"));
59
60/// Dump the function profile for \p FName.
61///
62/// \param FContext Name + context of the function to print.
63/// \param OS Stream to emit the output to.
64voidSampleProfileReader::dumpFunctionProfile(constFunctionSamples &FS,
65raw_ostream &OS) {
66OS <<"Function: " << FS.getContext().toString() <<": " << FS;
67}
68
69/// Dump all the function profiles found on stream \p OS.
70voidSampleProfileReader::dump(raw_ostream &OS) {
71 std::vector<NameFunctionSamples> V;
72sortFuncProfiles(Profiles, V);
73for (constauto &I : V)
74dumpFunctionProfile(*I.second,OS);
75}
76
77staticvoiddumpFunctionProfileJson(constFunctionSamples &S,
78json::OStream &JOS,bool TopLevel =false) {
79auto DumpBody = [&](constBodySampleMap &BodySamples) {
80for (constauto &I : BodySamples) {
81constLineLocation &Loc =I.first;
82constSampleRecord &Sample =I.second;
83 JOS.object([&] {
84 JOS.attribute("line", Loc.LineOffset);
85if (Loc.Discriminator)
86 JOS.attribute("discriminator", Loc.Discriminator);
87 JOS.attribute("samples", Sample.getSamples());
88
89auto CallTargets = Sample.getSortedCallTargets();
90if (!CallTargets.empty()) {
91 JOS.attributeArray("calls", [&] {
92for (constauto &J : CallTargets) {
93 JOS.object([&] {
94 JOS.attribute("function", J.first.str());
95 JOS.attribute("samples", J.second);
96 });
97 }
98 });
99 }
100 });
101 }
102 };
103
104auto DumpCallsiteSamples = [&](constCallsiteSampleMap &CallsiteSamples) {
105for (constauto &I : CallsiteSamples)
106for (constauto &FS :I.second) {
107constLineLocation &Loc =I.first;
108constFunctionSamples &CalleeSamples = FS.second;
109 JOS.object([&] {
110 JOS.attribute("line", Loc.LineOffset);
111if (Loc.Discriminator)
112 JOS.attribute("discriminator", Loc.Discriminator);
113 JOS.attributeArray(
114"samples", [&] {dumpFunctionProfileJson(CalleeSamples, JOS); });
115 });
116 }
117 };
118
119 JOS.object([&] {
120 JOS.attribute("name", S.getFunction().str());
121 JOS.attribute("total", S.getTotalSamples());
122if (TopLevel)
123 JOS.attribute("head", S.getHeadSamples());
124
125constauto &BodySamples = S.getBodySamples();
126if (!BodySamples.empty())
127 JOS.attributeArray("body", [&] { DumpBody(BodySamples); });
128
129constauto &CallsiteSamples = S.getCallsiteSamples();
130if (!CallsiteSamples.empty())
131 JOS.attributeArray("callsites",
132 [&] { DumpCallsiteSamples(CallsiteSamples); });
133 });
134}
135
136/// Dump all the function profiles found on stream \p OS in the JSON format.
137voidSampleProfileReader::dumpJson(raw_ostream &OS) {
138 std::vector<NameFunctionSamples> V;
139sortFuncProfiles(Profiles, V);
140json::OStream JOS(OS, 2);
141 JOS.arrayBegin();
142for (constauto &F : V)
143dumpFunctionProfileJson(*F.second, JOS,true);
144 JOS.arrayEnd();
145
146// Emit a newline character at the end as json::OStream doesn't emit one.
147OS <<"\n";
148}
149
150/// Parse \p Input as function head.
151///
152/// Parse one line of \p Input, and update function name in \p FName,
153/// function's total sample count in \p NumSamples, function's entry
154/// count in \p NumHeadSamples.
155///
156/// \returns true if parsing is successful.
157staticboolParseHead(constStringRef &Input,StringRef &FName,
158uint64_t &NumSamples,uint64_t &NumHeadSamples) {
159if (Input[0] ==' ')
160returnfalse;
161size_t n2 = Input.rfind(':');
162size_t n1 = Input.rfind(':', n2 - 1);
163 FName = Input.substr(0, n1);
164if (Input.substr(n1 + 1, n2 - n1 - 1).getAsInteger(10, NumSamples))
165returnfalse;
166if (Input.substr(n2 + 1).getAsInteger(10, NumHeadSamples))
167returnfalse;
168returntrue;
169}
170
171/// Returns true if line offset \p L is legal (only has 16 bits).
172staticboolisOffsetLegal(unsigned L) {return (L & 0xffff) == L; }
173
174/// Parse \p Input that contains metadata.
175/// Possible metadata:
176/// - CFG Checksum information:
177/// !CFGChecksum: 12345
178/// - CFG Checksum information:
179/// !Attributes: 1
180/// Stores the FunctionHash (a.k.a. CFG Checksum) into \p FunctionHash.
181staticboolparseMetadata(constStringRef &Input,uint64_t &FunctionHash,
182uint32_t &Attributes) {
183if (Input.starts_with("!CFGChecksum:")) {
184StringRef CFGInfo = Input.substr(strlen("!CFGChecksum:")).trim();
185return !CFGInfo.getAsInteger(10, FunctionHash);
186 }
187
188if (Input.starts_with("!Attributes:")) {
189StringRef Attrib = Input.substr(strlen("!Attributes:")).trim();
190return !Attrib.getAsInteger(10,Attributes);
191 }
192
193returnfalse;
194}
195
196enum classLineType {
197CallSiteProfile,
198BodyProfile,
199Metadata,
200};
201
202/// Parse \p Input as line sample.
203///
204/// \param Input input line.
205/// \param LineTy Type of this line.
206/// \param Depth the depth of the inline stack.
207/// \param NumSamples total samples of the line/inlined callsite.
208/// \param LineOffset line offset to the start of the function.
209/// \param Discriminator discriminator of the line.
210/// \param TargetCountMap map from indirect call target to count.
211/// \param FunctionHash the function's CFG hash, used by pseudo probe.
212///
213/// returns true if parsing is successful.
214staticboolParseLine(constStringRef &Input,LineType &LineTy,uint32_t &Depth,
215uint64_t &NumSamples,uint32_t &LineOffset,
216uint32_t &Discriminator,StringRef &CalleeName,
217DenseMap<StringRef, uint64_t> &TargetCountMap,
218uint64_t &FunctionHash,uint32_t &Attributes,
219bool &IsFlat) {
220for (Depth = 0; Input[Depth] ==' ';Depth++)
221 ;
222if (Depth == 0)
223returnfalse;
224
225if (Input[Depth] =='!') {
226 LineTy = LineType::Metadata;
227// This metadata is only for manual inspection only. We already created a
228// FunctionSamples and put it in the profile map, so there is no point
229// to skip profiles even they have no use for ThinLTO.
230if (Input ==StringRef(" !Flat")) {
231 IsFlat =true;
232returntrue;
233 }
234returnparseMetadata(Input.substr(Depth), FunctionHash,Attributes);
235 }
236
237size_t n1 = Input.find(':');
238StringRef Loc = Input.substr(Depth, n1 -Depth);
239size_t n2 = Loc.find('.');
240if (n2 ==StringRef::npos) {
241if (Loc.getAsInteger(10, LineOffset) || !isOffsetLegal(LineOffset))
242returnfalse;
243 Discriminator = 0;
244 }else {
245if (Loc.substr(0, n2).getAsInteger(10, LineOffset))
246returnfalse;
247if (Loc.substr(n2 + 1).getAsInteger(10, Discriminator))
248returnfalse;
249 }
250
251StringRef Rest = Input.substr(n1 + 2);
252if (isDigit(Rest[0])) {
253 LineTy = LineType::BodyProfile;
254size_t n3 = Rest.find(' ');
255if (n3 ==StringRef::npos) {
256if (Rest.getAsInteger(10, NumSamples))
257returnfalse;
258 }else {
259if (Rest.substr(0, n3).getAsInteger(10, NumSamples))
260returnfalse;
261 }
262// Find call targets and their sample counts.
263// Note: In some cases, there are symbols in the profile which are not
264// mangled. To accommodate such cases, use colon + integer pairs as the
265// anchor points.
266// An example:
267// _M_construct<char *>:1000 string_view<std::allocator<char> >:437
268// ":1000" and ":437" are used as anchor points so the string above will
269// be interpreted as
270// target: _M_construct<char *>
271// count: 1000
272// target: string_view<std::allocator<char> >
273// count: 437
274while (n3 !=StringRef::npos) {
275 n3 += Rest.substr(n3).find_first_not_of(' ');
276 Rest = Rest.substr(n3);
277 n3 = Rest.find_first_of(':');
278if (n3 ==StringRef::npos || n3 == 0)
279returnfalse;
280
281StringRefTarget;
282uint64_tcount, n4;
283while (true) {
284// Get the segment after the current colon.
285StringRef AfterColon = Rest.substr(n3 + 1);
286// Get the target symbol before the current colon.
287Target = Rest.substr(0, n3);
288// Check if the word after the current colon is an integer.
289 n4 = AfterColon.find_first_of(' ');
290 n4 = (n4 !=StringRef::npos) ? n3 + n4 + 1 : Rest.size();
291StringRef WordAfterColon = Rest.substr(n3 + 1, n4 - n3 - 1);
292if (!WordAfterColon.getAsInteger(10,count))
293break;
294
295// Try to find the next colon.
296uint64_t n5 = AfterColon.find_first_of(':');
297if (n5 ==StringRef::npos)
298returnfalse;
299 n3 += n5 + 1;
300 }
301
302// An anchor point is found. Save the {target, count} pair
303 TargetCountMap[Target] =count;
304if (n4 == Rest.size())
305break;
306// Change n3 to the next blank space after colon + integer pair.
307 n3 = n4;
308 }
309 }else {
310 LineTy = LineType::CallSiteProfile;
311size_t n3 = Rest.find_last_of(':');
312 CalleeName = Rest.substr(0, n3);
313if (Rest.substr(n3 + 1).getAsInteger(10, NumSamples))
314returnfalse;
315 }
316returntrue;
317}
318
319/// Load samples from a text file.
320///
321/// See the documentation at the top of the file for an explanation of
322/// the expected format.
323///
324/// \returns true if the file was loaded successfully, false otherwise.
325std::error_codeSampleProfileReaderText::readImpl() {
326line_iterator LineIt(*Buffer,/*SkipBlanks=*/true,'#');
327sampleprof_error Result =sampleprof_error::success;
328
329InlineCallStack InlineStack;
330uint32_t TopLevelProbeProfileCount = 0;
331
332// DepthMetadata tracks whether we have processed metadata for the current
333// top-level or nested function profile.
334uint32_t DepthMetadata = 0;
335
336 std::vector<SampleContext *> FlatSamples;
337
338ProfileIsFS =ProfileIsFSDisciminator;
339FunctionSamples::ProfileIsFS =ProfileIsFS;
340for (; !LineIt.is_at_eof(); ++LineIt) {
341size_t pos = LineIt->find_first_not_of(' ');
342if (pos == LineIt->npos || (*LineIt)[pos] =='#')
343continue;
344// Read the header of each function.
345//
346// Note that for function identifiers we are actually expecting
347// mangled names, but we may not always get them. This happens when
348// the compiler decides not to emit the function (e.g., it was inlined
349// and removed). In this case, the binary will not have the linkage
350// name for the function, so the profiler will emit the function's
351// unmangled name, which may contain characters like ':' and '>' in its
352// name (member functions, templates, etc).
353//
354// The only requirement we place on the identifier, then, is that it
355// should not begin with a number.
356if ((*LineIt)[0] !=' ') {
357uint64_t NumSamples, NumHeadSamples;
358StringRef FName;
359if (!ParseHead(*LineIt, FName, NumSamples, NumHeadSamples)) {
360reportError(LineIt.line_number(),
361"Expected 'mangled_name:NUM:NUM', found " + *LineIt);
362returnsampleprof_error::malformed;
363 }
364 DepthMetadata = 0;
365SampleContext FContext(FName, CSNameTable);
366if (FContext.hasContext())
367 ++CSProfileCount;
368FunctionSamples &FProfile =Profiles.create(FContext);
369mergeSampleProfErrors(Result, FProfile.addTotalSamples(NumSamples));
370mergeSampleProfErrors(Result, FProfile.addHeadSamples(NumHeadSamples));
371 InlineStack.clear();
372 InlineStack.push_back(&FProfile);
373 }else {
374uint64_t NumSamples;
375StringRef FName;
376DenseMap<StringRef, uint64_t> TargetCountMap;
377uint32_tDepth, LineOffset, Discriminator;
378LineType LineTy;
379uint64_t FunctionHash = 0;
380uint32_tAttributes = 0;
381bool IsFlat =false;
382if (!ParseLine(*LineIt, LineTy,Depth, NumSamples, LineOffset,
383 Discriminator, FName, TargetCountMap, FunctionHash,
384Attributes, IsFlat)) {
385reportError(LineIt.line_number(),
386"Expected 'NUM[.NUM]: NUM[ mangled_name:NUM]*', found " +
387 *LineIt);
388returnsampleprof_error::malformed;
389 }
390if (LineTy != LineType::Metadata &&Depth == DepthMetadata) {
391// Metadata must be put at the end of a function profile.
392reportError(LineIt.line_number(),
393"Found non-metadata after metadata: " + *LineIt);
394returnsampleprof_error::malformed;
395 }
396
397// Here we handle FS discriminators.
398 Discriminator &=getDiscriminatorMask();
399
400while (InlineStack.size() >Depth) {
401 InlineStack.pop_back();
402 }
403switch (LineTy) {
404case LineType::CallSiteProfile: {
405FunctionSamples &FSamples = InlineStack.back()->functionSamplesAt(
406LineLocation(LineOffset, Discriminator))[FunctionId(FName)];
407 FSamples.setFunction(FunctionId(FName));
408mergeSampleProfErrors(Result, FSamples.addTotalSamples(NumSamples));
409 InlineStack.push_back(&FSamples);
410 DepthMetadata = 0;
411break;
412 }
413case LineType::BodyProfile: {
414while (InlineStack.size() >Depth) {
415 InlineStack.pop_back();
416 }
417FunctionSamples &FProfile = *InlineStack.back();
418for (constauto &name_count : TargetCountMap) {
419mergeSampleProfErrors(Result, FProfile.addCalledTargetSamples(
420 LineOffset, Discriminator,
421FunctionId(name_count.first),
422 name_count.second));
423 }
424mergeSampleProfErrors(
425 Result,
426 FProfile.addBodySamples(LineOffset, Discriminator, NumSamples));
427break;
428 }
429case LineType::Metadata: {
430FunctionSamples &FProfile = *InlineStack.back();
431if (FunctionHash) {
432 FProfile.setFunctionHash(FunctionHash);
433if (Depth == 1)
434 ++TopLevelProbeProfileCount;
435 }
436 FProfile.getContext().setAllAttributes(Attributes);
437if (Attributes & (uint32_t)ContextShouldBeInlined)
438ProfileIsPreInlined =true;
439 DepthMetadata =Depth;
440if (IsFlat) {
441if (Depth == 1)
442 FlatSamples.push_back(&FProfile.getContext());
443else
444Ctx.diagnose(DiagnosticInfoSampleProfile(
445Buffer->getBufferIdentifier(), LineIt.line_number(),
446"!Flat may only be used at top level function.",DS_Warning));
447 }
448break;
449 }
450 }
451 }
452 }
453
454// Honor the option to skip flat functions. Since they are already added to
455// the profile map, remove them all here.
456if (SkipFlatProf)
457for (SampleContext *FlatSample : FlatSamples)
458Profiles.erase(*FlatSample);
459
460assert((CSProfileCount == 0 ||CSProfileCount ==Profiles.size()) &&
461"Cannot have both context-sensitive and regular profile");
462ProfileIsCS = (CSProfileCount > 0);
463assert((TopLevelProbeProfileCount == 0 ||
464 TopLevelProbeProfileCount ==Profiles.size()) &&
465"Cannot have both probe-based profiles and regular profiles");
466ProfileIsProbeBased = (TopLevelProbeProfileCount > 0);
467FunctionSamples::ProfileIsProbeBased =ProfileIsProbeBased;
468FunctionSamples::ProfileIsCS =ProfileIsCS;
469FunctionSamples::ProfileIsPreInlined =ProfileIsPreInlined;
470
471if (Result ==sampleprof_error::success)
472computeSummary();
473
474return Result;
475}
476
477boolSampleProfileReaderText::hasFormat(constMemoryBuffer &Buffer) {
478bool result =false;
479
480// Check that the first non-comment line is a valid function header.
481line_iterator LineIt(Buffer,/*SkipBlanks=*/true,'#');
482if (!LineIt.is_at_eof()) {
483if ((*LineIt)[0] !=' ') {
484uint64_t NumSamples, NumHeadSamples;
485StringRef FName;
486 result =ParseHead(*LineIt, FName, NumSamples, NumHeadSamples);
487 }
488 }
489
490return result;
491}
492
493template <typename T>ErrorOr<T>SampleProfileReaderBinary::readNumber() {
494unsigned NumBytesRead = 0;
495uint64_t Val =decodeULEB128(Data, &NumBytesRead);
496
497if (Val > std::numeric_limits<T>::max()) {
498 std::error_code EC =sampleprof_error::malformed;
499reportError(0, EC.message());
500return EC;
501 }elseif (Data + NumBytesRead >End) {
502 std::error_code EC =sampleprof_error::truncated;
503reportError(0, EC.message());
504return EC;
505 }
506
507Data += NumBytesRead;
508returnstatic_cast<T>(Val);
509}
510
511ErrorOr<StringRef>SampleProfileReaderBinary::readString() {
512StringRef Str(reinterpret_cast<constchar *>(Data));
513if (Data + Str.size() + 1 >End) {
514 std::error_code EC =sampleprof_error::truncated;
515reportError(0, EC.message());
516return EC;
517 }
518
519Data += Str.size() + 1;
520return Str;
521}
522
523template <typename T>
524ErrorOr<T>SampleProfileReaderBinary::readUnencodedNumber() {
525if (Data +sizeof(T) >End) {
526 std::error_code EC =sampleprof_error::truncated;
527reportError(0, EC.message());
528return EC;
529 }
530
531using namespacesupport;
532T Val = endian::readNext<T, llvm::endianness::little>(Data);
533return Val;
534}
535
536template <typename T>
537inlineErrorOr<size_t>SampleProfileReaderBinary::readStringIndex(T &Table) {
538autoIdx = readNumber<size_t>();
539if (std::error_code EC =Idx.getError())
540return EC;
541if (*Idx >= Table.size())
542returnsampleprof_error::truncated_name_table;
543return *Idx;
544}
545
546ErrorOr<FunctionId>
547SampleProfileReaderBinary::readStringFromTable(size_t *RetIdx) {
548autoIdx =readStringIndex(NameTable);
549if (std::error_code EC =Idx.getError())
550return EC;
551if (RetIdx)
552 *RetIdx = *Idx;
553returnNameTable[*Idx];
554}
555
556ErrorOr<SampleContextFrames>
557SampleProfileReaderBinary::readContextFromTable(size_t *RetIdx) {
558auto ContextIdx = readNumber<size_t>();
559if (std::error_code EC = ContextIdx.getError())
560return EC;
561if (*ContextIdx >=CSNameTable.size())
562returnsampleprof_error::truncated_name_table;
563if (RetIdx)
564 *RetIdx = *ContextIdx;
565returnCSNameTable[*ContextIdx];
566}
567
568ErrorOr<std::pair<SampleContext, uint64_t>>
569SampleProfileReaderBinary::readSampleContextFromTable() {
570SampleContext Context;
571size_tIdx;
572if (ProfileIsCS) {
573auto FContext(readContextFromTable(&Idx));
574if (std::error_code EC = FContext.getError())
575return EC;
576 Context =SampleContext(*FContext);
577 }else {
578auto FName(readStringFromTable(&Idx));
579if (std::error_code EC = FName.getError())
580return EC;
581 Context =SampleContext(*FName);
582 }
583// Since MD5SampleContextStart may point to the profile's file data, need to
584// make sure it is reading the same value on big endian CPU.
585uint64_t Hash =support::endian::read64le(MD5SampleContextStart +Idx);
586// Lazy computing of hash value, write back to the table to cache it. Only
587// compute the context's hash value if it is being referenced for the first
588// time.
589if (Hash == 0) {
590assert(MD5SampleContextStart ==MD5SampleContextTable.data());
591 Hash = Context.getHashCode();
592support::endian::write64le(&MD5SampleContextTable[Idx], Hash);
593 }
594return std::make_pair(Context, Hash);
595}
596
597std::error_code
598SampleProfileReaderBinary::readProfile(FunctionSamples &FProfile) {
599auto NumSamples = readNumber<uint64_t>();
600if (std::error_code EC = NumSamples.getError())
601return EC;
602 FProfile.addTotalSamples(*NumSamples);
603
604// Read the samples in the body.
605auto NumRecords = readNumber<uint32_t>();
606if (std::error_code EC = NumRecords.getError())
607return EC;
608
609for (uint32_tI = 0;I < *NumRecords; ++I) {
610auto LineOffset = readNumber<uint64_t>();
611if (std::error_code EC = LineOffset.getError())
612return EC;
613
614if (!isOffsetLegal(*LineOffset)) {
615return std::error_code();
616 }
617
618auto Discriminator = readNumber<uint64_t>();
619if (std::error_code EC = Discriminator.getError())
620return EC;
621
622auto NumSamples = readNumber<uint64_t>();
623if (std::error_code EC = NumSamples.getError())
624return EC;
625
626auto NumCalls = readNumber<uint32_t>();
627if (std::error_code EC = NumCalls.getError())
628return EC;
629
630// Here we handle FS discriminators:
631uint32_t DiscriminatorVal = (*Discriminator) &getDiscriminatorMask();
632
633for (uint32_t J = 0; J < *NumCalls; ++J) {
634auto CalledFunction(readStringFromTable());
635if (std::error_code EC = CalledFunction.getError())
636return EC;
637
638auto CalledFunctionSamples = readNumber<uint64_t>();
639if (std::error_code EC = CalledFunctionSamples.getError())
640return EC;
641
642 FProfile.addCalledTargetSamples(*LineOffset, DiscriminatorVal,
643 *CalledFunction, *CalledFunctionSamples);
644 }
645
646 FProfile.addBodySamples(*LineOffset, DiscriminatorVal, *NumSamples);
647 }
648
649// Read all the samples for inlined function calls.
650auto NumCallsites = readNumber<uint32_t>();
651if (std::error_code EC = NumCallsites.getError())
652return EC;
653
654for (uint32_t J = 0; J < *NumCallsites; ++J) {
655auto LineOffset = readNumber<uint64_t>();
656if (std::error_code EC = LineOffset.getError())
657return EC;
658
659auto Discriminator = readNumber<uint64_t>();
660if (std::error_code EC = Discriminator.getError())
661return EC;
662
663auto FName(readStringFromTable());
664if (std::error_code EC = FName.getError())
665return EC;
666
667// Here we handle FS discriminators:
668uint32_t DiscriminatorVal = (*Discriminator) &getDiscriminatorMask();
669
670FunctionSamples &CalleeProfile = FProfile.functionSamplesAt(
671LineLocation(*LineOffset, DiscriminatorVal))[*FName];
672 CalleeProfile.setFunction(*FName);
673if (std::error_code EC =readProfile(CalleeProfile))
674return EC;
675 }
676
677returnsampleprof_error::success;
678}
679
680std::error_code
681SampleProfileReaderBinary::readFuncProfile(constuint8_t *Start,
682SampleProfileMap &Profiles) {
683Data = Start;
684auto NumHeadSamples = readNumber<uint64_t>();
685if (std::error_code EC = NumHeadSamples.getError())
686return EC;
687
688auto FContextHash(readSampleContextFromTable());
689if (std::error_code EC = FContextHash.getError())
690return EC;
691
692auto &[FContext, Hash] = *FContextHash;
693// Use the cached hash value for insertion instead of recalculating it.
694auto Res =Profiles.try_emplace(Hash, FContext,FunctionSamples());
695FunctionSamples &FProfile = Res.first->second;
696 FProfile.setContext(FContext);
697 FProfile.addHeadSamples(*NumHeadSamples);
698
699if (FContext.hasContext())
700CSProfileCount++;
701
702if (std::error_code EC =readProfile(FProfile))
703return EC;
704returnsampleprof_error::success;
705}
706
707std::error_code
708SampleProfileReaderBinary::readFuncProfile(constuint8_t *Start) {
709returnreadFuncProfile(Start,Profiles);
710}
711
712std::error_codeSampleProfileReaderBinary::readImpl() {
713ProfileIsFS =ProfileIsFSDisciminator;
714FunctionSamples::ProfileIsFS =ProfileIsFS;
715while (Data <End) {
716if (std::error_code EC =readFuncProfile(Data))
717return EC;
718 }
719
720returnsampleprof_error::success;
721}
722
723std::error_codeSampleProfileReaderExtBinaryBase::readOneSection(
724constuint8_t *Start,uint64_tSize,constSecHdrTableEntry &Entry) {
725Data = Start;
726End = Start +Size;
727switch (Entry.Type) {
728caseSecProfSummary:
729if (std::error_code EC =readSummary())
730return EC;
731if (hasSecFlag(Entry,SecProfSummaryFlags::SecFlagPartial))
732Summary->setPartialProfile(true);
733if (hasSecFlag(Entry,SecProfSummaryFlags::SecFlagFullContext))
734FunctionSamples::ProfileIsCS =ProfileIsCS =true;
735if (hasSecFlag(Entry,SecProfSummaryFlags::SecFlagIsPreInlined))
736FunctionSamples::ProfileIsPreInlined =ProfileIsPreInlined =true;
737if (hasSecFlag(Entry,SecProfSummaryFlags::SecFlagFSDiscriminator))
738FunctionSamples::ProfileIsFS =ProfileIsFS =true;
739break;
740caseSecNameTable: {
741bool FixedLengthMD5 =
742hasSecFlag(Entry,SecNameTableFlags::SecFlagFixedLengthMD5);
743bool UseMD5 =hasSecFlag(Entry,SecNameTableFlags::SecFlagMD5Name);
744// UseMD5 means if THIS section uses MD5, ProfileIsMD5 means if the entire
745// profile uses MD5 for function name matching in IPO passes.
746ProfileIsMD5 =ProfileIsMD5 || UseMD5;
747FunctionSamples::HasUniqSuffix =
748hasSecFlag(Entry,SecNameTableFlags::SecFlagUniqSuffix);
749if (std::error_code EC =readNameTableSec(UseMD5, FixedLengthMD5))
750return EC;
751break;
752 }
753caseSecCSNameTable: {
754if (std::error_code EC =readCSNameTableSec())
755return EC;
756break;
757 }
758caseSecLBRProfile:
759ProfileSecRange = std::make_pair(Data,End);
760if (std::error_code EC =readFuncProfiles())
761return EC;
762break;
763caseSecFuncOffsetTable:
764// If module is absent, we are using LLVM tools, and need to read all
765// profiles, so skip reading the function offset table.
766if (!M) {
767Data =End;
768 }else {
769assert((!ProfileIsCS ||
770hasSecFlag(Entry,SecFuncOffsetFlags::SecFlagOrdered)) &&
771"func offset table should always be sorted in CS profile");
772if (std::error_code EC =readFuncOffsetTable())
773return EC;
774 }
775break;
776caseSecFuncMetadata: {
777ProfileIsProbeBased =
778hasSecFlag(Entry,SecFuncMetadataFlags::SecFlagIsProbeBased);
779FunctionSamples::ProfileIsProbeBased =ProfileIsProbeBased;
780ProfileHasAttribute =
781hasSecFlag(Entry,SecFuncMetadataFlags::SecFlagHasAttribute);
782if (std::error_code EC =readFuncMetadata(ProfileHasAttribute))
783return EC;
784break;
785 }
786caseSecProfileSymbolList:
787if (std::error_code EC =readProfileSymbolList())
788return EC;
789break;
790default:
791if (std::error_code EC =readCustomSection(Entry))
792return EC;
793break;
794 }
795returnsampleprof_error::success;
796}
797
798boolSampleProfileReaderExtBinaryBase::useFuncOffsetList() const{
799// If profile is CS, the function offset section is expected to consist of
800// sequences of contexts in pre-order layout
801// (e.g. [A, A:1 @ B, A:1 @ B:2.3 @ C] [D, D:1 @ E]), so that when a matched
802// context in the module is found, the profiles of all its callees are
803// recursively loaded. A list is needed since the order of profiles matters.
804if (ProfileIsCS)
805returntrue;
806
807// If the profile is MD5, use the map container to lookup functions in
808// the module. A remapper has no use on MD5 names.
809if (useMD5())
810returnfalse;
811
812// Profile is not MD5 and if a remapper is present, the remapped name of
813// every function needed to be matched against the module, so use the list
814// container since each entry is accessed.
815if (Remapper)
816returntrue;
817
818// Otherwise use the map container for faster lookup.
819// TODO: If the cardinality of the function offset section is much smaller
820// than the number of functions in the module, using the list container can
821// be always faster, but we need to figure out the constant factor to
822// determine the cutoff.
823returnfalse;
824}
825
826std::error_code
827SampleProfileReaderExtBinaryBase::read(constDenseSet<StringRef> &FuncsToUse,
828SampleProfileMap &Profiles) {
829Data =ProfileSecRange.first;
830End =ProfileSecRange.second;
831if (std::error_code EC =readFuncProfiles(FuncsToUse,Profiles))
832return EC;
833End =Data;
834
835if (std::error_code EC =readFuncMetadata(ProfileHasAttribute,Profiles))
836return EC;
837returnsampleprof_error::success;
838}
839
840boolSampleProfileReaderExtBinaryBase::collectFuncsFromModule() {
841if (!M)
842returnfalse;
843FuncsToUse.clear();
844for (auto &F : *M)
845FuncsToUse.insert(FunctionSamples::getCanonicalFnName(F));
846returntrue;
847}
848
849std::error_codeSampleProfileReaderExtBinaryBase::readFuncOffsetTable() {
850// If there are more than one function offset section, the profile associated
851// with the previous section has to be done reading before next one is read.
852FuncOffsetTable.clear();
853FuncOffsetList.clear();
854
855autoSize = readNumber<uint64_t>();
856if (std::error_code EC =Size.getError())
857return EC;
858
859bool UseFuncOffsetList =useFuncOffsetList();
860if (UseFuncOffsetList)
861FuncOffsetList.reserve(*Size);
862else
863FuncOffsetTable.reserve(*Size);
864
865for (uint64_tI = 0;I < *Size; ++I) {
866auto FContextHash(readSampleContextFromTable());
867if (std::error_code EC = FContextHash.getError())
868return EC;
869
870auto &[FContext, Hash] = *FContextHash;
871autoOffset = readNumber<uint64_t>();
872if (std::error_code EC =Offset.getError())
873return EC;
874
875if (UseFuncOffsetList)
876FuncOffsetList.emplace_back(FContext, *Offset);
877else
878// Because Porfiles replace existing value with new value if collision
879// happens, we also use the latest offset so that they are consistent.
880FuncOffsetTable[Hash] = *Offset;
881 }
882
883returnsampleprof_error::success;
884}
885
886std::error_codeSampleProfileReaderExtBinaryBase::readFuncProfiles(
887constDenseSet<StringRef> &FuncsToUse,SampleProfileMap &Profiles) {
888constuint8_t *Start =Data;
889
890if (Remapper) {
891for (autoName :FuncsToUse) {
892Remapper->insert(Name);
893 }
894 }
895
896if (ProfileIsCS) {
897assert(useFuncOffsetList());
898DenseSet<uint64_t> FuncGuidsToUse;
899if (useMD5()) {
900for (autoName :FuncsToUse)
901 FuncGuidsToUse.insert(Function::getGUID(Name));
902 }
903
904// For each function in current module, load all context profiles for
905// the function as well as their callee contexts which can help profile
906// guided importing for ThinLTO. This can be achieved by walking
907// through an ordered context container, where contexts are laid out
908// as if they were walked in preorder of a context trie. While
909// traversing the trie, a link to the highest common ancestor node is
910// kept so that all of its decendants will be loaded.
911constSampleContext *CommonContext =nullptr;
912for (constauto &NameOffset :FuncOffsetList) {
913constauto &FContext = NameOffset.first;
914FunctionId FName = FContext.getFunction();
915StringRef FNameString;
916if (!useMD5())
917 FNameString = FName.stringRef();
918
919// For function in the current module, keep its farthest ancestor
920// context. This can be used to load itself and its child and
921// sibling contexts.
922if ((useMD5() && FuncGuidsToUse.count(FName.getHashCode())) ||
923 (!useMD5() && (FuncsToUse.count(FNameString) ||
924 (Remapper &&Remapper->exist(FNameString))))) {
925if (!CommonContext || !CommonContext->isPrefixOf(FContext))
926 CommonContext = &FContext;
927 }
928
929if (CommonContext == &FContext ||
930 (CommonContext && CommonContext->isPrefixOf(FContext))) {
931// Load profile for the current context which originated from
932// the common ancestor.
933constuint8_t *FuncProfileAddr = Start + NameOffset.second;
934if (std::error_code EC =readFuncProfile(FuncProfileAddr))
935return EC;
936 }
937 }
938 }elseif (useMD5()) {
939assert(!useFuncOffsetList());
940for (autoName :FuncsToUse) {
941auto GUID =MD5Hash(Name);
942auto iter =FuncOffsetTable.find(GUID);
943if (iter ==FuncOffsetTable.end())
944continue;
945constuint8_t *FuncProfileAddr = Start + iter->second;
946if (std::error_code EC =readFuncProfile(FuncProfileAddr,Profiles))
947return EC;
948 }
949 }elseif (Remapper) {
950assert(useFuncOffsetList());
951for (auto NameOffset :FuncOffsetList) {
952SampleContext FContext(NameOffset.first);
953auto FuncName = FContext.getFunction();
954StringRef FuncNameStr = FuncName.stringRef();
955if (!FuncsToUse.count(FuncNameStr) && !Remapper->exist(FuncNameStr))
956continue;
957constuint8_t *FuncProfileAddr = Start + NameOffset.second;
958if (std::error_code EC =readFuncProfile(FuncProfileAddr,Profiles))
959return EC;
960 }
961 }else {
962assert(!useFuncOffsetList());
963for (autoName :FuncsToUse) {
964
965auto iter =FuncOffsetTable.find(MD5Hash(Name));
966if (iter ==FuncOffsetTable.end())
967continue;
968constuint8_t *FuncProfileAddr = Start + iter->second;
969if (std::error_code EC =readFuncProfile(FuncProfileAddr,Profiles))
970return EC;
971 }
972 }
973
974returnsampleprof_error::success;
975}
976
977std::error_codeSampleProfileReaderExtBinaryBase::readFuncProfiles() {
978// Collect functions used by current module if the Reader has been
979// given a module.
980// collectFuncsFromModule uses FunctionSamples::getCanonicalFnName
981// which will query FunctionSamples::HasUniqSuffix, so it has to be
982// called after FunctionSamples::HasUniqSuffix is set, i.e. after
983// NameTable section is read.
984bool LoadFuncsToBeUsed =collectFuncsFromModule();
985
986// When LoadFuncsToBeUsed is false, we are using LLVM tool, need to read all
987// profiles.
988if (!LoadFuncsToBeUsed) {
989while (Data <End) {
990if (std::error_code EC =readFuncProfile(Data))
991return EC;
992 }
993assert(Data ==End &&"More data is read than expected");
994 }else {
995// Load function profiles on demand.
996if (std::error_code EC =readFuncProfiles(FuncsToUse,Profiles))
997return EC;
998Data =End;
999 }
1000assert((CSProfileCount == 0 ||CSProfileCount ==Profiles.size()) &&
1001"Cannot have both context-sensitive and regular profile");
1002assert((!CSProfileCount ||ProfileIsCS) &&
1003"Section flag should be consistent with actual profile");
1004returnsampleprof_error::success;
1005}
1006
1007std::error_codeSampleProfileReaderExtBinaryBase::readProfileSymbolList() {
1008if (!ProfSymList)
1009ProfSymList = std::make_unique<ProfileSymbolList>();
1010
1011if (std::error_code EC =ProfSymList->read(Data,End -Data))
1012return EC;
1013
1014Data =End;
1015returnsampleprof_error::success;
1016}
1017
1018std::error_code SampleProfileReaderExtBinaryBase::decompressSection(
1019constuint8_t *SecStart,constuint64_t SecSize,
1020constuint8_t *&DecompressBuf,uint64_t &DecompressBufSize) {
1021Data = SecStart;
1022End = SecStart + SecSize;
1023auto DecompressSize = readNumber<uint64_t>();
1024if (std::error_code EC = DecompressSize.getError())
1025return EC;
1026 DecompressBufSize = *DecompressSize;
1027
1028auto CompressSize = readNumber<uint64_t>();
1029if (std::error_code EC = CompressSize.getError())
1030return EC;
1031
1032if (!llvm::compression::zlib::isAvailable())
1033returnsampleprof_error::zlib_unavailable;
1034
1035uint8_t *Buffer = Allocator.Allocate<uint8_t>(DecompressBufSize);
1036size_t UCSize = DecompressBufSize;
1037llvm::Error E =compression::zlib::decompress(ArrayRef(Data, *CompressSize),
1038Buffer, UCSize);
1039if (E)
1040returnsampleprof_error::uncompress_failed;
1041 DecompressBuf =reinterpret_cast<constuint8_t *>(Buffer);
1042returnsampleprof_error::success;
1043}
1044
1045std::error_codeSampleProfileReaderExtBinaryBase::readImpl() {
1046constuint8_t *BufStart =
1047reinterpret_cast<constuint8_t *>(Buffer->getBufferStart());
1048
1049for (auto &Entry :SecHdrTable) {
1050// Skip empty section.
1051if (!Entry.Size)
1052continue;
1053
1054// Skip sections without inlined functions when SkipFlatProf is true.
1055if (SkipFlatProf &&hasSecFlag(Entry,SecCommonFlags::SecFlagFlat))
1056continue;
1057
1058constuint8_t *SecStart = BufStart + Entry.Offset;
1059uint64_t SecSize = Entry.Size;
1060
1061// If the section is compressed, decompress it into a buffer
1062// DecompressBuf before reading the actual data. The pointee of
1063// 'Data' will be changed to buffer hold by DecompressBuf
1064// temporarily when reading the actual data.
1065bool isCompressed =hasSecFlag(Entry,SecCommonFlags::SecFlagCompress);
1066if (isCompressed) {
1067constuint8_t *DecompressBuf;
1068uint64_t DecompressBufSize;
1069if (std::error_code EC = decompressSection(
1070 SecStart, SecSize, DecompressBuf, DecompressBufSize))
1071return EC;
1072 SecStart = DecompressBuf;
1073 SecSize = DecompressBufSize;
1074 }
1075
1076if (std::error_code EC =readOneSection(SecStart, SecSize, Entry))
1077return EC;
1078if (Data != SecStart + SecSize)
1079returnsampleprof_error::malformed;
1080
1081// Change the pointee of 'Data' from DecompressBuf to original Buffer.
1082if (isCompressed) {
1083Data = BufStart + Entry.Offset;
1084End = BufStart +Buffer->getBufferSize();
1085 }
1086 }
1087
1088returnsampleprof_error::success;
1089}
1090
1091std::error_code SampleProfileReaderRawBinary::verifySPMagic(uint64_t Magic) {
1092if (Magic ==SPMagic())
1093returnsampleprof_error::success;
1094returnsampleprof_error::bad_magic;
1095}
1096
1097std::error_code SampleProfileReaderExtBinary::verifySPMagic(uint64_t Magic) {
1098if (Magic ==SPMagic(SPF_Ext_Binary))
1099returnsampleprof_error::success;
1100returnsampleprof_error::bad_magic;
1101}
1102
1103std::error_codeSampleProfileReaderBinary::readNameTable() {
1104autoSize = readNumber<size_t>();
1105if (std::error_code EC =Size.getError())
1106return EC;
1107
1108// Normally if useMD5 is true, the name table should have MD5 values, not
1109// strings, however in the case that ExtBinary profile has multiple name
1110// tables mixing string and MD5, all of them have to be normalized to use MD5,
1111// because optimization passes can only handle either type.
1112bool UseMD5 =useMD5();
1113
1114NameTable.clear();
1115NameTable.reserve(*Size);
1116if (!ProfileIsCS) {
1117MD5SampleContextTable.clear();
1118if (UseMD5)
1119MD5SampleContextTable.reserve(*Size);
1120else
1121// If we are using strings, delay MD5 computation since only a portion of
1122// names are used by top level functions. Use 0 to indicate MD5 value is
1123// to be calculated as no known string has a MD5 value of 0.
1124MD5SampleContextTable.resize(*Size);
1125 }
1126for (size_tI = 0;I < *Size; ++I) {
1127autoName(readString());
1128if (std::error_code EC =Name.getError())
1129return EC;
1130if (UseMD5) {
1131FunctionId FID(*Name);
1132if (!ProfileIsCS)
1133MD5SampleContextTable.emplace_back(FID.getHashCode());
1134NameTable.emplace_back(FID);
1135 }else
1136NameTable.push_back(FunctionId(*Name));
1137 }
1138if (!ProfileIsCS)
1139MD5SampleContextStart =MD5SampleContextTable.data();
1140returnsampleprof_error::success;
1141}
1142
1143std::error_code
1144SampleProfileReaderExtBinaryBase::readNameTableSec(bool IsMD5,
1145bool FixedLengthMD5) {
1146if (FixedLengthMD5) {
1147if (!IsMD5)
1148errs() <<"If FixedLengthMD5 is true, UseMD5 has to be true";
1149autoSize = readNumber<size_t>();
1150if (std::error_code EC =Size.getError())
1151return EC;
1152
1153assert(Data + (*Size) *sizeof(uint64_t) ==End &&
1154"Fixed length MD5 name table does not contain specified number of "
1155"entries");
1156if (Data + (*Size) *sizeof(uint64_t) >End)
1157returnsampleprof_error::truncated;
1158
1159NameTable.clear();
1160NameTable.reserve(*Size);
1161for (size_tI = 0;I < *Size; ++I) {
1162using namespacesupport;
1163uint64_t FID = endian::read<uint64_t, endianness::little, unaligned>(
1164Data +I *sizeof(uint64_t));
1165NameTable.emplace_back(FunctionId(FID));
1166 }
1167if (!ProfileIsCS)
1168MD5SampleContextStart =reinterpret_cast<constuint64_t *>(Data);
1169Data =Data + (*Size) *sizeof(uint64_t);
1170returnsampleprof_error::success;
1171 }
1172
1173if (IsMD5) {
1174assert(!FixedLengthMD5 &&"FixedLengthMD5 should be unreachable here");
1175autoSize = readNumber<size_t>();
1176if (std::error_code EC =Size.getError())
1177return EC;
1178
1179NameTable.clear();
1180NameTable.reserve(*Size);
1181if (!ProfileIsCS)
1182MD5SampleContextTable.resize(*Size);
1183for (size_tI = 0;I < *Size; ++I) {
1184auto FID = readNumber<uint64_t>();
1185if (std::error_code EC = FID.getError())
1186return EC;
1187if (!ProfileIsCS)
1188support::endian::write64le(&MD5SampleContextTable[I], *FID);
1189NameTable.emplace_back(FunctionId(*FID));
1190 }
1191if (!ProfileIsCS)
1192MD5SampleContextStart =MD5SampleContextTable.data();
1193returnsampleprof_error::success;
1194 }
1195
1196returnSampleProfileReaderBinary::readNameTable();
1197}
1198
1199// Read in the CS name table section, which basically contains a list of context
1200// vectors. Each element of a context vector, aka a frame, refers to the
1201// underlying raw function names that are stored in the name table, as well as
1202// a callsite identifier that only makes sense for non-leaf frames.
1203std::error_codeSampleProfileReaderExtBinaryBase::readCSNameTableSec() {
1204autoSize = readNumber<size_t>();
1205if (std::error_code EC =Size.getError())
1206return EC;
1207
1208CSNameTable.clear();
1209CSNameTable.reserve(*Size);
1210if (ProfileIsCS) {
1211// Delay MD5 computation of CS context until they are needed. Use 0 to
1212// indicate MD5 value is to be calculated as no known string has a MD5
1213// value of 0.
1214MD5SampleContextTable.clear();
1215MD5SampleContextTable.resize(*Size);
1216MD5SampleContextStart =MD5SampleContextTable.data();
1217 }
1218for (size_tI = 0;I < *Size; ++I) {
1219CSNameTable.emplace_back(SampleContextFrameVector());
1220auto ContextSize = readNumber<uint32_t>();
1221if (std::error_code EC = ContextSize.getError())
1222return EC;
1223for (uint32_t J = 0; J < *ContextSize; ++J) {
1224auto FName(readStringFromTable());
1225if (std::error_code EC = FName.getError())
1226return EC;
1227auto LineOffset = readNumber<uint64_t>();
1228if (std::error_code EC = LineOffset.getError())
1229return EC;
1230
1231if (!isOffsetLegal(*LineOffset))
1232return std::error_code();
1233
1234auto Discriminator = readNumber<uint64_t>();
1235if (std::error_code EC = Discriminator.getError())
1236return EC;
1237
1238CSNameTable.back().emplace_back(
1239 FName.get(),LineLocation(LineOffset.get(), Discriminator.get()));
1240 }
1241 }
1242
1243returnsampleprof_error::success;
1244}
1245
1246std::error_code
1247SampleProfileReaderExtBinaryBase::readFuncMetadata(bool ProfileHasAttribute,
1248FunctionSamples *FProfile) {
1249if (Data <End) {
1250if (ProfileIsProbeBased) {
1251auto Checksum = readNumber<uint64_t>();
1252if (std::error_code EC = Checksum.getError())
1253return EC;
1254if (FProfile)
1255 FProfile->setFunctionHash(*Checksum);
1256 }
1257
1258if (ProfileHasAttribute) {
1259autoAttributes = readNumber<uint32_t>();
1260if (std::error_code EC =Attributes.getError())
1261return EC;
1262if (FProfile)
1263 FProfile->getContext().setAllAttributes(*Attributes);
1264 }
1265
1266if (!ProfileIsCS) {
1267// Read all the attributes for inlined function calls.
1268auto NumCallsites = readNumber<uint32_t>();
1269if (std::error_code EC = NumCallsites.getError())
1270return EC;
1271
1272for (uint32_t J = 0; J < *NumCallsites; ++J) {
1273auto LineOffset = readNumber<uint64_t>();
1274if (std::error_code EC = LineOffset.getError())
1275return EC;
1276
1277auto Discriminator = readNumber<uint64_t>();
1278if (std::error_code EC = Discriminator.getError())
1279return EC;
1280
1281auto FContextHash(readSampleContextFromTable());
1282if (std::error_code EC = FContextHash.getError())
1283return EC;
1284
1285auto &[FContext, Hash] = *FContextHash;
1286FunctionSamples *CalleeProfile =nullptr;
1287if (FProfile) {
1288 CalleeProfile =const_cast<FunctionSamples *>(
1289 &FProfile->functionSamplesAt(LineLocation(
1290 *LineOffset,
1291 *Discriminator))[FContext.getFunction()]);
1292 }
1293if (std::error_code EC =
1294readFuncMetadata(ProfileHasAttribute, CalleeProfile))
1295return EC;
1296 }
1297 }
1298 }
1299
1300returnsampleprof_error::success;
1301}
1302
1303std::error_code
1304SampleProfileReaderExtBinaryBase::readFuncMetadata(bool ProfileHasAttribute,
1305SampleProfileMap &Profiles) {
1306if (FuncMetadataIndex.empty())
1307returnsampleprof_error::success;
1308
1309for (auto &I :Profiles) {
1310FunctionSamples *FProfile = &I.second;
1311auto R =FuncMetadataIndex.find(FProfile->getContext().getHashCode());
1312if (R ==FuncMetadataIndex.end())
1313continue;
1314
1315Data = R->second.first;
1316End = R->second.second;
1317if (std::error_code EC =readFuncMetadata(ProfileHasAttribute, FProfile))
1318return EC;
1319assert(Data ==End &&"More data is read than expected");
1320 }
1321returnsampleprof_error::success;
1322}
1323
1324std::error_code
1325SampleProfileReaderExtBinaryBase::readFuncMetadata(bool ProfileHasAttribute) {
1326while (Data <End) {
1327auto FContextHash(readSampleContextFromTable());
1328if (std::error_code EC = FContextHash.getError())
1329return EC;
1330auto &[FContext, Hash] = *FContextHash;
1331FunctionSamples *FProfile =nullptr;
1332auto It =Profiles.find(FContext);
1333if (It !=Profiles.end())
1334 FProfile = &It->second;
1335
1336constuint8_t *Start =Data;
1337if (std::error_code EC =readFuncMetadata(ProfileHasAttribute, FProfile))
1338return EC;
1339
1340FuncMetadataIndex[FContext.getHashCode()] = {Start,Data};
1341 }
1342
1343assert(Data ==End &&"More data is read than expected");
1344returnsampleprof_error::success;
1345}
1346
1347std::error_code
1348SampleProfileReaderExtBinaryBase::readSecHdrTableEntry(uint64_tIdx) {
1349SecHdrTableEntry Entry;
1350autoType = readUnencodedNumber<uint64_t>();
1351if (std::error_code EC =Type.getError())
1352return EC;
1353 Entry.Type =static_cast<SecType>(*Type);
1354
1355auto Flags = readUnencodedNumber<uint64_t>();
1356if (std::error_code EC = Flags.getError())
1357return EC;
1358 Entry.Flags = *Flags;
1359
1360autoOffset = readUnencodedNumber<uint64_t>();
1361if (std::error_code EC =Offset.getError())
1362return EC;
1363 Entry.Offset = *Offset;
1364
1365autoSize = readUnencodedNumber<uint64_t>();
1366if (std::error_code EC =Size.getError())
1367return EC;
1368 Entry.Size = *Size;
1369
1370 Entry.LayoutIndex =Idx;
1371SecHdrTable.push_back(std::move(Entry));
1372returnsampleprof_error::success;
1373}
1374
1375std::error_codeSampleProfileReaderExtBinaryBase::readSecHdrTable() {
1376auto EntryNum = readUnencodedNumber<uint64_t>();
1377if (std::error_code EC = EntryNum.getError())
1378return EC;
1379
1380for (uint64_t i = 0; i < (*EntryNum); i++)
1381if (std::error_code EC =readSecHdrTableEntry(i))
1382return EC;
1383
1384returnsampleprof_error::success;
1385}
1386
1387std::error_codeSampleProfileReaderExtBinaryBase::readHeader() {
1388constuint8_t *BufStart =
1389reinterpret_cast<constuint8_t *>(Buffer->getBufferStart());
1390Data = BufStart;
1391End = BufStart +Buffer->getBufferSize();
1392
1393if (std::error_code EC =readMagicIdent())
1394return EC;
1395
1396if (std::error_code EC =readSecHdrTable())
1397return EC;
1398
1399returnsampleprof_error::success;
1400}
1401
1402uint64_tSampleProfileReaderExtBinaryBase::getSectionSize(SecTypeType) {
1403uint64_tSize = 0;
1404for (auto &Entry :SecHdrTable) {
1405if (Entry.Type ==Type)
1406Size += Entry.Size;
1407 }
1408returnSize;
1409}
1410
1411uint64_tSampleProfileReaderExtBinaryBase::getFileSize() {
1412// Sections in SecHdrTable is not necessarily in the same order as
1413// sections in the profile because section like FuncOffsetTable needs
1414// to be written after section LBRProfile but needs to be read before
1415// section LBRProfile, so we cannot simply use the last entry in
1416// SecHdrTable to calculate the file size.
1417uint64_t FileSize = 0;
1418for (auto &Entry :SecHdrTable) {
1419 FileSize = std::max(Entry.Offset + Entry.Size, FileSize);
1420 }
1421return FileSize;
1422}
1423
1424static std::stringgetSecFlagsStr(constSecHdrTableEntry &Entry) {
1425 std::string Flags;
1426if (hasSecFlag(Entry,SecCommonFlags::SecFlagCompress))
1427 Flags.append("{compressed,");
1428else
1429 Flags.append("{");
1430
1431if (hasSecFlag(Entry,SecCommonFlags::SecFlagFlat))
1432 Flags.append("flat,");
1433
1434switch (Entry.Type) {
1435caseSecNameTable:
1436if (hasSecFlag(Entry,SecNameTableFlags::SecFlagFixedLengthMD5))
1437 Flags.append("fixlenmd5,");
1438elseif (hasSecFlag(Entry,SecNameTableFlags::SecFlagMD5Name))
1439 Flags.append("md5,");
1440if (hasSecFlag(Entry,SecNameTableFlags::SecFlagUniqSuffix))
1441 Flags.append("uniq,");
1442break;
1443caseSecProfSummary:
1444if (hasSecFlag(Entry,SecProfSummaryFlags::SecFlagPartial))
1445 Flags.append("partial,");
1446if (hasSecFlag(Entry,SecProfSummaryFlags::SecFlagFullContext))
1447 Flags.append("context,");
1448if (hasSecFlag(Entry,SecProfSummaryFlags::SecFlagIsPreInlined))
1449 Flags.append("preInlined,");
1450if (hasSecFlag(Entry,SecProfSummaryFlags::SecFlagFSDiscriminator))
1451 Flags.append("fs-discriminator,");
1452break;
1453caseSecFuncOffsetTable:
1454if (hasSecFlag(Entry,SecFuncOffsetFlags::SecFlagOrdered))
1455 Flags.append("ordered,");
1456break;
1457caseSecFuncMetadata:
1458if (hasSecFlag(Entry,SecFuncMetadataFlags::SecFlagIsProbeBased))
1459 Flags.append("probe,");
1460if (hasSecFlag(Entry,SecFuncMetadataFlags::SecFlagHasAttribute))
1461 Flags.append("attr,");
1462break;
1463default:
1464break;
1465 }
1466char &last = Flags.back();
1467if (last ==',')
1468 last ='}';
1469else
1470 Flags.append("}");
1471return Flags;
1472}
1473
1474boolSampleProfileReaderExtBinaryBase::dumpSectionInfo(raw_ostream &OS) {
1475uint64_t TotalSecsSize = 0;
1476for (auto &Entry :SecHdrTable) {
1477OS <<getSecName(Entry.Type) <<" - Offset: " << Entry.Offset
1478 <<", Size: " << Entry.Size <<", Flags: " <<getSecFlagsStr(Entry)
1479 <<"\n";
1480 ;
1481 TotalSecsSize += Entry.Size;
1482 }
1483uint64_t HeaderSize =SecHdrTable.front().Offset;
1484assert(HeaderSize + TotalSecsSize ==getFileSize() &&
1485"Size of 'header + sections' doesn't match the total size of profile");
1486
1487OS <<"Header Size: " << HeaderSize <<"\n";
1488OS <<"Total Sections Size: " << TotalSecsSize <<"\n";
1489OS <<"File Size: " <<getFileSize() <<"\n";
1490returntrue;
1491}
1492
1493std::error_codeSampleProfileReaderBinary::readMagicIdent() {
1494// Read and check the magic identifier.
1495auto Magic = readNumber<uint64_t>();
1496if (std::error_code EC = Magic.getError())
1497return EC;
1498elseif (std::error_code EC = verifySPMagic(*Magic))
1499return EC;
1500
1501// Read the version number.
1502autoVersion = readNumber<uint64_t>();
1503if (std::error_code EC =Version.getError())
1504return EC;
1505elseif (*Version !=SPVersion())
1506returnsampleprof_error::unsupported_version;
1507
1508returnsampleprof_error::success;
1509}
1510
1511std::error_codeSampleProfileReaderBinary::readHeader() {
1512Data =reinterpret_cast<constuint8_t *>(Buffer->getBufferStart());
1513End =Data +Buffer->getBufferSize();
1514
1515if (std::error_code EC =readMagicIdent())
1516return EC;
1517
1518if (std::error_code EC =readSummary())
1519return EC;
1520
1521if (std::error_code EC =readNameTable())
1522return EC;
1523returnsampleprof_error::success;
1524}
1525
1526std::error_code SampleProfileReaderBinary::readSummaryEntry(
1527 std::vector<ProfileSummaryEntry> &Entries) {
1528auto Cutoff = readNumber<uint64_t>();
1529if (std::error_code EC = Cutoff.getError())
1530return EC;
1531
1532auto MinBlockCount = readNumber<uint64_t>();
1533if (std::error_code EC = MinBlockCount.getError())
1534return EC;
1535
1536auto NumBlocks = readNumber<uint64_t>();
1537if (std::error_code EC = NumBlocks.getError())
1538return EC;
1539
1540 Entries.emplace_back(*Cutoff, *MinBlockCount, *NumBlocks);
1541returnsampleprof_error::success;
1542}
1543
1544std::error_codeSampleProfileReaderBinary::readSummary() {
1545auto TotalCount = readNumber<uint64_t>();
1546if (std::error_code EC = TotalCount.getError())
1547return EC;
1548
1549auto MaxBlockCount = readNumber<uint64_t>();
1550if (std::error_code EC = MaxBlockCount.getError())
1551return EC;
1552
1553auto MaxFunctionCount = readNumber<uint64_t>();
1554if (std::error_code EC = MaxFunctionCount.getError())
1555return EC;
1556
1557auto NumBlocks = readNumber<uint64_t>();
1558if (std::error_code EC = NumBlocks.getError())
1559return EC;
1560
1561auto NumFunctions = readNumber<uint64_t>();
1562if (std::error_code EC = NumFunctions.getError())
1563return EC;
1564
1565auto NumSummaryEntries = readNumber<uint64_t>();
1566if (std::error_code EC = NumSummaryEntries.getError())
1567return EC;
1568
1569 std::vector<ProfileSummaryEntry> Entries;
1570for (unsigned i = 0; i < *NumSummaryEntries; i++) {
1571 std::error_code EC = readSummaryEntry(Entries);
1572if (EC !=sampleprof_error::success)
1573return EC;
1574 }
1575Summary = std::make_unique<ProfileSummary>(
1576ProfileSummary::PSK_Sample, Entries, *TotalCount, *MaxBlockCount, 0,
1577 *MaxFunctionCount, *NumBlocks, *NumFunctions);
1578
1579returnsampleprof_error::success;
1580}
1581
1582boolSampleProfileReaderRawBinary::hasFormat(constMemoryBuffer &Buffer) {
1583constuint8_t *Data =
1584reinterpret_cast<constuint8_t *>(Buffer.getBufferStart());
1585uint64_t Magic =decodeULEB128(Data);
1586return Magic ==SPMagic();
1587}
1588
1589boolSampleProfileReaderExtBinary::hasFormat(constMemoryBuffer &Buffer) {
1590constuint8_t *Data =
1591reinterpret_cast<constuint8_t *>(Buffer.getBufferStart());
1592uint64_t Magic =decodeULEB128(Data);
1593return Magic ==SPMagic(SPF_Ext_Binary);
1594}
1595
1596std::error_codeSampleProfileReaderGCC::skipNextWord() {
1597uint32_t dummy;
1598if (!GcovBuffer.readInt(dummy))
1599returnsampleprof_error::truncated;
1600returnsampleprof_error::success;
1601}
1602
1603template <typename T>ErrorOr<T>SampleProfileReaderGCC::readNumber() {
1604if (sizeof(T) <=sizeof(uint32_t)) {
1605uint32_t Val;
1606if (GcovBuffer.readInt(Val) && Val <= std::numeric_limits<T>::max())
1607returnstatic_cast<T>(Val);
1608 }elseif (sizeof(T) <=sizeof(uint64_t)) {
1609uint64_t Val;
1610if (GcovBuffer.readInt64(Val) && Val <= std::numeric_limits<T>::max())
1611returnstatic_cast<T>(Val);
1612 }
1613
1614 std::error_code EC =sampleprof_error::malformed;
1615reportError(0, EC.message());
1616return EC;
1617}
1618
1619ErrorOr<StringRef>SampleProfileReaderGCC::readString() {
1620StringRef Str;
1621if (!GcovBuffer.readString(Str))
1622returnsampleprof_error::truncated;
1623return Str;
1624}
1625
1626std::error_codeSampleProfileReaderGCC::readHeader() {
1627// Read the magic identifier.
1628if (!GcovBuffer.readGCDAFormat())
1629returnsampleprof_error::unrecognized_format;
1630
1631// Read the version number. Note - the GCC reader does not validate this
1632// version, but the profile creator generates v704.
1633GCOV::GCOVVersion version;
1634if (!GcovBuffer.readGCOVVersion(version))
1635returnsampleprof_error::unrecognized_format;
1636
1637if (version !=GCOV::V407)
1638returnsampleprof_error::unsupported_version;
1639
1640// Skip the empty integer.
1641if (std::error_code EC =skipNextWord())
1642return EC;
1643
1644returnsampleprof_error::success;
1645}
1646
1647std::error_codeSampleProfileReaderGCC::readSectionTag(uint32_tExpected) {
1648uint32_tTag;
1649if (!GcovBuffer.readInt(Tag))
1650returnsampleprof_error::truncated;
1651
1652if (Tag !=Expected)
1653returnsampleprof_error::malformed;
1654
1655if (std::error_code EC =skipNextWord())
1656return EC;
1657
1658returnsampleprof_error::success;
1659}
1660
1661std::error_codeSampleProfileReaderGCC::readNameTable() {
1662if (std::error_code EC =readSectionTag(GCOVTagAFDOFileNames))
1663return EC;
1664
1665uint32_tSize;
1666if (!GcovBuffer.readInt(Size))
1667returnsampleprof_error::truncated;
1668
1669for (uint32_tI = 0;I <Size; ++I) {
1670StringRef Str;
1671if (!GcovBuffer.readString(Str))
1672returnsampleprof_error::truncated;
1673Names.push_back(std::string(Str));
1674 }
1675
1676returnsampleprof_error::success;
1677}
1678
1679std::error_codeSampleProfileReaderGCC::readFunctionProfiles() {
1680if (std::error_code EC =readSectionTag(GCOVTagAFDOFunction))
1681return EC;
1682
1683uint32_t NumFunctions;
1684if (!GcovBuffer.readInt(NumFunctions))
1685returnsampleprof_error::truncated;
1686
1687InlineCallStack Stack;
1688for (uint32_tI = 0;I < NumFunctions; ++I)
1689if (std::error_code EC =readOneFunctionProfile(Stack,true, 0))
1690return EC;
1691
1692computeSummary();
1693returnsampleprof_error::success;
1694}
1695
1696std::error_codeSampleProfileReaderGCC::readOneFunctionProfile(
1697constInlineCallStack &InlineStack,bool Update,uint32_tOffset) {
1698uint64_t HeadCount = 0;
1699if (InlineStack.size() == 0)
1700if (!GcovBuffer.readInt64(HeadCount))
1701returnsampleprof_error::truncated;
1702
1703uint32_t NameIdx;
1704if (!GcovBuffer.readInt(NameIdx))
1705returnsampleprof_error::truncated;
1706
1707StringRefName(Names[NameIdx]);
1708
1709uint32_t NumPosCounts;
1710if (!GcovBuffer.readInt(NumPosCounts))
1711returnsampleprof_error::truncated;
1712
1713uint32_t NumCallsites;
1714if (!GcovBuffer.readInt(NumCallsites))
1715returnsampleprof_error::truncated;
1716
1717FunctionSamples *FProfile =nullptr;
1718if (InlineStack.size() == 0) {
1719// If this is a top function that we have already processed, do not
1720// update its profile again. This happens in the presence of
1721// function aliases. Since these aliases share the same function
1722// body, there will be identical replicated profiles for the
1723// original function. In this case, we simply not bother updating
1724// the profile of the original function.
1725 FProfile = &Profiles[FunctionId(Name)];
1726 FProfile->addHeadSamples(HeadCount);
1727if (FProfile->getTotalSamples() > 0)
1728 Update =false;
1729 }else {
1730// Otherwise, we are reading an inlined instance. The top of the
1731// inline stack contains the profile of the caller. Insert this
1732// callee in the caller's CallsiteMap.
1733FunctionSamples *CallerProfile = InlineStack.front();
1734uint32_t LineOffset =Offset >> 16;
1735uint32_t Discriminator =Offset & 0xffff;
1736 FProfile = &CallerProfile->functionSamplesAt(
1737LineLocation(LineOffset, Discriminator))[FunctionId(Name)];
1738 }
1739 FProfile->setFunction(FunctionId(Name));
1740
1741for (uint32_tI = 0;I < NumPosCounts; ++I) {
1742uint32_tOffset;
1743if (!GcovBuffer.readInt(Offset))
1744returnsampleprof_error::truncated;
1745
1746uint32_t NumTargets;
1747if (!GcovBuffer.readInt(NumTargets))
1748returnsampleprof_error::truncated;
1749
1750uint64_t Count;
1751if (!GcovBuffer.readInt64(Count))
1752returnsampleprof_error::truncated;
1753
1754// The line location is encoded in the offset as:
1755// high 16 bits: line offset to the start of the function.
1756// low 16 bits: discriminator.
1757uint32_t LineOffset =Offset >> 16;
1758uint32_t Discriminator =Offset & 0xffff;
1759
1760InlineCallStack NewStack;
1761 NewStack.push_back(FProfile);
1762llvm::append_range(NewStack, InlineStack);
1763if (Update) {
1764// Walk up the inline stack, adding the samples on this line to
1765// the total sample count of the callers in the chain.
1766for (auto *CallerProfile : NewStack)
1767 CallerProfile->addTotalSamples(Count);
1768
1769// Update the body samples for the current profile.
1770 FProfile->addBodySamples(LineOffset, Discriminator, Count);
1771 }
1772
1773// Process the list of functions called at an indirect call site.
1774// These are all the targets that a function pointer (or virtual
1775// function) resolved at runtime.
1776for (uint32_t J = 0; J < NumTargets; J++) {
1777uint32_t HistVal;
1778if (!GcovBuffer.readInt(HistVal))
1779returnsampleprof_error::truncated;
1780
1781if (HistVal !=HIST_TYPE_INDIR_CALL_TOPN)
1782returnsampleprof_error::malformed;
1783
1784uint64_t TargetIdx;
1785if (!GcovBuffer.readInt64(TargetIdx))
1786returnsampleprof_error::truncated;
1787StringRef TargetName(Names[TargetIdx]);
1788
1789uint64_t TargetCount;
1790if (!GcovBuffer.readInt64(TargetCount))
1791returnsampleprof_error::truncated;
1792
1793if (Update)
1794 FProfile->addCalledTargetSamples(LineOffset, Discriminator,
1795FunctionId(TargetName),
1796 TargetCount);
1797 }
1798 }
1799
1800// Process all the inlined callers into the current function. These
1801// are all the callsites that were inlined into this function.
1802for (uint32_tI = 0;I < NumCallsites;I++) {
1803// The offset is encoded as:
1804// high 16 bits: line offset to the start of the function.
1805// low 16 bits: discriminator.
1806uint32_tOffset;
1807if (!GcovBuffer.readInt(Offset))
1808returnsampleprof_error::truncated;
1809InlineCallStack NewStack;
1810 NewStack.push_back(FProfile);
1811llvm::append_range(NewStack, InlineStack);
1812if (std::error_code EC =readOneFunctionProfile(NewStack, Update,Offset))
1813return EC;
1814 }
1815
1816returnsampleprof_error::success;
1817}
1818
1819/// Read a GCC AutoFDO profile.
1820///
1821/// This format is generated by the Linux Perf conversion tool at
1822/// https://github.com/google/autofdo.
1823std::error_codeSampleProfileReaderGCC::readImpl() {
1824assert(!ProfileIsFSDisciminator &&"Gcc profiles not support FSDisciminator");
1825// Read the string table.
1826if (std::error_code EC =readNameTable())
1827return EC;
1828
1829// Read the source profile.
1830if (std::error_code EC =readFunctionProfiles())
1831return EC;
1832
1833returnsampleprof_error::success;
1834}
1835
1836boolSampleProfileReaderGCC::hasFormat(constMemoryBuffer &Buffer) {
1837StringRef Magic(reinterpret_cast<constchar *>(Buffer.getBufferStart()));
1838return Magic =="adcg*704";
1839}
1840
1841voidSampleProfileReaderItaniumRemapper::applyRemapping(LLVMContext &Ctx) {
1842// If the reader uses MD5 to represent string, we can't remap it because
1843// we don't know what the original function names were.
1844if (Reader.useMD5()) {
1845 Ctx.diagnose(DiagnosticInfoSampleProfile(
1846 Reader.getBuffer()->getBufferIdentifier(),
1847"Profile data remapping cannot be applied to profile data "
1848"using MD5 names (original mangled names are not available).",
1849DS_Warning));
1850return;
1851 }
1852
1853// CSSPGO-TODO: Remapper is not yet supported.
1854// We will need to remap the entire context string.
1855assert(Remappings &&"should be initialized while creating remapper");
1856for (auto &Sample : Reader.getProfiles()) {
1857DenseSet<FunctionId> NamesInSample;
1858 Sample.second.findAllNames(NamesInSample);
1859for (auto &Name : NamesInSample) {
1860StringRef NameStr =Name.stringRef();
1861if (auto Key = Remappings->insert(NameStr))
1862 NameMap.insert({Key, NameStr});
1863 }
1864 }
1865
1866 RemappingApplied =true;
1867}
1868
1869std::optional<StringRef>
1870SampleProfileReaderItaniumRemapper::lookUpNameInProfile(StringRef Fname) {
1871if (auto Key = Remappings->lookup(Fname)) {
1872StringRef Result = NameMap.lookup(Key);
1873if (!Result.empty())
1874return Result;
1875 }
1876return std::nullopt;
1877}
1878
1879/// Prepare a memory buffer for the contents of \p Filename.
1880///
1881/// \returns an error code indicating the status of the buffer.
1882staticErrorOr<std::unique_ptr<MemoryBuffer>>
1883setupMemoryBuffer(constTwine &Filename,vfs::FileSystem &FS) {
1884auto BufferOrErr = Filename.str() =="-" ?MemoryBuffer::getSTDIN()
1885 : FS.getBufferForFile(Filename);
1886if (std::error_code EC = BufferOrErr.getError())
1887return EC;
1888auto Buffer = std::move(BufferOrErr.get());
1889
1890return std::move(Buffer);
1891}
1892
1893/// Create a sample profile reader based on the format of the input file.
1894///
1895/// \param Filename The file to open.
1896///
1897/// \param C The LLVM context to use to emit diagnostics.
1898///
1899/// \param P The FSDiscriminatorPass.
1900///
1901/// \param RemapFilename The file used for profile remapping.
1902///
1903/// \returns an error code indicating the status of the created reader.
1904ErrorOr<std::unique_ptr<SampleProfileReader>>
1905SampleProfileReader::create(StringRef Filename,LLVMContext &C,
1906vfs::FileSystem &FS,FSDiscriminatorPassP,
1907StringRef RemapFilename) {
1908auto BufferOrError =setupMemoryBuffer(Filename, FS);
1909if (std::error_code EC = BufferOrError.getError())
1910return EC;
1911returncreate(BufferOrError.get(),C, FS,P, RemapFilename);
1912}
1913
1914/// Create a sample profile remapper from the given input, to remap the
1915/// function names in the given profile data.
1916///
1917/// \param Filename The file to open.
1918///
1919/// \param Reader The profile reader the remapper is going to be applied to.
1920///
1921/// \param C The LLVM context to use to emit diagnostics.
1922///
1923/// \returns an error code indicating the status of the created reader.
1924ErrorOr<std::unique_ptr<SampleProfileReaderItaniumRemapper>>
1925SampleProfileReaderItaniumRemapper::create(StringRef Filename,
1926vfs::FileSystem &FS,
1927SampleProfileReader &Reader,
1928LLVMContext &C) {
1929auto BufferOrError =setupMemoryBuffer(Filename, FS);
1930if (std::error_code EC = BufferOrError.getError())
1931return EC;
1932returncreate(BufferOrError.get(), Reader,C);
1933}
1934
1935/// Create a sample profile remapper from the given input, to remap the
1936/// function names in the given profile data.
1937///
1938/// \param B The memory buffer to create the reader from (assumes ownership).
1939///
1940/// \param C The LLVM context to use to emit diagnostics.
1941///
1942/// \param Reader The profile reader the remapper is going to be applied to.
1943///
1944/// \returns an error code indicating the status of the created reader.
1945ErrorOr<std::unique_ptr<SampleProfileReaderItaniumRemapper>>
1946SampleProfileReaderItaniumRemapper::create(std::unique_ptr<MemoryBuffer> &B,
1947SampleProfileReader &Reader,
1948LLVMContext &C) {
1949auto Remappings = std::make_unique<SymbolRemappingReader>();
1950if (Error E = Remappings->read(*B)) {
1951handleAllErrors(
1952 std::move(E), [&](constSymbolRemappingParseError &ParseError) {
1953C.diagnose(DiagnosticInfoSampleProfile(B->getBufferIdentifier(),
1954 ParseError.getLineNum(),
1955 ParseError.getMessage()));
1956 });
1957returnsampleprof_error::malformed;
1958 }
1959
1960return std::make_unique<SampleProfileReaderItaniumRemapper>(
1961 std::move(B), std::move(Remappings), Reader);
1962}
1963
1964/// Create a sample profile reader based on the format of the input data.
1965///
1966/// \param B The memory buffer to create the reader from (assumes ownership).
1967///
1968/// \param C The LLVM context to use to emit diagnostics.
1969///
1970/// \param P The FSDiscriminatorPass.
1971///
1972/// \param RemapFilename The file used for profile remapping.
1973///
1974/// \returns an error code indicating the status of the created reader.
1975ErrorOr<std::unique_ptr<SampleProfileReader>>
1976SampleProfileReader::create(std::unique_ptr<MemoryBuffer> &B,LLVMContext &C,
1977vfs::FileSystem &FS,FSDiscriminatorPassP,
1978StringRef RemapFilename) {
1979 std::unique_ptr<SampleProfileReader> Reader;
1980if (SampleProfileReaderRawBinary::hasFormat(*B))
1981 Reader.reset(newSampleProfileReaderRawBinary(std::move(B),C));
1982elseif (SampleProfileReaderExtBinary::hasFormat(*B))
1983 Reader.reset(newSampleProfileReaderExtBinary(std::move(B),C));
1984elseif (SampleProfileReaderGCC::hasFormat(*B))
1985 Reader.reset(newSampleProfileReaderGCC(std::move(B),C));
1986elseif (SampleProfileReaderText::hasFormat(*B))
1987 Reader.reset(newSampleProfileReaderText(std::move(B),C));
1988else
1989returnsampleprof_error::unrecognized_format;
1990
1991if (!RemapFilename.empty()) {
1992auto ReaderOrErr =SampleProfileReaderItaniumRemapper::create(
1993 RemapFilename, FS, *Reader,C);
1994if (std::error_code EC = ReaderOrErr.getError()) {
1995 std::string Msg ="Could not create remapper: " + EC.message();
1996C.diagnose(DiagnosticInfoSampleProfile(RemapFilename, Msg));
1997return EC;
1998 }
1999 Reader->Remapper = std::move(ReaderOrErr.get());
2000 }
2001
2002if (std::error_code EC = Reader->readHeader()) {
2003return EC;
2004 }
2005
2006 Reader->setDiscriminatorMaskedBitFrom(P);
2007
2008return std::move(Reader);
2009}
2010
2011// For text and GCC file formats, we compute the summary after reading the
2012// profile. Binary format has the profile summary in its header.
2013voidSampleProfileReader::computeSummary() {
2014SampleProfileSummaryBuilder Builder(ProfileSummaryBuilder::DefaultCutoffs);
2015Summary = Builder.computeSummaryForProfiles(Profiles);
2016}
Attributes
AMDGPU Kernel Attributes
Definition:AMDGPULowerKernelAttributes.cpp:370
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
CommandLine.h
Compression.h
Idx
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Definition:DeadArgumentElimination.cpp:353
DenseMap.h
This file defines the DenseMap class.
Name
std::string Name
Definition:ELFObjHandler.cpp:77
Size
uint64_t Size
Definition:ELFObjHandler.cpp:81
ErrorOr.h
Provides ErrorOr<T> smart pointer.
Module.h
Module.h This file contains the declarations for the Module class.
JSON.h
This file supports working with JSON data.
LEB128.h
LineIterator.h
F
#define F(x, y, z)
Definition:MD5.cpp:55
I
#define I(x, y, z)
Definition:MD5.cpp:58
MD5.h
MemoryBuffer.h
P
#define P(N)
ProfileCommon.h
ProfileSummary.h
isDigit
static bool isDigit(const char C)
Definition:RustDemangle.cpp:170
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
STLExtras.h
This file contains some templates that are useful if you are working with the STL at all.
ParseHead
static bool ParseHead(const StringRef &Input, StringRef &FName, uint64_t &NumSamples, uint64_t &NumHeadSamples)
Parse Input as function head.
Definition:SampleProfReader.cpp:157
dumpFunctionProfileJson
static void dumpFunctionProfileJson(const FunctionSamples &S, json::OStream &JOS, bool TopLevel=false)
Definition:SampleProfReader.cpp:77
isOffsetLegal
static bool isOffsetLegal(unsigned L)
Returns true if line offset L is legal (only has 16 bits).
Definition:SampleProfReader.cpp:172
ParseLine
static bool ParseLine(const StringRef &Input, LineType &LineTy, uint32_t &Depth, uint64_t &NumSamples, uint32_t &LineOffset, uint32_t &Discriminator, StringRef &CalleeName, DenseMap< StringRef, uint64_t > &TargetCountMap, uint64_t &FunctionHash, uint32_t &Attributes, bool &IsFlat)
Parse Input as line sample.
Definition:SampleProfReader.cpp:214
ProfileIsFSDisciminator
static cl::opt< bool > ProfileIsFSDisciminator("profile-isfs", cl::Hidden, cl::init(false), cl::desc("Profile uses flow sensitive discriminators"))
getSecFlagsStr
static std::string getSecFlagsStr(const SecHdrTableEntry &Entry)
Definition:SampleProfReader.cpp:1424
parseMetadata
static bool parseMetadata(const StringRef &Input, uint64_t &FunctionHash, uint32_t &Attributes)
Parse Input that contains metadata.
Definition:SampleProfReader.cpp:181
LineType
LineType
Definition:SampleProfReader.cpp:196
LineType::CallSiteProfile
@ CallSiteProfile
LineType::BodyProfile
@ BodyProfile
SampleProfReader.h
OS
raw_pwrite_stream & OS
Definition:SampleProfWriter.cpp:51
SampleProf.h
StringRef.h
VirtualFileSystem.h
Defines the virtual file system interface vfs::FileSystem.
T
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition:ArrayRef.h:41
llvm::BumpPtrAllocatorImpl::Allocate
LLVM_ATTRIBUTE_RETURNS_NONNULL void * Allocate(size_t Size, Align Alignment)
Allocate space at the specified alignment.
Definition:Allocator.h:148
llvm::DenseMap
Definition:DenseMap.h:727
llvm::DenseSet
Implements a dense probed hash-table based set.
Definition:DenseSet.h:278
llvm::DiagnosticInfoSampleProfile
Diagnostic information for the sample profiler.
Definition:DiagnosticInfo.h:257
llvm::ErrorOr
Represents either an error or a value T.
Definition:ErrorOr.h:56
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition:Error.h:160
llvm::Expected
Tagged union holding either a T or a Error.
Definition:Error.h:481
llvm::GCOVBuffer::readInt
bool readInt(uint32_t &Val)
Definition:GCOV.h:152
llvm::GCOVBuffer::readInt64
bool readInt64(uint64_t &Val)
Definition:GCOV.h:162
llvm::GCOVBuffer::readGCOVVersion
bool readGCOVVersion(GCOV::GCOVVersion &version)
readGCOVVersion - Read GCOV version.
Definition:GCOV.h:108
llvm::GCOVBuffer::readString
bool readString(StringRef &str)
Definition:GCOV.h:170
llvm::GCOVBuffer::readGCDAFormat
bool readGCDAFormat()
readGCDAFormat - Check GCDA signature is valid at the beginning of buffer.
Definition:GCOV.h:94
llvm::GlobalValue::getGUID
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
Definition:GlobalValue.h:596
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition:LLVMContext.h:67
llvm::LLVMContext::diagnose
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
Definition:LLVMContext.cpp:245
llvm::MemoryBuffer
This interface provides simple read-only access to a block of memory, and provides simple methods for...
Definition:MemoryBuffer.h:51
llvm::MemoryBuffer::getBufferIdentifier
virtual StringRef getBufferIdentifier() const
Return an identifier for this buffer, typically the filename it was read from.
Definition:MemoryBuffer.h:76
llvm::MemoryBuffer::getSTDIN
static ErrorOr< std::unique_ptr< MemoryBuffer > > getSTDIN()
Read all of stdin into a file buffer, and return it.
Definition:MemoryBuffer.cpp:566
llvm::Metadata
Root of the metadata hierarchy.
Definition:Metadata.h:62
llvm::ProfileSummaryBuilder::DefaultCutoffs
static const ArrayRef< uint32_t > DefaultCutoffs
A vector of useful cutoff values for detailed summary.
Definition:ProfileCommon.h:70
llvm::ProfileSummary::PSK_Sample
@ PSK_Sample
Definition:ProfileSummary.h:47
llvm::SampleProfileSummaryBuilder
Definition:ProfileCommon.h:93
llvm::SampleProfileSummaryBuilder::computeSummaryForProfiles
std::unique_ptr< ProfileSummary > computeSummaryForProfiles(const sampleprof::SampleProfileMap &Profiles)
Definition:ProfileSummaryBuilder.cpp:193
llvm::SmallVectorBase::size
size_t size() const
Definition:SmallVector.h:78
llvm::SmallVectorImpl::clear
void clear()
Definition:SmallVector.h:610
llvm::SmallVectorTemplateBase::pop_back
void pop_back()
Definition:SmallVector.h:425
llvm::SmallVectorTemplateBase::push_back
void push_back(const T &Elt)
Definition:SmallVector.h:413
llvm::SmallVectorTemplateCommon::front
reference front()
Definition:SmallVector.h:299
llvm::SmallVectorTemplateCommon::back
reference back()
Definition:SmallVector.h:308
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition:SmallVector.h:1196
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition:StringRef.h:51
llvm::StringRef::getAsInteger
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition:StringRef.h:470
llvm::StringRef::substr
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition:StringRef.h:571
llvm::StringRef::starts_with
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition:StringRef.h:265
llvm::StringRef::empty
constexpr bool empty() const
empty - Check if the string is empty.
Definition:StringRef.h:147
llvm::StringRef::size
constexpr size_t size() const
size - Get the string size.
Definition:StringRef.h:150
llvm::StringRef::find_last_of
size_t find_last_of(char C, size_t From=npos) const
Find the last character in the string that is C, or npos if not found.
Definition:StringRef.h:400
llvm::StringRef::find_first_of
size_t find_first_of(char C, size_t From=0) const
Find the first character in the string that is C, or npos if not found.
Definition:StringRef.h:377
llvm::StringRef::rfind
size_t rfind(char C, size_t From=npos) const
Search for the last character C in the string.
Definition:StringRef.h:347
llvm::StringRef::find
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition:StringRef.h:297
llvm::StringRef::trim
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
Definition:StringRef.h:815
llvm::StringRef::npos
static constexpr size_t npos
Definition:StringRef.h:53
llvm::StringRef::find_first_not_of
size_t find_first_not_of(char C, size_t From=0) const
Find the first character in the string that is not C or npos if not found.
Definition:StringRef.cpp:253
llvm::SymbolRemappingParseError
Definition:SymbolRemappingReader.h:70
llvm::SymbolRemappingParseError::getLineNum
int64_t getLineNum() const
Definition:SymbolRemappingReader.h:83
llvm::SymbolRemappingParseError::getMessage
StringRef getMessage() const
Definition:SymbolRemappingReader.h:84
llvm::Target
Target - Wrapper for Target specific information.
Definition:TargetRegistry.h:144
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition:Twine.h:81
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition:Type.h:45
llvm::cl::opt
Definition:CommandLine.h:1423
llvm::detail::DenseSetImpl::insert
std::pair< iterator, bool > insert(const ValueT &V)
Definition:DenseSet.h:213
llvm::detail::DenseSetImpl::count
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
Definition:DenseSet.h:95
llvm::json::OStream
json::OStream allows writing well-formed JSON without materializing all structures as json::Value ahe...
Definition:JSON.h:979
llvm::json::OStream::object
void object(Block Contents)
Emit an object whose elements are emitted in the provided Block.
Definition:JSON.h:1009
llvm::json::OStream::attribute
void attribute(llvm::StringRef Key, const Value &Contents)
Emit an attribute whose value is self-contained (number, vector<int> etc).
Definition:JSON.h:1034
llvm::json::OStream::arrayBegin
void arrayBegin()
Definition:JSON.cpp:840
llvm::json::OStream::attributeArray
void attributeArray(llvm::StringRef Key, Block Contents)
Emit an attribute whose value is an array with elements from the Block.
Definition:JSON.h:1038
llvm::json::OStream::arrayEnd
void arrayEnd()
Definition:JSON.cpp:848
llvm::line_iterator
A forward iterator which reads text lines from a buffer.
Definition:LineIterator.h:33
llvm::line_iterator::line_number
int64_t line_number() const
Return the current line number. May return any number at EOF.
Definition:LineIterator.h:66
llvm::line_iterator::is_at_eof
bool is_at_eof() const
Return true if we've reached EOF or are an "end" iterator.
Definition:LineIterator.h:60
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition:raw_ostream.h:52
llvm::sampleprof::FunctionId
This class represents a function that is read from a sample profile.
Definition:FunctionId.h:36
llvm::sampleprof::FunctionId::stringRef
StringRef stringRef() const
Convert to StringRef.
Definition:FunctionId.h:108
llvm::sampleprof::FunctionId::getHashCode
uint64_t getHashCode() const
Get hash code of this object.
Definition:FunctionId.h:123
llvm::sampleprof::FunctionId::str
std::string str() const
Convert to a string, usually for output purpose.
Definition:FunctionId.h:97
llvm::sampleprof::FunctionSamples
Representation of the samples collected for a function.
Definition:SampleProf.h:745
llvm::sampleprof::FunctionSamples::ProfileIsPreInlined
static bool ProfileIsPreInlined
Definition:SampleProf.h:1190
llvm::sampleprof::FunctionSamples::addTotalSamples
sampleprof_error addTotalSamples(uint64_t Num, uint64_t Weight=1)
Definition:SampleProf.h:752
llvm::sampleprof::FunctionSamples::getHeadSamples
uint64_t getHeadSamples() const
For top-level functions, return the total number of branch samples that have the function as the bran...
Definition:SampleProf.h:942
llvm::sampleprof::FunctionSamples::setFunction
void setFunction(FunctionId NewFunctionID)
Set the name of the function.
Definition:SampleProf.h:1069
llvm::sampleprof::FunctionSamples::ProfileIsCS
static bool ProfileIsCS
Definition:SampleProf.h:1188
llvm::sampleprof::FunctionSamples::getFunction
FunctionId getFunction() const
Return the function name.
Definition:SampleProf.h:1074
llvm::sampleprof::FunctionSamples::addHeadSamples
sampleprof_error addHeadSamples(uint64_t Num, uint64_t Weight=1)
Definition:SampleProf.h:771
llvm::sampleprof::FunctionSamples::addCalledTargetSamples
sampleprof_error addCalledTargetSamples(uint32_t LineOffset, uint32_t Discriminator, FunctionId Func, uint64_t Num, uint64_t Weight=1)
Definition:SampleProf.h:785
llvm::sampleprof::FunctionSamples::functionSamplesAt
FunctionSamplesMap & functionSamplesAt(const LineLocation &Loc)
Return the function samples at the given callsite location.
Definition:SampleProf.h:906
llvm::sampleprof::FunctionSamples::ProfileIsProbeBased
static bool ProfileIsProbeBased
Definition:SampleProf.h:1186
llvm::sampleprof::FunctionSamples::getCanonicalFnName
static StringRef getCanonicalFnName(const Function &F)
Return the canonical name for a function, taking into account suffix elision policy attributes.
Definition:SampleProf.h:1090
llvm::sampleprof::FunctionSamples::addBodySamples
sampleprof_error addBodySamples(uint32_t LineOffset, uint32_t Discriminator, uint64_t Num, uint64_t Weight=1)
Definition:SampleProf.h:779
llvm::sampleprof::FunctionSamples::setFunctionHash
void setFunctionHash(uint64_t Hash)
Definition:SampleProf.h:1079
llvm::sampleprof::FunctionSamples::ProfileIsFS
static bool ProfileIsFS
If this profile uses flow sensitive discriminators.
Definition:SampleProf.h:1203
llvm::sampleprof::FunctionSamples::getContext
SampleContext & getContext() const
Definition:SampleProf.h:1192
llvm::sampleprof::FunctionSamples::HasUniqSuffix
static bool HasUniqSuffix
Whether the profile contains any ".__uniq." suffix in a name.
Definition:SampleProf.h:1200
llvm::sampleprof::FunctionSamples::getTotalSamples
uint64_t getTotalSamples() const
Return the total number of samples collected inside the function.
Definition:SampleProf.h:934
llvm::sampleprof::FunctionSamples::getCallsiteSamples
const CallsiteSampleMap & getCallsiteSamples() const
Return all the callsite samples collected in the body of the function.
Definition:SampleProf.h:976
llvm::sampleprof::FunctionSamples::setContext
void setContext(const SampleContext &FContext)
Definition:SampleProf.h:1194
llvm::sampleprof::FunctionSamples::getBodySamples
const BodySampleMap & getBodySamples() const
Return all the samples collected in the body of the function.
Definition:SampleProf.h:973
llvm::sampleprof::HashKeyMap::try_emplace
std::pair< iterator, bool > try_emplace(const key_type &Hash, const original_key_type &Key, Ts &&...Args)
Definition:HashKeyMap.h:65
llvm::sampleprof::SampleContext
Definition:SampleProf.h:523
llvm::sampleprof::SampleContext::hasContext
bool hasContext() const
Definition:SampleProf.h:615
llvm::sampleprof::SampleContext::setAllAttributes
void setAllAttributes(uint32_t A)
Definition:SampleProf.h:611
llvm::sampleprof::SampleContext::getHashCode
uint64_t getHashCode() const
Definition:SampleProf.h:639
llvm::sampleprof::SampleContext::getFunction
FunctionId getFunction() const
Definition:SampleProf.h:617
llvm::sampleprof::SampleContext::isPrefixOf
bool isPrefixOf(const SampleContext &That) const
Definition:SampleProf.h:696
llvm::sampleprof::SampleProfileMap
This class provides operator overloads to the map container using MD5 as the key type,...
Definition:SampleProf.h:1313
llvm::sampleprof::SampleProfileMap::find
iterator find(const SampleContext &Ctx)
Definition:SampleProf.h:1324
llvm::sampleprof::SampleProfileMap::create
mapped_type & create(const SampleContext &Ctx)
Definition:SampleProf.h:1317
llvm::sampleprof::SampleProfileMap::erase
size_t erase(const SampleContext &Ctx)
Definition:SampleProf.h:1334
llvm::sampleprof::SampleProfileReaderBinary::readProfile
std::error_code readProfile(FunctionSamples &FProfile)
Read the contents of the given profile instance.
Definition:SampleProfReader.cpp:598
llvm::sampleprof::SampleProfileReaderBinary::readNameTable
std::error_code readNameTable()
Read the whole name table.
Definition:SampleProfReader.cpp:1103
llvm::sampleprof::SampleProfileReaderBinary::Data
const uint8_t * Data
Points to the current location in the buffer.
Definition:SampleProfReader.h:705
llvm::sampleprof::SampleProfileReaderBinary::readString
ErrorOr< StringRef > readString()
Read a string from the profile.
Definition:SampleProfReader.cpp:511
llvm::sampleprof::SampleProfileReaderBinary::NameTable
std::vector< FunctionId > NameTable
Function name table.
Definition:SampleProfReader.h:711
llvm::sampleprof::SampleProfileReaderBinary::readNumber
ErrorOr< T > readNumber()
Read a numeric value of type T from the profile.
Definition:SampleProfReader.cpp:493
llvm::sampleprof::SampleProfileReaderBinary::readContextFromTable
ErrorOr< SampleContextFrames > readContextFromTable(size_t *RetIdx=nullptr)
Read a context indirectly via the CSNameTable.
Definition:SampleProfReader.cpp:557
llvm::sampleprof::SampleProfileReaderBinary::readSampleContextFromTable
ErrorOr< std::pair< SampleContext, uint64_t > > readSampleContextFromTable()
Read a context indirectly via the CSNameTable if the profile has context, otherwise same as readStrin...
Definition:SampleProfReader.cpp:569
llvm::sampleprof::SampleProfileReaderBinary::readHeader
std::error_code readHeader() override
Read and validate the file header.
Definition:SampleProfReader.cpp:1511
llvm::sampleprof::SampleProfileReaderBinary::MD5SampleContextStart
const uint64_t * MD5SampleContextStart
The starting address of the table of MD5 values of sample contexts.
Definition:SampleProfReader.h:726
llvm::sampleprof::SampleProfileReaderBinary::CSNameTable
std::vector< SampleContextFrameVector > CSNameTable
CSNameTable is used to save full context vectors.
Definition:SampleProfReader.h:715
llvm::sampleprof::SampleProfileReaderBinary::readImpl
std::error_code readImpl() override
Read sample profiles from the associated file.
Definition:SampleProfReader.cpp:712
llvm::sampleprof::SampleProfileReaderBinary::readStringFromTable
ErrorOr< FunctionId > readStringFromTable(size_t *RetIdx=nullptr)
Read a string indirectly via the name table. Optionally return the index.
Definition:SampleProfReader.cpp:547
llvm::sampleprof::SampleProfileReaderBinary::MD5SampleContextTable
std::vector< uint64_t > MD5SampleContextTable
Table to cache MD5 values of sample contexts corresponding to readSampleContextFromTable(),...
Definition:SampleProfReader.h:720
llvm::sampleprof::SampleProfileReaderBinary::readStringIndex
ErrorOr< size_t > readStringIndex(T &Table)
Read the string index and check whether it overflows the table.
Definition:SampleProfReader.cpp:537
llvm::sampleprof::SampleProfileReaderBinary::End
const uint8_t * End
Points to the end of the buffer.
Definition:SampleProfReader.h:708
llvm::sampleprof::SampleProfileReaderBinary::readUnencodedNumber
ErrorOr< T > readUnencodedNumber()
Read a numeric value of type T from the profile.
Definition:SampleProfReader.cpp:524
llvm::sampleprof::SampleProfileReaderBinary::readFuncProfile
std::error_code readFuncProfile(const uint8_t *Start)
Read the next function profile instance.
Definition:SampleProfReader.cpp:708
llvm::sampleprof::SampleProfileReaderBinary::readSummary
std::error_code readSummary()
Read profile summary.
Definition:SampleProfReader.cpp:1544
llvm::sampleprof::SampleProfileReaderBinary::readMagicIdent
std::error_code readMagicIdent()
Read the contents of Magic number and Version number.
Definition:SampleProfReader.cpp:1493
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readFuncOffsetTable
std::error_code readFuncOffsetTable()
Definition:SampleProfReader.cpp:849
llvm::sampleprof::SampleProfileReaderExtBinaryBase::SecHdrTable
std::vector< SecHdrTableEntry > SecHdrTable
Definition:SampleProfReader.h:775
llvm::sampleprof::SampleProfileReaderExtBinaryBase::collectFuncsFromModule
bool collectFuncsFromModule() override
Collect functions with definitions in Module M.
Definition:SampleProfReader.cpp:840
llvm::sampleprof::SampleProfileReaderExtBinaryBase::getSectionSize
uint64_t getSectionSize(SecType Type)
Get the total size of all Type sections.
Definition:SampleProfReader.cpp:1402
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readCSNameTableSec
std::error_code readCSNameTableSec()
Definition:SampleProfReader.cpp:1203
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readCustomSection
virtual std::error_code readCustomSection(const SecHdrTableEntry &Entry)=0
llvm::sampleprof::SampleProfileReaderExtBinaryBase::FuncOffsetList
std::vector< std::pair< SampleContext, uint64_t > > FuncOffsetList
The list version of FuncOffsetTable.
Definition:SampleProfReader.h:812
llvm::sampleprof::SampleProfileReaderExtBinaryBase::FuncsToUse
DenseSet< StringRef > FuncsToUse
The set containing the functions to use when compiling a module.
Definition:SampleProfReader.h:815
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readFuncMetadata
std::error_code readFuncMetadata(bool ProfileHasAttribute, SampleProfileMap &Profiles)
Definition:SampleProfReader.cpp:1304
llvm::sampleprof::SampleProfileReaderExtBinaryBase::ProfSymList
std::unique_ptr< ProfileSymbolList > ProfSymList
Definition:SampleProfReader.h:803
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readSecHdrTable
std::error_code readSecHdrTable()
Definition:SampleProfReader.cpp:1375
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readFuncProfiles
std::error_code readFuncProfiles()
Definition:SampleProfReader.cpp:977
llvm::sampleprof::SampleProfileReaderExtBinaryBase::useFuncOffsetList
bool useFuncOffsetList() const
Determine which container readFuncOffsetTable() should populate, the list FuncOffsetList or the map F...
Definition:SampleProfReader.cpp:798
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readNameTableSec
std::error_code readNameTableSec(bool IsMD5, bool FixedLengthMD5)
Definition:SampleProfReader.cpp:1144
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readSecHdrTableEntry
std::error_code readSecHdrTableEntry(uint64_t Idx)
Definition:SampleProfReader.cpp:1348
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readImpl
std::error_code readImpl() override
Read sample profiles in extensible format from the associated file.
Definition:SampleProfReader.cpp:1045
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readOneSection
virtual std::error_code readOneSection(const uint8_t *Start, uint64_t Size, const SecHdrTableEntry &Entry)
Definition:SampleProfReader.cpp:723
llvm::sampleprof::SampleProfileReaderExtBinaryBase::dumpSectionInfo
bool dumpSectionInfo(raw_ostream &OS=dbgs()) override
Definition:SampleProfReader.cpp:1474
llvm::sampleprof::SampleProfileReaderExtBinaryBase::FuncOffsetTable
DenseMap< hash_code, uint64_t > FuncOffsetTable
The table mapping from a function context's MD5 to the offset of its FunctionSample towards file star...
Definition:SampleProfReader.h:808
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readHeader
std::error_code readHeader() override
Read and validate the file header.
Definition:SampleProfReader.cpp:1387
llvm::sampleprof::SampleProfileReaderExtBinaryBase::getFileSize
uint64_t getFileSize()
Get the total size of header and all sections.
Definition:SampleProfReader.cpp:1411
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readProfileSymbolList
std::error_code readProfileSymbolList()
Definition:SampleProfReader.cpp:1007
llvm::sampleprof::SampleProfileReaderExtBinary
Definition:SampleProfReader.h:848
llvm::sampleprof::SampleProfileReaderExtBinary::hasFormat
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if Buffer is in the format supported by this class.
Definition:SampleProfReader.cpp:1589
llvm::sampleprof::SampleProfileReaderGCC
Definition:SampleProfReader.h:881
llvm::sampleprof::SampleProfileReaderGCC::readNumber
ErrorOr< T > readNumber()
Definition:SampleProfReader.cpp:1603
llvm::sampleprof::SampleProfileReaderGCC::GcovBuffer
GCOVBuffer GcovBuffer
GCOV buffer containing the profile.
Definition:SampleProfReader.h:909
llvm::sampleprof::SampleProfileReaderGCC::Names
std::vector< std::string > Names
Function names in this profile.
Definition:SampleProfReader.h:912
llvm::sampleprof::SampleProfileReaderGCC::readImpl
std::error_code readImpl() override
Read sample profiles from the associated file.
Definition:SampleProfReader.cpp:1823
llvm::sampleprof::SampleProfileReaderGCC::readNameTable
std::error_code readNameTable()
Definition:SampleProfReader.cpp:1661
llvm::sampleprof::SampleProfileReaderGCC::readHeader
std::error_code readHeader() override
Read and validate the file header.
Definition:SampleProfReader.cpp:1626
llvm::sampleprof::SampleProfileReaderGCC::readString
ErrorOr< StringRef > readString()
Definition:SampleProfReader.cpp:1619
llvm::sampleprof::SampleProfileReaderGCC::GCOVTagAFDOFunction
static const uint32_t GCOVTagAFDOFunction
Definition:SampleProfReader.h:916
llvm::sampleprof::SampleProfileReaderGCC::readOneFunctionProfile
std::error_code readOneFunctionProfile(const InlineCallStack &InlineStack, bool Update, uint32_t Offset)
Definition:SampleProfReader.cpp:1696
llvm::sampleprof::SampleProfileReaderGCC::readFunctionProfiles
std::error_code readFunctionProfiles()
Definition:SampleProfReader.cpp:1679
llvm::sampleprof::SampleProfileReaderGCC::GCOVTagAFDOFileNames
static const uint32_t GCOVTagAFDOFileNames
GCOV tags used to separate sections in the profile file.
Definition:SampleProfReader.h:915
llvm::sampleprof::SampleProfileReaderGCC::skipNextWord
std::error_code skipNextWord()
Definition:SampleProfReader.cpp:1596
llvm::sampleprof::SampleProfileReaderGCC::hasFormat
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if Buffer is in the format supported by this class.
Definition:SampleProfReader.cpp:1836
llvm::sampleprof::SampleProfileReaderGCC::readSectionTag
std::error_code readSectionTag(uint32_t Expected)
Read the section tag and check that it's the same as Expected.
Definition:SampleProfReader.cpp:1647
llvm::sampleprof::SampleProfileReaderItaniumRemapper::create
static ErrorOr< std::unique_ptr< SampleProfileReaderItaniumRemapper > > create(StringRef Filename, vfs::FileSystem &FS, SampleProfileReader &Reader, LLVMContext &C)
Create a remapper from the given remapping file.
Definition:SampleProfReader.cpp:1925
llvm::sampleprof::SampleProfileReaderItaniumRemapper::applyRemapping
void applyRemapping(LLVMContext &Ctx)
Apply remappings to the profile read by Reader.
Definition:SampleProfReader.cpp:1841
llvm::sampleprof::SampleProfileReaderItaniumRemapper::lookUpNameInProfile
std::optional< StringRef > lookUpNameInProfile(StringRef FunctionName)
Return the equivalent name in the profile for FunctionName if it exists.
Definition:SampleProfReader.cpp:1870
llvm::sampleprof::SampleProfileReaderRawBinary
Definition:SampleProfReader.h:733
llvm::sampleprof::SampleProfileReaderRawBinary::hasFormat
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if Buffer is in the format supported by this class.
Definition:SampleProfReader.cpp:1582
llvm::sampleprof::SampleProfileReaderText
Definition:SampleProfReader.h:611
llvm::sampleprof::SampleProfileReaderText::readImpl
std::error_code readImpl() override
Read sample profiles from the associated file.
Definition:SampleProfReader.cpp:325
llvm::sampleprof::SampleProfileReaderText::hasFormat
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if Buffer is in the format supported by this class.
Definition:SampleProfReader.cpp:477
llvm::sampleprof::SampleProfileReader
Sample-based profile reader.
Definition:SampleProfReader.h:346
llvm::sampleprof::SampleProfileReader::ProfileSecRange
std::pair< const uint8_t *, const uint8_t * > ProfileSecRange
Definition:SampleProfReader.h:570
llvm::sampleprof::SampleProfileReader::ProfileIsPreInlined
bool ProfileIsPreInlined
Whether function profile contains ShouldBeInlined contexts.
Definition:SampleProfReader.h:582
llvm::sampleprof::SampleProfileReader::FuncMetadataIndex
std::unordered_map< uint64_t, std::pair< const uint8_t *, const uint8_t * > > FuncMetadataIndex
Definition:SampleProfReader.h:568
llvm::sampleprof::SampleProfileReader::getProfiles
SampleProfileMap & getProfiles()
Return all the profiles.
Definition:SampleProfReader.h:448
llvm::sampleprof::SampleProfileReader::CSProfileCount
uint32_t CSProfileCount
Number of context-sensitive profiles.
Definition:SampleProfReader.h:585
llvm::sampleprof::SampleProfileReader::create
static ErrorOr< std::unique_ptr< SampleProfileReader > > create(StringRef Filename, LLVMContext &C, vfs::FileSystem &FS, FSDiscriminatorPass P=FSDiscriminatorPass::Base, StringRef RemapFilename="")
Create a sample profile reader appropriate to the file format.
Definition:SampleProfReader.cpp:1905
llvm::sampleprof::SampleProfileReader::dump
void dump(raw_ostream &OS=dbgs())
Print all the profiles on stream OS.
Definition:SampleProfReader.cpp:70
llvm::sampleprof::SampleProfileReader::useMD5
bool useMD5() const
Return whether names in the profile are all MD5 numbers.
Definition:SampleProfReader.h:502
llvm::sampleprof::SampleProfileReader::M
const Module * M
The current module being compiled if SampleProfileReader is used by compiler.
Definition:SampleProfReader.h:596
llvm::sampleprof::SampleProfileReader::Buffer
std::unique_ptr< MemoryBuffer > Buffer
Memory buffer holding the profile file.
Definition:SampleProfReader.h:535
llvm::sampleprof::SampleProfileReader::Remapper
std::unique_ptr< SampleProfileReaderItaniumRemapper > Remapper
Definition:SampleProfReader.h:557
llvm::sampleprof::SampleProfileReader::ProfileHasAttribute
bool ProfileHasAttribute
Whether the profile has attribute metadata.
Definition:SampleProfReader.h:573
llvm::sampleprof::SampleProfileReader::SkipFlatProf
bool SkipFlatProf
If SkipFlatProf is true, skip functions marked with !Flat in text mode or sections with SecFlagFlat f...
Definition:SampleProfReader.h:608
llvm::sampleprof::SampleProfileReader::read
std::error_code read()
The interface to read sample profiles from the associated file.
Definition:SampleProfReader.h:374
llvm::sampleprof::SampleProfileReader::getBuffer
MemoryBuffer * getBuffer() const
Definition:SampleProfReader.h:475
llvm::sampleprof::SampleProfileReader::ProfileIsCS
bool ProfileIsCS
Whether function profiles are context-sensitive flat profiles.
Definition:SampleProfReader.h:579
llvm::sampleprof::SampleProfileReader::ProfileIsMD5
bool ProfileIsMD5
Whether the profile uses MD5 for Sample Contexts and function names.
Definition:SampleProfReader.h:604
llvm::sampleprof::SampleProfileReader::Summary
std::unique_ptr< ProfileSummary > Summary
Profile summary information.
Definition:SampleProfReader.h:538
llvm::sampleprof::SampleProfileReader::computeSummary
void computeSummary()
Compute summary for this profile.
Definition:SampleProfReader.cpp:2013
llvm::sampleprof::SampleProfileReader::getDiscriminatorMask
uint32_t getDiscriminatorMask() const
Get the bitmask the discriminators: For FS profiles, return the bit mask for this pass.
Definition:SampleProfReader.h:366
llvm::sampleprof::SampleProfileReader::ProfileIsFS
bool ProfileIsFS
Whether the function profiles use FS discriminators.
Definition:SampleProfReader.h:588
llvm::sampleprof::SampleProfileReader::dumpJson
void dumpJson(raw_ostream &OS=dbgs())
Print all the profiles on stream OS in the JSON format.
Definition:SampleProfReader.cpp:137
llvm::sampleprof::SampleProfileReader::Profiles
SampleProfileMap Profiles
Map every function to its associated profile.
Definition:SampleProfReader.h:529
llvm::sampleprof::SampleProfileReader::dumpFunctionProfile
void dumpFunctionProfile(const FunctionSamples &FS, raw_ostream &OS=dbgs())
Print the profile for FunctionSamples on stream OS.
Definition:SampleProfReader.cpp:64
llvm::sampleprof::SampleProfileReader::ProfileIsProbeBased
bool ProfileIsProbeBased
Whether samples are collected based on pseudo probes.
Definition:SampleProfReader.h:576
llvm::sampleprof::SampleProfileReader::reportError
void reportError(int64_t LineNumber, const Twine &Msg) const
Report a parse error message.
Definition:SampleProfReader.h:451
llvm::sampleprof::SampleProfileReader::Ctx
LLVMContext & Ctx
LLVM context used to emit diagnostics.
Definition:SampleProfReader.h:532
llvm::sampleprof::SampleRecord
Representation of a single sample record.
Definition:SampleProf.h:325
llvm::sampleprof::SampleRecord::getSamples
uint64_t getSamples() const
Definition:SampleProf.h:392
llvm::sampleprof::SampleRecord::getSortedCallTargets
const SortedCallTargetSet getSortedCallTargets() const
Definition:SampleProf.h:394
llvm::vfs::FileSystem
The virtual file system interface.
Definition:VirtualFileSystem.h:266
uint32_t
uint64_t
uint8_t
llvm::CallingConv::C
@ C
The default llvm calling convention, compatible with C.
Definition:CallingConv.h:34
llvm::GCOV::GCOVVersion
GCOVVersion
Definition:GCOV.h:42
llvm::GCOV::V407
@ V407
Definition:GCOV.h:42
llvm::cl::Hidden
@ Hidden
Definition:CommandLine.h:137
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition:CommandLine.h:443
llvm::compression::zlib::decompress
Error decompress(ArrayRef< uint8_t > Input, uint8_t *Output, size_t &UncompressedSize)
Definition:Compression.cpp:151
llvm::compression::zlib::isAvailable
bool isAvailable()
Definition:Compression.cpp:146
llvm::sampleprof::sortFuncProfiles
void sortFuncProfiles(const SampleProfileMap &ProfileMap, std::vector< NameFunctionSamples > &SortedProfiles)
Definition:SampleProf.cpp:202
llvm::sampleprof::SPMagic
static uint64_t SPMagic(SampleProfileFormat Format=SPF_Binary)
Definition:SampleProf.h:106
llvm::sampleprof::SecCommonFlags::SecFlagCompress
@ SecFlagCompress
llvm::sampleprof::SecCommonFlags::SecFlagFlat
@ SecFlagFlat
llvm::sampleprof::SPF_Ext_Binary
@ SPF_Ext_Binary
Definition:SampleProf.h:96
llvm::sampleprof::hasSecFlag
static bool hasSecFlag(const SecHdrTableEntry &Entry, SecFlagType Flag)
Definition:SampleProf.h:264
llvm::sampleprof::CallsiteSampleMap
std::map< LineLocation, FunctionSamplesMap > CallsiteSampleMap
Definition:SampleProf.h:736
llvm::sampleprof::FSDiscriminatorPass
FSDiscriminatorPass
Definition:Discriminator.h:57
llvm::sampleprof::SecNameTableFlags::SecFlagMD5Name
@ SecFlagMD5Name
llvm::sampleprof::SecNameTableFlags::SecFlagUniqSuffix
@ SecFlagUniqSuffix
llvm::sampleprof::SecNameTableFlags::SecFlagFixedLengthMD5
@ SecFlagFixedLengthMD5
llvm::sampleprof::HIST_TYPE_INDIR_CALL_TOPN
@ HIST_TYPE_INDIR_CALL_TOPN
Definition:SampleProfReader.h:878
llvm::sampleprof::MD5Hash
uint64_t MD5Hash(const FunctionId &Obj)
Definition:FunctionId.h:167
llvm::sampleprof::ContextShouldBeInlined
@ ContextShouldBeInlined
Definition:SampleProf.h:459
llvm::sampleprof::BodySampleMap
std::map< LineLocation, SampleRecord > BodySampleMap
Definition:SampleProf.h:732
llvm::sampleprof::SecProfSummaryFlags::SecFlagIsPreInlined
@ SecFlagIsPreInlined
SecFlagIsPreInlined means this profile contains ShouldBeInlined contexts thus this is CS preinliner c...
llvm::sampleprof::SecProfSummaryFlags::SecFlagPartial
@ SecFlagPartial
SecFlagPartial means the profile is for common/shared code.
llvm::sampleprof::SecProfSummaryFlags::SecFlagFSDiscriminator
@ SecFlagFSDiscriminator
SecFlagFSDiscriminator means this profile uses flow-sensitive discriminators.
llvm::sampleprof::SecProfSummaryFlags::SecFlagFullContext
@ SecFlagFullContext
SecFlagContext means this is context-sensitive flat profile for CSSPGO.
llvm::sampleprof::SampleContextFrameVector
SmallVector< SampleContextFrame, 1 > SampleContextFrameVector
Definition:SampleProf.h:504
llvm::sampleprof::SecFuncOffsetFlags::SecFlagOrdered
@ SecFlagOrdered
llvm::sampleprof::SecFuncMetadataFlags::SecFlagHasAttribute
@ SecFlagHasAttribute
llvm::sampleprof::SecFuncMetadataFlags::SecFlagIsProbeBased
@ SecFlagIsProbeBased
llvm::sampleprof::getSecName
static std::string getSecName(SecType Type)
Definition:SampleProf.h:131
llvm::sampleprof::SPVersion
static uint64_t SPVersion()
Definition:SampleProf.h:113
llvm::sampleprof::SecType
SecType
Definition:SampleProf.h:118
llvm::sampleprof::SecNameTable
@ SecNameTable
Definition:SampleProf.h:121
llvm::sampleprof::SecLBRProfile
@ SecLBRProfile
Definition:SampleProf.h:128
llvm::sampleprof::SecProfSummary
@ SecProfSummary
Definition:SampleProf.h:120
llvm::sampleprof::SecCSNameTable
@ SecCSNameTable
Definition:SampleProf.h:125
llvm::sampleprof::SecFuncMetadata
@ SecFuncMetadata
Definition:SampleProf.h:124
llvm::sampleprof::SecProfileSymbolList
@ SecProfileSymbolList
Definition:SampleProf.h:122
llvm::sampleprof::SecFuncOffsetTable
@ SecFuncOffsetTable
Definition:SampleProf.h:123
llvm::support::endian::read64le
uint64_t read64le(const void *P)
Definition:Endian.h:428
llvm::support::endian::write64le
void write64le(void *P, uint64_t V)
Definition:Endian.h:471
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::Offset
@ Offset
Definition:DWP.cpp:480
llvm::setupMemoryBuffer
static Expected< std::unique_ptr< MemoryBuffer > > setupMemoryBuffer(const Twine &Filename, vfs::FileSystem &FS)
Definition:CodeGenDataReader.cpp:25
llvm::Depth
@ Depth
Definition:SIMachineScheduler.h:36
llvm::handleAllErrors
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
Definition:Error.h:977
llvm::decodeULEB128
uint64_t decodeULEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a ULEB128 value.
Definition:LEB128.h:131
llvm::append_range
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition:STLExtras.h:2115
llvm::mergeSampleProfErrors
sampleprof_error mergeSampleProfErrors(sampleprof_error &Accumulator, sampleprof_error Result)
Definition:SampleProf.h:69
llvm::sampleprof_error
sampleprof_error
Definition:SampleProf.h:47
llvm::sampleprof_error::zlib_unavailable
@ zlib_unavailable
llvm::sampleprof_error::success
@ success
llvm::sampleprof_error::unsupported_version
@ unsupported_version
llvm::sampleprof_error::bad_magic
@ bad_magic
llvm::sampleprof_error::uncompress_failed
@ uncompress_failed
llvm::sampleprof_error::malformed
@ malformed
llvm::sampleprof_error::truncated_name_table
@ truncated_name_table
llvm::sampleprof_error::truncated
@ truncated
llvm::sampleprof_error::unrecognized_format
@ unrecognized_format
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition:raw_ostream.cpp:907
llvm::count
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
Definition:STLExtras.h:1938
llvm::DS_Warning
@ DS_Warning
Definition:DiagnosticInfo.h:51
llvm::HighlightColor::Tag
@ Tag
llvm::Version
@ Version
Definition:PGOCtxProfWriter.h:22
raw_ostream.h
llvm::cl::desc
Definition:CommandLine.h:409
llvm::sampleprof::LineLocation
Represents the relative location of an instruction.
Definition:SampleProf.h:280
llvm::sampleprof::LineLocation::LineOffset
uint32_t LineOffset
Definition:SampleProf.h:303
llvm::sampleprof::LineLocation::Discriminator
uint32_t Discriminator
Definition:SampleProf.h:304
llvm::sampleprof::SecHdrTableEntry
Definition:SampleProf.h:156

Generated on Fri Jul 18 2025 11:47:44 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp