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)
83 "the value of ULEB128 is greater than or equal to MaxPlus1");
90 if (Result >
Data.size())
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) {
135 StringRef CompressedFilenames =
Data.substr(0, CompressedLen);
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");
223 uint64_t EncodedCounter;
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) {
255 if (
auto Err =
readIntMax(EncodedCounterAndRegion,
256 std::numeric_limits<unsigned>::max()))
273 if (
auto Err = decodeCounter(EncodedCounterAndRegion,
C))
279 ExpandedFileID = EncodedCounterAndRegion >>
281 if (ExpandedFileID >= NumFileIDs)
283 "ExpandedFileID is invalid");
285 switch (EncodedCounterAndRegion >>
296 if (
auto Err = readCounter(
C))
298 if (
auto Err = readCounter(C2))
304 if (
auto Err = readCounter(
C))
306 if (
auto Err = readCounter(C2))
308 if (
auto Err =
readIntMax(ID1, std::numeric_limits<int16_t>::max()))
310 if (
auto Err =
readIntMax(TID1, std::numeric_limits<int16_t>::max()))
312 if (
auto Err =
readIntMax(FID1, std::numeric_limits<int16_t>::max()))
317 "MCDCConditionID shouldn't be zero");
319 static_cast<int16_t
>(
static_cast<int16_t
>(ID1) - 1),
320 {
static_cast<int16_t
>(
static_cast<int16_t
>(FID1) - 1),
321 static_cast<int16_t
>(
static_cast<int16_t
>(TID1) - 1)}};
325 if (
auto Err =
readIntMax(BIDX, std::numeric_limits<unsigned>::max()))
327 if (
auto Err =
readIntMax(
NC, std::numeric_limits<int16_t>::max()))
334 "region kind is incorrect");
340 uint64_t LineStartDelta, ColumnStart, NumLines, ColumnEnd;
342 readIntMax(LineStartDelta, std::numeric_limits<unsigned>::max()))
346 if (ColumnStart > std::numeric_limits<unsigned>::max())
348 "start column is too big");
349 if (
auto Err =
readIntMax(NumLines, std::numeric_limits<unsigned>::max()))
351 if (
auto Err =
readIntMax(ColumnEnd, std::numeric_limits<unsigned>::max()))
353 LineStart += LineStartDelta;
356 if (ColumnEnd & (1U << 31)) {
358 ColumnEnd &= ~(1U << 31);
369 if (ColumnStart == 0 && ColumnEnd == 0) {
371 ColumnEnd = std::numeric_limits<unsigned>::max();
375 dbgs() <<
"Counter in file " << InferredFileID <<
" " << LineStart <<
":"
376 << ColumnStart <<
" -> " << (LineStart + NumLines) <<
":"
377 << ColumnEnd <<
", ";
379 dbgs() <<
"Expands to file " << ExpandedFileID;
386 C, C2, InferredFileID, ExpandedFileID, LineStart, ColumnStart,
387 LineStart + NumLines, ColumnEnd,
Kind, Params);
388 if (CMR.startLoc() > CMR.endLoc())
391 "counter mapping region locations are incorrect");
392 MappingRegions.push_back(CMR);
401 if (
auto Err =
readSize(NumFileMappings))
403 for (
size_t I = 0;
I < NumFileMappings; ++
I) {
405 if (
auto Err =
readIntMax(FilenameIndex, TranslationUnitFilenames.size()))
407 VirtualFileMapping.
push_back(FilenameIndex);
411 for (
auto I : VirtualFileMapping) {
412 Filenames.push_back(TranslationUnitFilenames[
I]);
417 if (
auto Err =
readSize(NumExpressions))
425 for (
size_t I = 0;
I < NumExpressions; ++
I) {
426 if (
auto Err = readCounter(Expressions[
I].LHS))
428 if (
auto Err = readCounter(Expressions[
I].RHS))
433 for (
unsigned InferredFileID = 0, S = VirtualFileMapping.
size();
434 InferredFileID < S; ++InferredFileID) {
435 if (
auto Err = readMappingRegionsSubArray(MappingRegions, InferredFileID,
436 VirtualFileMapping.
size()))
446 FileIDExpansionRegionMapping.
resize(VirtualFileMapping.
size(),
nullptr);
448 for (
auto &R : MappingRegions) {
451 assert(!FileIDExpansionRegionMapping[R.ExpandedFileID]);
452 FileIDExpansionRegionMapping[R.ExpandedFileID] = &R;
454 for (
auto &R : MappingRegions) {
455 if (FileIDExpansionRegionMapping[R.FileID]) {
456 FileIDExpansionRegionMapping[R.FileID]->Count = R.Count;
457 FileIDExpansionRegionMapping[R.FileID] =
nullptr;
469 return std::move(Err);
470 if (NumFileMappings != 1)
475 readIntMax(FilenameIndex, std::numeric_limits<unsigned>::max()))
476 return std::move(Err);
479 return std::move(Err);
480 if (NumExpressions != 0)
484 return std::move(Err);
489 std::numeric_limits<unsigned>::max()))
490 return std::move(Err);
514 Address = Section.getAddress();
517 Data = Data.substr(1);
523 if (Pointer < Address)
525 auto Offset = Pointer - Address;
528 return Data.substr(Pointer - Address,
Size);
555struct CovMapFuncRecordReader {
556 virtual ~CovMapFuncRecordReader() =
default;
565 virtual Expected<const char *> readCoverageHeader(
const char *CovBuf,
566 const char *CovBufEnd) = 0;
579 readFunctionRecords(
const char *FuncRecBuf,
const char *FuncRecBufEnd,
580 std::optional<FilenameRange> OutOfLineFileRange,
581 const char *OutOfLineMappingBuf,
582 const char *OutOfLineMappingBufEnd) = 0;
584 template <
class IntPtrT, llvm::endianness Endian>
585 static Expected<std::unique_ptr<CovMapFuncRecordReader>>
587 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, StringRef
D,
588 std::vector<std::string> &
F);
592template <CovMapVersion Version,
class IntPtrT, llvm::endianness Endian>
593class VersionedCovMapFuncRecordReader :
public CovMapFuncRecordReader {
594 using FuncRecordType =
600 DenseMap<NameRefType, size_t> FunctionRecords;
601 InstrProfSymtab &ProfileNames;
602 StringRef CompilationDir;
603 std::vector<std::string> &Filenames;
604 std::vector<BinaryCoverageReader::ProfileMappingRecord> &
Records;
608 DenseMap<uint64_t, FilenameRange> FileRangeMap;
616 Error insertFunctionRecordIfNeeded(
const FuncRecordType *CFR,
618 FilenameRange FileRange) {
620 uint64_t
FuncHash = CFR->template getFuncHash<Endian>();
621 NameRefType NameRef = CFR->template getFuncNameRef<Endian>();
624 if (InsertResult.second) {
626 if (
Error Err = CFR->template getFuncName<Endian>(ProfileNames, FuncName))
628 if (FuncName.
empty())
630 "function name is empty");
631 ++CovMapNumUsedRecords;
637 size_t OldRecordIndex = InsertResult.first->second;
638 BinaryCoverageReader::ProfileMappingRecord &OldRecord =
644 if (!*OldIsDummyExpected)
646 Expected<bool> NewIsDummyExpected =
650 if (*NewIsDummyExpected)
652 ++CovMapNumUsedRecords;
661 VersionedCovMapFuncRecordReader(
663 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, StringRef
D,
664 std::vector<std::string> &
F)
665 : ProfileNames(
P), CompilationDir(
D), Filenames(
F),
Records(
R) {}
667 ~VersionedCovMapFuncRecordReader()
override =
default;
669 Expected<const char *> readCoverageHeader(
const char *CovBuf,
670 const char *CovBufEnd)
override {
671 using namespace support;
673 if (CovBuf +
sizeof(CovMapHeader) > CovBufEnd)
675 coveragemap_error::malformed,
676 "coverage mapping header section is larger than buffer size");
677 auto CovHeader =
reinterpret_cast<const CovMapHeader *
>(CovBuf);
678 uint32_t
NRecords = CovHeader->getNRecords<Endian>();
679 uint32_t
FilenamesSize = CovHeader->getFilenamesSize<Endian>();
680 uint32_t
CoverageSize = CovHeader->getCoverageSize<Endian>();
682 CovBuf =
reinterpret_cast<const char *
>(CovHeader + 1);
687 const char *FuncRecBuf =
nullptr;
688 const char *FuncRecBufEnd =
nullptr;
689 if (
Version < CovMapVersion::Version4)
691 CovBuf +=
NRecords *
sizeof(FuncRecordType);
692 if (
Version < CovMapVersion::Version4)
693 FuncRecBufEnd = CovBuf;
698 coveragemap_error::malformed,
699 "filenames section is larger than buffer size");
700 size_t FilenamesBegin = Filenames.size();
702 RawCoverageFilenamesReader Reader(FilenameRegion, Filenames,
704 if (
auto Err = Reader.read(
Version))
705 return std::move(Err);
707 FilenameRange FileRange(FilenamesBegin, Filenames.size() - FilenamesBegin);
709 if (
Version >= CovMapVersion::Version4) {
712 int64_t FilenamesRef =
715 FileRangeMap.
insert(std::make_pair(FilenamesRef, FileRange));
719 auto It = Filenames.begin();
720 FilenameRange &OrigRange =
Insert.first->getSecond();
726 FileRange = OrigRange;
736 const char *MappingBuf = CovBuf;
739 "coverage mapping size is not zero");
741 const char *MappingEnd = CovBuf;
743 if (CovBuf > CovBufEnd)
745 coveragemap_error::malformed,
746 "function records section is larger than buffer size");
748 if (
Version < CovMapVersion::Version4) {
750 if (
Error E = readFunctionRecords(FuncRecBuf, FuncRecBufEnd, FileRange,
751 MappingBuf, MappingEnd))
762 Error readFunctionRecords(
const char *FuncRecBuf,
const char *FuncRecBufEnd,
763 std::optional<FilenameRange> OutOfLineFileRange,
764 const char *OutOfLineMappingBuf,
765 const char *OutOfLineMappingBufEnd)
override {
766 auto CFR =
reinterpret_cast<const FuncRecordType *
>(FuncRecBuf);
767 while ((
const char *)CFR < FuncRecBufEnd) {
769 const char *NextMappingBuf;
770 const FuncRecordType *NextCFR;
771 std::tie(NextMappingBuf, NextCFR) =
772 CFR->template advanceByOne<Endian>(OutOfLineMappingBuf);
773 if (
Version < CovMapVersion::Version4)
774 if (NextMappingBuf > OutOfLineMappingBufEnd)
776 coveragemap_error::malformed,
777 "next mapping buffer is larger than buffer size");
780 std::optional<FilenameRange> FileRange;
781 if (
Version < CovMapVersion::Version4) {
782 FileRange = OutOfLineFileRange;
784 uint64_t FilenamesRef = CFR->template getFilenamesRef<Endian>();
785 auto It = FileRangeMap.
find(FilenamesRef);
786 if (It == FileRangeMap.
end())
788 coveragemap_error::malformed,
789 "no filename found for function with hash=0x" +
792 FileRange = It->getSecond();
796 if (FileRange && !FileRange->isInvalid()) {
798 CFR->template getCoverageMapping<Endian>(OutOfLineMappingBuf);
799 if (
Version >= CovMapVersion::Version4 &&
800 Mapping.
data() + Mapping.
size() > FuncRecBufEnd)
802 coveragemap_error::malformed,
803 "coverage mapping data is larger than buffer size");
804 if (
Error Err = insertFunctionRecordIfNeeded(CFR, Mapping, *FileRange))
808 std::tie(OutOfLineMappingBuf, CFR) = std::tie(NextMappingBuf, NextCFR);
816template <
class IntPtrT, llvm::endianness Endian>
817Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get(
819 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, StringRef
D,
820 std::vector<std::string> &
F) {
821 using namespace coverage;
825 return std::make_unique<VersionedCovMapFuncRecordReader<
834 if (
Error E =
P.create(
P.getNameData()))
837 return std::make_unique<VersionedCovMapFuncRecordReader<
840 return std::make_unique<VersionedCovMapFuncRecordReader<
843 return std::make_unique<VersionedCovMapFuncRecordReader<
846 return std::make_unique<VersionedCovMapFuncRecordReader<
849 return std::make_unique<VersionedCovMapFuncRecordReader<
852 return std::make_unique<VersionedCovMapFuncRecordReader<
858template <
typename T, llvm::endianness Endian>
861 std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
862 StringRef CompilationDir, std::vector<std::string> &Filenames) {
872 CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames, Records,
873 CompilationDir, Filenames);
876 auto Reader = std::move(ReaderExpected.
get());
877 const char *CovBuf = CovMap.
data();
878 const char *CovBufEnd = CovBuf + CovMap.
size();
879 const char *FuncRecBuf = FuncRecords.
data();
880 const char *FuncRecBufEnd = FuncRecords.
data() + FuncRecords.
size();
881 while (CovBuf < CovBufEnd) {
888 auto NextOrErr = Reader->readCoverageHeader(CovBuf, CovBufEnd);
889 if (
auto E = NextOrErr.takeError())
891 CovBuf = NextOrErr.get();
896 return Reader->readFunctionRecords(FuncRecBuf, FuncRecBufEnd, std::nullopt,
901Expected<std::unique_ptr<BinaryCoverageReader>>
905 std::unique_ptr<InstrProfSymtab> ProfileNamesPtr,
uint8_t BytesInAddress,
907 if (ProfileNamesPtr ==
nullptr)
909 "Caller must provide ProfileNames");
910 std::unique_ptr<BinaryCoverageReader> Reader(
911 new BinaryCoverageReader(std::move(ProfileNamesPtr),
912 std::move(FuncRecords), std::move(CoverageMap)));
914 StringRef FuncRecordsRef = Reader->FuncRecords->getBuffer();
917 ProfileNames, Coverage, FuncRecordsRef, Reader->MappingRecords,
918 CompilationDir, Reader->Filenames))
922 ProfileNames, Coverage, FuncRecordsRef, Reader->MappingRecords,
923 CompilationDir, Reader->Filenames))
927 ProfileNames, Coverage, FuncRecordsRef, Reader->MappingRecords,
928 CompilationDir, Reader->Filenames))
932 ProfileNames, Coverage, FuncRecordsRef, Reader->MappingRecords,
933 CompilationDir, Reader->Filenames))
938 "not supported endianness or bytes in address");
939 return std::move(Reader);
951 "the size of data is too small");
952 auto TestingVersion =
965 "the size of TestingFormatMagic is too big");
973 "the size of ULEB128 is too big");
975 if (
Data.size() < ProfileNamesSize)
977 "the size of ProfileNames is too big");
978 auto ProfileNames = std::make_unique<InstrProfSymtab>();
979 if (
Error E = ProfileNames->
create(
Data.substr(0, ProfileNamesSize), Address))
981 Data =
Data.substr(ProfileNamesSize);
990 "the size of ULEB128 is too big");
995 "the size of CoverageMapping is teoo small");
1002 if (
Data.size() < Pad)
1004 "insufficient padding");
1009 "coverage mapping header section is larger than data size");
1010 auto const *CovHeader =
reinterpret_cast<const CovMapHeader *
>(
1018 CoverageMappingSize =
Data.size();
1027 Data =
Data.substr(CoverageMappingSize);
1033 "data is not empty");
1038 if (
Data.size() < Pad)
1040 "insufficient padding");
1048 std::move(ProfileNames), BytesInAddress, Endian, CompilationDir);
1053static Expected<std::vector<SectionRef>>
1055 auto ObjFormat = OF.getTripleObjectFormat();
1063 return IsCOFF ?
N.split(
'$').first :
N;
1065 Name = stripSuffix(Name);
1067 std::vector<SectionRef> Sections;
1068 for (
const auto &Section : OF.sections()) {
1072 if (stripSuffix(*NameOrErr) == Name) {
1076 if (IPSK == IPSK_name &&
1077 (Section.getSize() == 0 || (IsCOFF && Section.getSize() == 2)))
1079 Sections.push_back(Section);
1082 if (Sections.empty())
1090static Expected<std::pair<StringRef, uint64_t>>
1094 std::vector<const WasmSegment *> Segments;
1095 auto ObjFormat = OF.getTripleObjectFormat();
1098 for (
const auto &DebugName : WOF->debugNames()) {
1100 DebugName.Name != Name)
1102 if (DebugName.Index >= WOF->dataSegments().size())
1104 auto &Segment = WOF->dataSegments()[DebugName.Index];
1105 Segments.push_back(&Segment);
1107 if (Segments.empty())
1109 if (Segments.size() != 1)
1112 const auto &Segment = *Segments.front();
1113 auto &
Data = Segment.Data;
1114 StringRef Content(
reinterpret_cast<const char *
>(
Data.Content.data()),
1115 Data.Content.size());
1116 return std::make_pair(Content, Segment.SectionOffset);
1122 return Sections.takeError();
1123 if (Sections->size() != 1)
1126 "the size of coverage mapping section is not one");
1127 auto &Section = Sections->front();
1128 auto ContentsOrErr = Section.getContents();
1130 return ContentsOrErr.takeError();
1131 auto Content = *ContentsOrErr;
1133 Content = Content.drop_front(1);
1134 return std::make_pair(Content, Section.getAddress());
1137static Expected<std::unique_ptr<BinaryCoverageReader>>
1141 std::unique_ptr<ObjectFile> OF;
1145 auto ObjectFileOrErr = Universal->getMachOObjectForArch(Arch);
1146 if (!ObjectFileOrErr)
1147 return ObjectFileOrErr.takeError();
1148 OF = std::move(ObjectFileOrErr.get());
1153 if (!Arch.
empty() && OF->getArch() !=
Triple(Arch).getArch())
1158 "binary is not an object file");
1161 uint8_t BytesInAddress = OF->getBytesInAddress();
1166 auto ProfileNames = std::make_unique<InstrProfSymtab>();
1170 if (
auto E = NamesSection.takeError()) {
1173 if (
auto E = NamesSection.takeError())
1174 return std::move(
E);
1179 std::tie(NamesContent, NamesAddress) = *NamesSection;
1180 if (
Error E = ProfileNames->
create(NamesContent, NamesAddress))
1181 return std::move(
E);
1184 if (
auto E = CoverageSection.takeError())
1185 return std::move(
E);
1186 std::vector<SectionRef> CoverageSectionRefs = *CoverageSection;
1187 if (CoverageSectionRefs.size() != 1)
1189 "the size of name section is not one");
1190 auto CoverageMappingOrErr = CoverageSectionRefs.back().getContents();
1191 if (!CoverageMappingOrErr)
1192 return CoverageMappingOrErr.takeError();
1198 std::unique_ptr<MemoryBuffer> CoverageMapCopy;
1208 if (
auto E = CoverageRecordsSections.takeError()) {
1216 const Align RecordAlignment(8);
1218 for (
SectionRef Section : *CoverageRecordsSections) {
1219 auto CoverageRecordsOrErr = Section.getContents();
1220 if (!CoverageRecordsOrErr)
1221 return CoverageRecordsOrErr.takeError();
1222 FuncRecordsSize +=
alignTo(CoverageRecordsOrErr->size(), RecordAlignment);
1224 auto WritableBuffer =
1226 char *FuncRecordsBuffer = WritableBuffer->getBufferStart();
1228 "Allocated memory is correctly aligned");
1230 for (
SectionRef Section : *CoverageRecordsSections) {
1231 auto CoverageRecordsOrErr = Section.getContents();
1232 if (!CoverageRecordsOrErr)
1233 return CoverageRecordsOrErr.takeError();
1234 const auto &CoverageRecords = CoverageRecordsOrErr.get();
1235 FuncRecordsBuffer = std::copy(CoverageRecords.begin(),
1236 CoverageRecords.end(), FuncRecordsBuffer);
1238 std::fill_n(FuncRecordsBuffer,
1239 alignAddr(FuncRecordsBuffer, RecordAlignment) -
1240 (uintptr_t)FuncRecordsBuffer,
1243 assert(FuncRecordsBuffer == WritableBuffer->getBufferEnd() &&
1245 FuncRecords = std::move(WritableBuffer);
1253 std::move(ProfileNames), BytesInAddress, Endian, CompilationDir);
1261 for (
auto &ObjForArch : Universal->objects())
1262 if (Arch == ObjForArch.getArchFlagName())
1269Expected<std::vector<std::unique_ptr<BinaryCoverageReader>>>
1274 std::vector<std::unique_ptr<BinaryCoverageReader>> Readers;
1285 return ReaderOrErr.takeError();
1286 Readers.push_back(std::move(ReaderOrErr.get()));
1287 return std::move(Readers);
1293 return BinOrErr.takeError();
1294 std::unique_ptr<Binary>
Bin = std::move(BinOrErr.get());
1303 for (
auto &ObjForArch : Universal->objects()) {
1305 std::string ObjArch = ObjForArch.getArchFlagName();
1306 if (Arch != ObjArch)
1309 auto ArchiveOrErr = ObjForArch.getAsArchive();
1310 if (!ArchiveOrErr) {
1317 ArchiveOrErr.get()->getMemoryBufferRef(), Arch, ObjectFileBuffers,
1318 CompilationDir, BinaryIDs);
1325 for (
auto &Child : Ar->children(Err)) {
1331 ChildBufOrErr.
get(), Arch, ObjectFileBuffers, CompilationDir,
1333 if (!ChildReadersOrErr)
1334 return ChildReadersOrErr.takeError();
1335 for (
auto &Reader : ChildReadersOrErr.get())
1336 Readers.push_back(std::move(Reader));
1339 return std::move(Err);
1345 for (
auto &Buffer : Ar->takeThinBuffers())
1346 ObjectFileBuffers.push_back(std::move(Buffer));
1348 return std::move(Readers);
1353 BinaryIDs ? &BinaryID :
nullptr);
1355 return ReaderOrErr.takeError();
1356 Readers.push_back(std::move(ReaderOrErr.get()));
1357 if (!BinaryID.
empty())
1359 return std::move(Readers);
1363 if (CurrentRecord >= MappingRecords.size())
1366 FunctionsFilenames.clear();
1367 Expressions.clear();
1368 MappingRegions.clear();
1369 auto &R = MappingRecords[CurrentRecord];
1370 auto F =
ArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize);
1372 Expressions, MappingRegions);
1373 if (
auto Err = Reader.
read())
1376 Record.FunctionName = R.FunctionName;
1377 Record.FunctionHash = R.FunctionHash;
1378 Record.Filenames = FunctionsFilenames;
1379 Record.Expressions = Expressions;
1380 Record.MappingRegions = MappingRegions;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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::pair< StringRef, uint64_t > > lookupAllocatableSection(ObjectFile &OF, InstrProfSectKind IPSK)
Find a section that matches Name and is allocatable at runtime.
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 Expected< std::vector< SectionRef > > lookupSections(ObjectFile &OF, InstrProfSectKind IPSK)
Find all sections that match IPSK name.
static bool isArchSpecifierInvalidOrMissing(Binary *Bin, StringRef Arch)
Determine whether Arch is invalid or empty, given Bin.
static bool shouldSkipSectionFirstByte(SectionRef &Section)
Determine if we should skip the first byte of the section content.
static Expected< bool > isCoverageMappingDummy(uint64_t Hash, StringRef Mapping)
static const unsigned EncodingExpansionRegionBit
This file defines the DenseMap class.
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)
bool empty() const
empty - Check if the array is empty.
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 [IR]PGO name look-up with keys (such as pointers,...
LLVM_ABI StringRef getFuncName(uint64_t FuncNameAddress, size_t NameSize) const
Return function's PGO name from the function name's symbol address in the object file.
LLVM_ABI Error create(object::SectionRef &Section)
Create InstrProfSymtab from an object file section which contains function PGO names.
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.
static std::unique_ptr< MemoryBuffer > getMemBufferCopy(StringRef InputData, const Twine &BufferName="")
Open the specified memory range as a MemoryBuffer, copying the contents and taking ownership of it.
Pass interface - Implemented by all 'passes'.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
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 bool empty() const
empty - Check if the string is empty.
constexpr size_t size() const
size - Get the string size.
constexpr 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)
static LLVM_ABI 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.
static Expected< std::unique_ptr< BinaryCoverageReader > > createCoverageReaderFromBuffer(StringRef Coverage, FuncRecordsStorage &&FuncRecords, CoverageMapCopyStorage &&CoverageMap, std::unique_ptr< InstrProfSymtab > ProfileNamesPtr, uint8_t BytesInAddress, llvm::endianness Endian, StringRef CompilationDir="")
std::unique_ptr< MemoryBuffer > CoverageMapCopyStorage
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
A Counter mapping context is used to connect the counters, expressions and the obtained counter value...
LLVM_ABI void dump(const Counter &C, raw_ostream &OS) const
coveragemap_error get() const
CoverageMappingIterator()
virtual Error readNextRecord(CoverageMappingRecord &Record)=0
The mapping of profile information to coverage data.
RawCoverageFilenamesReader(StringRef Data, std::vector< std::string > &Filenames, StringRef CompilationDir="")
LLVM_ABI Error read(CovMapVersion Version)
Checks if the given coverage mapping data is exported for an unused function.
LLVM_ABI Expected< bool > isDummy()
Reader for the raw coverage mapping data.
LLVM_ABI Error readSize(uint64_t &Result)
LLVM_ABI Error readIntMax(uint64_t &Result, uint64_t MaxPlus1)
LLVM_ABI Error readULEB128(uint64_t &Result)
LLVM_ABI Error readString(StringRef &Result)
This class is the base class for all object file types.
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.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
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)
llvm::SmallVector< std::shared_ptr< RecordsSlice >, 4 > Records
LLVM_ABI Error decompress(ArrayRef< uint8_t > Input, uint8_t *Output, size_t &UncompressedSize)
LLVM_ABI bool isAvailable()
std::variant< std::monostate, DecisionParameters, BranchParameters > Parameters
The type of MC/DC-specific parameters.
@ invalid_or_missing_arch_specifier
constexpr uint64_t TestingFormatMagic
LLVM_ABI BuildIDRef getBuildID(const ObjectFile *Obj)
Returns the build ID, if any, contained in the given object file.
ArrayRef< uint8_t > BuildIDRef
A reference to a BuildID in binary form.
LLVM_ABI Expected< std::unique_ptr< Binary > > createBinary(MemoryBufferRef Source, LLVMContext *Context=nullptr, bool InitContent=true)
Create a Binary from Source, autodetecting the file type.
value_type byte_swap(value_type value, endianness endian)
LLVM_ABI bool remove_dots(SmallVectorImpl< char > &path, bool remove_dot_dot=false, Style style=Style::native)
In-place remove any '.
LLVM_ABI bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
LLVM_ABI 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.
FunctionAddr VTableAddr Value
ArrayRef< CharT > arrayRefFromStringRef(StringRef Input)
Construct a string ref from an array ref of unsigned chars.
FunctionAddr VTableAddr uintptr_t uintptr_t FilenamesSize
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
FunctionAddr VTableAddr uintptr_t uintptr_t CoverageSize
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.
LLVM_ABI std::string getInstrProfSectionName(InstrProfSectKind IPSK, Triple::ObjectFormatType OF, bool AddSegmentInfo=true)
Return the name of the profile section corresponding to IPSK.
FunctionAddr VTableAddr uintptr_t uintptr_t Version
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
FunctionAddr VTableAddr uintptr_t uintptr_t NRecords
void consumeError(Error Err)
Consume a Error without doing anything.
StringRef toStringRef(bool B)
Construct a string ref from a boolean.
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.
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...
@ MCDCDecisionRegion
A DecisionRegion represents a top-level boolean expression and is associated with a variable length b...
@ MCDCBranchRegion
A Branch Region can be extended to include IDs to facilitate MC/DC.
@ 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.
CovMapFunctionRecordV3 CovMapFuncRecordType
Coverage mapping information for a single function.