42using namespace coverage;
43using namespace object;
45#define DEBUG_TYPE "coverage-mapping"
47STATISTIC(CovMapNumRecords,
"The # of coverage function records");
48STATISTIC(CovMapNumUsedRecords,
"The # of used coverage function records");
50void CoverageMappingIterator::increment() {
72 "the size of ULEB128 is too big");
80 if (Result >= MaxPlus1)
81 return make_error<CoverageMapError>(
83 "the value of ULEB128 is greater than or equal to MaxPlus1");
92 "the value of ULEB128 is too big");
107 if (
auto Err =
readSize(NumFilenames))
111 "number of filenames is zero");
114 return readUncompressed(Version, NumFilenames);
123 if (
auto Err =
readSize(CompressedLen))
126 if (CompressedLen > 0) {
128 return make_error<CoverageMapError>(
138 arrayRefFromStringRef(CompressedFilenames), StorageBuf,
142 return make_error<CoverageMapError>(
148 return Delegate.readUncompressed(Version, NumFilenames);
151 return readUncompressed(Version, NumFilenames);
158 for (
size_t I = 0;
I < NumFilenames; ++
I) {
162 Filenames.push_back(Filename.str());
168 Filenames.push_back(CWD.
str());
170 for (
size_t I = 1;
I < NumFilenames; ++
I) {
175 Filenames.push_back(Filename.str());
178 if (!CompilationDir.
empty())
179 P.assign(CompilationDir);
184 Filenames.push_back(
static_cast<std::string
>(
P.str()));
208 if (
ID >= Expressions.size())
210 "counter expression is invalid");
217 "counter expression kind is invalid");
225 readIntMax(EncodedCounter, std::numeric_limits<unsigned>::max()))
227 if (
auto Err = decodeCounter(EncodedCounter,
C))
238Error RawCoverageMappingReader::readMappingRegionsSubArray(
239 std::vector<CounterMappingRegion> &MappingRegions,
unsigned InferredFileID,
242 if (
auto Err =
readSize(NumRegions))
244 unsigned LineStart = 0;
245 for (
size_t I = 0;
I < NumRegions; ++
I) {
251 if (
auto Err =
readIntMax(EncodedCounterAndRegion,
252 std::numeric_limits<unsigned>::max()))
269 if (
auto Err = decodeCounter(EncodedCounterAndRegion,
C))
275 ExpandedFileID = EncodedCounterAndRegion >>
277 if (ExpandedFileID >= NumFileIDs)
279 "ExpandedFileID is invalid");
281 switch (EncodedCounterAndRegion >>
292 if (
auto Err = readCounter(
C))
294 if (
auto Err = readCounter(C2))
299 "region kind is incorrect");
305 uint64_t LineStartDelta, ColumnStart, NumLines, ColumnEnd;
307 readIntMax(LineStartDelta, std::numeric_limits<unsigned>::max()))
311 if (ColumnStart > std::numeric_limits<unsigned>::max())
313 "start column is too big");
314 if (
auto Err =
readIntMax(NumLines, std::numeric_limits<unsigned>::max()))
316 if (
auto Err =
readIntMax(ColumnEnd, std::numeric_limits<unsigned>::max()))
318 LineStart += LineStartDelta;
321 if (ColumnEnd & (1U << 31)) {
323 ColumnEnd &= ~(1U << 31);
334 if (ColumnStart == 0 && ColumnEnd == 0) {
336 ColumnEnd = std::numeric_limits<unsigned>::max();
340 dbgs() <<
"Counter in file " << InferredFileID <<
" " << LineStart <<
":"
341 << ColumnStart <<
" -> " << (LineStart + NumLines) <<
":"
342 << ColumnEnd <<
", ";
344 dbgs() <<
"Expands to file " << ExpandedFileID;
351 LineStart, ColumnStart,
352 LineStart + NumLines, ColumnEnd,
Kind);
353 if (CMR.startLoc() > CMR.endLoc())
354 return make_error<CoverageMapError>(
356 "counter mapping region locations are incorrect");
357 MappingRegions.push_back(CMR);
366 if (
auto Err =
readSize(NumFileMappings))
368 for (
size_t I = 0;
I < NumFileMappings; ++
I) {
370 if (
auto Err =
readIntMax(FilenameIndex, TranslationUnitFilenames.
size()))
372 VirtualFileMapping.
push_back(FilenameIndex);
376 for (
auto I : VirtualFileMapping) {
377 Filenames.push_back(TranslationUnitFilenames[
I]);
382 if (
auto Err =
readSize(NumExpressions))
390 for (
size_t I = 0;
I < NumExpressions; ++
I) {
391 if (
auto Err = readCounter(Expressions[
I].
LHS))
393 if (
auto Err = readCounter(Expressions[
I].
RHS))
398 for (
unsigned InferredFileID = 0, S = VirtualFileMapping.
size();
399 InferredFileID < S; ++InferredFileID) {
400 if (
auto Err = readMappingRegionsSubArray(MappingRegions, InferredFileID,
401 VirtualFileMapping.
size()))
411 FileIDExpansionRegionMapping.
resize(VirtualFileMapping.
size(),
nullptr);
413 for (
auto &R : MappingRegions) {
416 assert(!FileIDExpansionRegionMapping[R.ExpandedFileID]);
417 FileIDExpansionRegionMapping[R.ExpandedFileID] = &R;
419 for (
auto &R : MappingRegions) {
420 if (FileIDExpansionRegionMapping[R.FileID]) {
421 FileIDExpansionRegionMapping[R.FileID]->Count = R.Count;
422 FileIDExpansionRegionMapping[R.FileID] =
nullptr;
434 return std::move(Err);
435 if (NumFileMappings != 1)
440 readIntMax(FilenameIndex, std::numeric_limits<unsigned>::max()))
441 return std::move(Err);
444 return std::move(Err);
445 if (NumExpressions != 0)
449 return std::move(Err);
454 std::numeric_limits<unsigned>::max()))
455 return std::move(Err);
465 Address = Section.getAddress();
509struct CovMapFuncRecordReader {
510 virtual ~CovMapFuncRecordReader() =
default;
520 const char *CovBufEnd) = 0;
533 readFunctionRecords(
const char *FuncRecBuf,
const char *FuncRecBufEnd,
534 std::optional<FilenameRange> OutOfLineFileRange,
535 const char *OutOfLineMappingBuf,
536 const char *OutOfLineMappingBufEnd) = 0;
538 template <
class IntPtrT, llvm::endianness Endian>
541 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
StringRef D,
542 std::vector<std::string> &
F);
546template <CovMapVersion Version,
class IntPtrT, llvm::endianness Endian>
547class VersionedCovMapFuncRecordReader :
public CovMapFuncRecordReader {
548 using FuncRecordType =
557 std::vector<std::string> &Filenames;
558 std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records;
570 Error insertFunctionRecordIfNeeded(
const FuncRecordType *CFR,
574 uint64_t FuncHash = CFR->template getFuncHash<Endian>();
575 NameRefType NameRef = CFR->template getFuncNameRef<Endian>();
577 FunctionRecords.
insert(std::make_pair(NameRef, Records.size()));
578 if (InsertResult.second) {
580 if (
Error Err = CFR->template getFuncName<Endian>(ProfileNames, FuncName))
582 if (FuncName.
empty())
583 return make_error<InstrProfError>(instrprof_error::malformed,
584 "function name is empty");
585 ++CovMapNumUsedRecords;
586 Records.emplace_back(Version, FuncName, FuncHash, Mapping,
591 size_t OldRecordIndex = InsertResult.first->second;
593 Records[OldRecordIndex];
598 if (!*OldIsDummyExpected)
604 if (*NewIsDummyExpected)
606 ++CovMapNumUsedRecords;
615 VersionedCovMapFuncRecordReader(
617 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
StringRef D,
618 std::vector<std::string> &
F)
619 : ProfileNames(
P), CompilationDir(
D), Filenames(
F), Records(
R) {}
621 ~VersionedCovMapFuncRecordReader()
override =
default;
624 const char *CovBufEnd)
override {
625 using namespace support;
628 return make_error<CoverageMapError>(
629 coveragemap_error::malformed,
630 "coverage mapping header section is larger than buffer size");
631 auto CovHeader =
reinterpret_cast<const CovMapHeader *
>(CovBuf);
636 CovBuf =
reinterpret_cast<const char *
>(CovHeader + 1);
641 const char *FuncRecBuf =
nullptr;
642 const char *FuncRecBufEnd =
nullptr;
643 if (Version < CovMapVersion::Version4)
645 CovBuf += NRecords *
sizeof(FuncRecordType);
646 if (Version < CovMapVersion::Version4)
647 FuncRecBufEnd = CovBuf;
650 if (CovBuf + FilenamesSize > CovBufEnd)
651 return make_error<CoverageMapError>(
652 coveragemap_error::malformed,
653 "filenames section is larger than buffer size");
654 size_t FilenamesBegin = Filenames.size();
655 StringRef FilenameRegion(CovBuf, FilenamesSize);
658 if (
auto Err = Reader.read(Version))
659 return std::move(Err);
660 CovBuf += FilenamesSize;
661 FilenameRange FileRange(FilenamesBegin, Filenames.size() - FilenamesBegin);
663 if (Version >= CovMapVersion::Version4) {
666 int64_t FilenamesRef =
669 FileRangeMap.
insert(std::make_pair(FilenamesRef, FileRange));
673 auto It = Filenames.begin();
680 FileRange = OrigRange;
690 const char *MappingBuf = CovBuf;
691 if (Version >= CovMapVersion::Version4 && CoverageSize != 0)
692 return make_error<CoverageMapError>(coveragemap_error::malformed,
693 "coverage mapping size is not zero");
694 CovBuf += CoverageSize;
695 const char *MappingEnd = CovBuf;
697 if (CovBuf > CovBufEnd)
698 return make_error<CoverageMapError>(
699 coveragemap_error::malformed,
700 "function records section is larger than buffer size");
702 if (Version < CovMapVersion::Version4) {
704 if (
Error E = readFunctionRecords(FuncRecBuf, FuncRecBufEnd, FileRange,
705 MappingBuf, MappingEnd))
716 Error readFunctionRecords(
const char *FuncRecBuf,
const char *FuncRecBufEnd,
717 std::optional<FilenameRange> OutOfLineFileRange,
718 const char *OutOfLineMappingBuf,
719 const char *OutOfLineMappingBufEnd)
override {
720 auto CFR =
reinterpret_cast<const FuncRecordType *
>(FuncRecBuf);
721 while ((
const char *)CFR < FuncRecBufEnd) {
723 const char *NextMappingBuf;
724 const FuncRecordType *NextCFR;
725 std::tie(NextMappingBuf, NextCFR) =
726 CFR->template advanceByOne<Endian>(OutOfLineMappingBuf);
727 if (Version < CovMapVersion::Version4)
728 if (NextMappingBuf > OutOfLineMappingBufEnd)
729 return make_error<CoverageMapError>(
730 coveragemap_error::malformed,
731 "next mapping buffer is larger than buffer size");
734 std::optional<FilenameRange> FileRange;
735 if (Version < CovMapVersion::Version4) {
736 FileRange = OutOfLineFileRange;
738 uint64_t FilenamesRef = CFR->template getFilenamesRef<Endian>();
739 auto It = FileRangeMap.
find(FilenamesRef);
740 if (It == FileRangeMap.
end())
741 return make_error<CoverageMapError>(
742 coveragemap_error::malformed,
743 "no filename found for function with hash=0x" +
746 FileRange = It->getSecond();
750 if (FileRange && !FileRange->isInvalid()) {
752 CFR->template getCoverageMapping<Endian>(OutOfLineMappingBuf);
753 if (Version >= CovMapVersion::Version4 &&
754 Mapping.
data() + Mapping.
size() > FuncRecBufEnd)
755 return make_error<CoverageMapError>(
756 coveragemap_error::malformed,
757 "coverage mapping data is larger than buffer size");
758 if (
Error Err = insertFunctionRecordIfNeeded(CFR, Mapping, *FileRange))
762 std::tie(OutOfLineMappingBuf, CFR) = std::tie(NextMappingBuf, NextCFR);
770template <
class IntPtrT, llvm::endianness Endian>
773 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
StringRef D,
774 std::vector<std::string> &
F) {
775 using namespace coverage;
779 return std::make_unique<VersionedCovMapFuncRecordReader<
788 if (
Error E =
P.create(
P.getNameData()))
791 return std::make_unique<VersionedCovMapFuncRecordReader<
794 return std::make_unique<VersionedCovMapFuncRecordReader<
797 return std::make_unique<VersionedCovMapFuncRecordReader<
800 return std::make_unique<VersionedCovMapFuncRecordReader<
803 return std::make_unique<VersionedCovMapFuncRecordReader<
806 return std::make_unique<VersionedCovMapFuncRecordReader<
812template <
typename T, llvm::endianness Endian>
815 std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
816 StringRef CompilationDir, std::vector<std::string> &Filenames) {
817 using namespace coverage;
826 CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames, Records,
827 CompilationDir, Filenames);
830 auto Reader = std::move(ReaderExpected.
get());
831 const char *CovBuf = CovMap.
data();
832 const char *CovBufEnd = CovBuf + CovMap.
size();
833 const char *FuncRecBuf = FuncRecords.
data();
834 const char *FuncRecBufEnd = FuncRecords.
data() + FuncRecords.
size();
835 while (CovBuf < CovBufEnd) {
842 auto NextOrErr = Reader->readCoverageHeader(CovBuf, CovBufEnd);
843 if (
auto E = NextOrErr.takeError())
845 CovBuf = NextOrErr.get();
850 return Reader->readFunctionRecords(FuncRecBuf, FuncRecBufEnd, std::nullopt,
860 std::unique_ptr<BinaryCoverageReader> Reader(
862 Reader->ProfileNames = std::move(ProfileNames);
863 StringRef FuncRecordsRef = Reader->FuncRecords->getBuffer();
865 if (
Error E = readCoverageMappingData<uint32_t, llvm::endianness::little>(
866 Reader->ProfileNames, Coverage, FuncRecordsRef,
867 Reader->MappingRecords, CompilationDir, Reader->Filenames))
870 if (
Error E = readCoverageMappingData<uint32_t, llvm::endianness::big>(
871 Reader->ProfileNames, Coverage, FuncRecordsRef,
872 Reader->MappingRecords, CompilationDir, Reader->Filenames))
875 if (
Error E = readCoverageMappingData<uint64_t, llvm::endianness::little>(
876 Reader->ProfileNames, Coverage, FuncRecordsRef,
877 Reader->MappingRecords, CompilationDir, Reader->Filenames))
880 if (
Error E = readCoverageMappingData<uint64_t, llvm::endianness::big>(
881 Reader->ProfileNames, Coverage, FuncRecordsRef,
882 Reader->MappingRecords, CompilationDir, Reader->Filenames))
885 return make_error<CoverageMapError>(
887 "not supported endianness or bytes in address");
888 return std::move(Reader);
893 uint8_t BytesInAddress = 8;
900 "the size of data is too small");
901 auto TestingVersion =
902 support::endian::byte_swap<uint64_t, llvm::endianness::little>(
912 return make_error<CoverageMapError>(
914 "the size of TestingFormatMagic is too big");
922 "the size of ULEB128 is too big");
924 if (
Data.size() < ProfileNamesSize)
926 "the size of ProfileNames is too big");
930 Data =
Data.substr(ProfileNamesSize);
939 "the size of ULEB128 is too big");
942 return make_error<CoverageMapError>(
944 "the size of CoverageMapping is teoo small");
951 if (
Data.size() < Pad)
953 "insufficient padding");
956 return make_error<CoverageMapError>(
958 "coverage mapping header section is larger than data size");
959 auto const *CovHeader =
reinterpret_cast<const CovMapHeader *
>(
967 CoverageMappingSize =
Data.size();
971 CoverageMappingSize =
sizeof(
CovMapHeader) + FilenamesSize;
976 Data =
Data.substr(CoverageMappingSize);
982 "data is not empty");
987 if (
Data.size() < Pad)
989 "insufficient padding");
997 BytesInAddress,
Endian, CompilationDir);
1007 bool IsCOFF = isa<COFFObjectFile>(OF);
1009 return IsCOFF ?
N.split(
'$').first :
N;
1013 std::vector<SectionRef> Sections;
1014 for (
const auto &Section : OF.
sections()) {
1018 if (stripSuffix(*NameOrErr) ==
Name)
1019 Sections.push_back(Section);
1021 if (Sections.empty())
1030 std::unique_ptr<ObjectFile> OF;
1031 if (
auto *Universal = dyn_cast<MachOUniversalBinary>(
Bin.get())) {
1034 auto ObjectFileOrErr = Universal->getMachOObjectForArch(Arch);
1035 if (!ObjectFileOrErr)
1036 return ObjectFileOrErr.takeError();
1037 OF = std::move(ObjectFileOrErr.get());
1038 }
else if (isa<ObjectFile>(
Bin.get())) {
1040 OF.reset(cast<ObjectFile>(
Bin.release()));
1042 if (!Arch.
empty() && OF->getArch() !=
Triple(Arch).getArch())
1047 "binary is not an object file");
1050 uint8_t BytesInAddress = OF->getBytesInAddress();
1055 auto ObjFormat = OF->getTripleObjectFormat();
1059 if (
auto E = NamesSection.takeError())
1060 return std::move(
E);
1061 auto CoverageSection =
1064 if (
auto E = CoverageSection.takeError())
1065 return std::move(
E);
1066 std::vector<SectionRef> CoverageSectionRefs = *CoverageSection;
1067 if (CoverageSectionRefs.size() != 1)
1069 "the size of name section is not one");
1070 auto CoverageMappingOrErr = CoverageSectionRefs.back().getContents();
1071 if (!CoverageMappingOrErr)
1072 return CoverageMappingOrErr.takeError();
1076 std::vector<SectionRef> NamesSectionRefs = *NamesSection;
1077 if (NamesSectionRefs.size() != 1)
1078 return make_error<CoverageMapError>(
1080 "the size of coverage mapping section is not one");
1081 if (
Error E = ProfileNames.
create(NamesSectionRefs.back()))
1082 return std::move(
E);
1085 auto CoverageRecordsSections =
1090 if (
auto E = CoverageRecordsSections.takeError()) {
1098 const Align RecordAlignment(8);
1100 for (
SectionRef Section : *CoverageRecordsSections) {
1101 auto CoverageRecordsOrErr = Section.getContents();
1102 if (!CoverageRecordsOrErr)
1103 return CoverageRecordsOrErr.takeError();
1104 FuncRecordsSize +=
alignTo(CoverageRecordsOrErr->size(), RecordAlignment);
1106 auto WritableBuffer =
1108 char *FuncRecordsBuffer = WritableBuffer->getBufferStart();
1110 "Allocated memory is correctly aligned");
1112 for (
SectionRef Section : *CoverageRecordsSections) {
1113 auto CoverageRecordsOrErr = Section.getContents();
1114 if (!CoverageRecordsOrErr)
1115 return CoverageRecordsOrErr.takeError();
1116 const auto &CoverageRecords = CoverageRecordsOrErr.get();
1117 FuncRecordsBuffer = std::copy(CoverageRecords.begin(),
1118 CoverageRecords.end(), FuncRecordsBuffer);
1120 std::fill_n(FuncRecordsBuffer,
1121 alignAddr(FuncRecordsBuffer, RecordAlignment) -
1122 (uintptr_t)FuncRecordsBuffer,
1125 assert(FuncRecordsBuffer == WritableBuffer->getBufferEnd() &&
1127 FuncRecords = std::move(WritableBuffer);
1135 BytesInAddress,
Endian, CompilationDir);
1142 if (
auto *Universal = dyn_cast<MachOUniversalBinary>(
Bin)) {
1143 for (
auto &ObjForArch : Universal->objects())
1144 if (Arch == ObjForArch.getArchFlagName())
1156 std::vector<std::unique_ptr<BinaryCoverageReader>> Readers;
1160 support::endian::byte_swap<uint64_t, llvm::endianness::little>(
1167 return ReaderOrErr.takeError();
1168 Readers.push_back(std::move(ReaderOrErr.get()));
1169 return std::move(Readers);
1175 return BinOrErr.takeError();
1176 std::unique_ptr<Binary>
Bin = std::move(BinOrErr.get());
1179 return make_error<CoverageMapError>(
1184 if (
auto *Universal = dyn_cast<MachOUniversalBinary>(
Bin.get())) {
1185 for (
auto &ObjForArch : Universal->objects()) {
1187 std::string ObjArch = ObjForArch.getArchFlagName();
1188 if (Arch != ObjArch)
1191 auto ArchiveOrErr = ObjForArch.getAsArchive();
1192 if (!ArchiveOrErr) {
1199 ArchiveOrErr.get()->getMemoryBufferRef(), Arch, ObjectFileBuffers,
1200 CompilationDir, BinaryIDs);
1205 if (
auto *Ar = dyn_cast<Archive>(
Bin.get())) {
1207 for (
auto &Child : Ar->children(Err)) {
1213 ChildBufOrErr.
get(), Arch, ObjectFileBuffers, CompilationDir,
1215 if (!ChildReadersOrErr)
1216 return ChildReadersOrErr.takeError();
1217 for (
auto &Reader : ChildReadersOrErr.get())
1218 Readers.push_back(std::move(Reader));
1221 return std::move(Err);
1227 for (
auto &Buffer : Ar->takeThinBuffers())
1228 ObjectFileBuffers.push_back(std::move(Buffer));
1230 return std::move(Readers);
1235 BinaryIDs ? &BinaryID :
nullptr);
1237 return ReaderOrErr.takeError();
1238 Readers.push_back(std::move(ReaderOrErr.get()));
1239 if (!BinaryID.
empty())
1241 return std::move(Readers);
1245 if (CurrentRecord >= MappingRecords.size())
1248 FunctionsFilenames.clear();
1249 Expressions.clear();
1250 MappingRegions.clear();
1251 auto &R = MappingRecords[CurrentRecord];
1252 auto F =
ArrayRef(Filenames).
slice(R.FilenamesBegin, R.FilenamesSize);
1254 Expressions, MappingRegions);
1255 if (
auto Err = Reader.
read())
1258 Record.FunctionName = R.FunctionName;
1259 Record.FunctionHash = R.FunctionHash;
1260 Record.Filenames = FunctionsFilenames;
1261 Record.Expressions = Expressions;
1262 Record.MappingRegions = MappingRegions;
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static Error readCoverageMappingData(InstrProfSymtab &ProfileNames, StringRef CovMap, StringRef FuncRecords, std::vector< BinaryCoverageReader::ProfileMappingRecord > &Records, StringRef CompilationDir, std::vector< std::string > &Filenames)
static Expected< std::unique_ptr< BinaryCoverageReader > > loadBinaryFormat(std::unique_ptr< Binary > Bin, StringRef Arch, StringRef CompilationDir="", object::BuildIDRef *BinaryID=nullptr)
static Expected< std::unique_ptr< BinaryCoverageReader > > loadTestingFormat(StringRef Data, StringRef CompilationDir)
static bool isArchSpecifierInvalidOrMissing(Binary *Bin, StringRef Arch)
Determine whether Arch is invalid or empty, given Bin.
static Expected< bool > isCoverageMappingDummy(uint64_t Hash, StringRef Mapping)
static const unsigned EncodingExpansionRegionBit
static Expected< std::vector< SectionRef > > lookupSections(ObjectFile &OF, StringRef Name)
Find all sections that match Name.
This file defines the DenseMap class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
reference get()
Returns a reference to the stored T value.
A symbol table used for function PGO name look-up with keys (such as pointers, md5hash values) to the...
Error create(object::SectionRef &Section)
Create InstrProfSymtab from an object file section which contains function PGO names.
StringRef getFuncName(uint64_t FuncNameAddress, size_t NameSize)
Return function's PGO name from the function name's symbol address in the object file.
const char * getBufferStart() const
StringRef getBuffer() const
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
Pass interface - Implemented by all 'passes'.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
constexpr bool empty() const
empty - Check if the string is empty.
constexpr size_t size() const
size - Get the string size.
const unsigned char * bytes_begin() const
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Triple - Helper class for working with autoconf configuration names.
static Twine utohexstr(const uint64_t &Val)
LLVM Value Representation.
static std::unique_ptr< WritableMemoryBuffer > getNewUninitMemBuffer(size_t Size, const Twine &BufferName="", std::optional< Align > Alignment=std::nullopt)
Allocate a new MemoryBuffer of the specified size that is not initialized.
Reader for the coverage mapping data that is emitted by the frontend and stored in an object file.
static Expected< std::vector< std::unique_ptr< BinaryCoverageReader > > > create(MemoryBufferRef ObjectBuffer, StringRef Arch, SmallVectorImpl< std::unique_ptr< MemoryBuffer > > &ObjectFileBuffers, StringRef CompilationDir="", SmallVectorImpl< object::BuildIDRef > *BinaryIDs=nullptr)
std::unique_ptr< MemoryBuffer > FuncRecordsStorage
Error readNextRecord(CoverageMappingRecord &Record) override
static Expected< std::unique_ptr< BinaryCoverageReader > > createCoverageReaderFromBuffer(StringRef Coverage, FuncRecordsStorage &&FuncRecords, InstrProfSymtab &&ProfileNames, uint8_t BytesInAddress, llvm::endianness Endian, StringRef CompilationDir="")
A Counter mapping context is used to connect the counters, expressions and the obtained counter value...
void dump(const Counter &C, raw_ostream &OS) const
coveragemap_error get() const
A file format agnostic iterator over coverage mapping data.
virtual Error readNextRecord(CoverageMappingRecord &Record)=0
The mapping of profile information to coverage data.
Reader for the raw coverage filenames.
Error read(CovMapVersion Version)
Checks if the given coverage mapping data is exported for an unused function.
Expected< bool > isDummy()
Reader for the raw coverage mapping data.
Error readSize(uint64_t &Result)
Error readIntMax(uint64_t &Result, uint64_t MaxPlus1)
Error readULEB128(uint64_t &Result)
Error readString(StringRef &Result)
This class is the base class for all object file types.
section_iterator_range sections() const
virtual bool isRelocatableObject() const =0
True if this is a relocatable object (.o/.obj).
Represents a GOFF physical record.
This is a value type class that represents a single section in the list of sections in the object fil...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
uint64_t ComputeHash(StringRef K)
Error decompress(ArrayRef< uint8_t > Input, uint8_t *Output, size_t &UncompressedSize)
@ invalid_or_missing_arch_specifier
constexpr uint64_t TestingFormatMagic
StringRef toStringRef(const std::optional< DWARFFormValue > &V, StringRef Default={})
Take an optional DWARFFormValue and try to extract a string value from it.
BuildIDRef getBuildID(const ObjectFile *Obj)
Returns the build ID, if any, contained in the given object file.
Expected< std::unique_ptr< Binary > > createBinary(MemoryBufferRef Source, LLVMContext *Context=nullptr, bool InitContent=true)
Create a Binary from Source, autodetecting the file type.
bool remove_dots(SmallVectorImpl< char > &path, bool remove_dot_dot=false, Style style=Style::native)
In-place remove any '.
bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
This is an optimization pass for GlobalISel generic memory operations.
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
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.
uint64_t offsetToAlignedAddr(const void *Addr, Align Alignment)
Returns the necessary adjustment for aligning Addr to Alignment bytes, rounding up.
std::string getInstrProfSectionName(InstrProfSectKind IPSK, Triple::ObjectFormatType OF, bool AddSegmentInfo=true)
Return the name of the profile section corresponding to IPSK.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
void consumeError(Error Err)
Consume a Error without doing anything.
bool isAddrAligned(Align Lhs, const void *Addr)
Checks that Addr is a multiple of the alignment.
uintptr_t alignAddr(const void *Addr, Align Alignment)
Aligns Addr to Alignment bytes, rounding up.
A range of filename indices.
FilenameRange(unsigned StartingIndex, unsigned Length)
This struct is a compact representation of a valid (non-zero power of two) alignment.
StringRef CoverageMapping
A Counter expression is a value that represents an arithmetic operation with two counters.
A Counter mapping region associates a source range with a specific counter.
@ ExpansionRegion
An ExpansionRegion represents a file expansion region that associates a source range with the expansi...
@ SkippedRegion
A SkippedRegion represents a source range with code that was skipped by a preprocessor or similar mea...
@ GapRegion
A GapRegion is like a CodeRegion, but its count is only set as the line execution count when its the ...
@ BranchRegion
A BranchRegion represents leaf-level boolean expressions and is associated with two counters,...
@ CodeRegion
A CodeRegion associates some code with a counter.
A Counter is an abstract value that describes how to compute the execution count for a region of code...
static const unsigned EncodingTagBits
static Counter getZero()
Return the counter that represents the number zero.
static Counter getCounter(unsigned CounterId)
Return the counter that corresponds to a specific profile counter.
static const unsigned EncodingCounterTagAndExpansionRegionTagBits
static const unsigned EncodingTagMask
static Counter getExpression(unsigned ExpressionId)
Return the counter that corresponds to a specific addition counter expression.
Coverage mapping information for a single function.