43using namespace coverage;
44using namespace object;
46#define DEBUG_TYPE "coverage-mapping"
48STATISTIC(CovMapNumRecords,
"The # of coverage function records");
49STATISTIC(CovMapNumUsedRecords,
"The # of used coverage function records");
51void CoverageMappingIterator::increment() {
73 "the size of ULEB128 is too big");
81 if (Result >= MaxPlus1)
82 return make_error<CoverageMapError>(
84 "the value of ULEB128 is greater than or equal to MaxPlus1");
93 "the value of ULEB128 is too big");
108 if (
auto Err =
readSize(NumFilenames))
112 "number of filenames is zero");
115 return readUncompressed(Version, NumFilenames);
124 if (
auto Err =
readSize(CompressedLen))
127 if (CompressedLen > 0) {
129 return make_error<CoverageMapError>(
139 arrayRefFromStringRef(CompressedFilenames), StorageBuf,
143 return make_error<CoverageMapError>(
149 return Delegate.readUncompressed(Version, NumFilenames);
152 return readUncompressed(Version, NumFilenames);
159 for (
size_t I = 0;
I < NumFilenames; ++
I) {
163 Filenames.push_back(Filename.str());
169 Filenames.push_back(CWD.
str());
171 for (
size_t I = 1;
I < NumFilenames; ++
I) {
176 Filenames.push_back(Filename.str());
179 if (!CompilationDir.
empty())
180 P.assign(CompilationDir);
185 Filenames.push_back(
static_cast<std::string
>(
P.str()));
209 if (
ID >= Expressions.size())
211 "counter expression is invalid");
218 "counter expression kind is invalid");
226 readIntMax(EncodedCounter, std::numeric_limits<unsigned>::max()))
228 if (
auto Err = decodeCounter(EncodedCounter,
C))
239Error RawCoverageMappingReader::readMappingRegionsSubArray(
240 std::vector<CounterMappingRegion> &MappingRegions,
unsigned InferredFileID,
243 if (
auto Err =
readSize(NumRegions))
245 unsigned LineStart = 0;
246 for (
size_t I = 0;
I < NumRegions; ++
I) {
252 if (
auto Err =
readIntMax(EncodedCounterAndRegion,
253 std::numeric_limits<unsigned>::max()))
270 if (
auto Err = decodeCounter(EncodedCounterAndRegion,
C))
276 ExpandedFileID = EncodedCounterAndRegion >>
278 if (ExpandedFileID >= NumFileIDs)
280 "ExpandedFileID is invalid");
282 switch (EncodedCounterAndRegion >>
293 if (
auto Err = readCounter(
C))
295 if (
auto Err = readCounter(C2))
300 "region kind is incorrect");
306 uint64_t LineStartDelta, ColumnStart, NumLines, ColumnEnd;
308 readIntMax(LineStartDelta, std::numeric_limits<unsigned>::max()))
312 if (ColumnStart > std::numeric_limits<unsigned>::max())
314 "start column is too big");
315 if (
auto Err =
readIntMax(NumLines, std::numeric_limits<unsigned>::max()))
317 if (
auto Err =
readIntMax(ColumnEnd, std::numeric_limits<unsigned>::max()))
319 LineStart += LineStartDelta;
322 if (ColumnEnd & (1U << 31)) {
324 ColumnEnd &= ~(1U << 31);
335 if (ColumnStart == 0 && ColumnEnd == 0) {
337 ColumnEnd = std::numeric_limits<unsigned>::max();
341 dbgs() <<
"Counter in file " << InferredFileID <<
" " << LineStart <<
":"
342 << ColumnStart <<
" -> " << (LineStart + NumLines) <<
":"
343 << ColumnEnd <<
", ";
345 dbgs() <<
"Expands to file " << ExpandedFileID;
352 LineStart, ColumnStart,
353 LineStart + NumLines, ColumnEnd,
Kind);
354 if (CMR.startLoc() > CMR.endLoc())
355 return make_error<CoverageMapError>(
357 "counter mapping region locations are incorrect");
358 MappingRegions.push_back(CMR);
367 if (
auto Err =
readSize(NumFileMappings))
369 for (
size_t I = 0;
I < NumFileMappings; ++
I) {
371 if (
auto Err =
readIntMax(FilenameIndex, TranslationUnitFilenames.
size()))
373 VirtualFileMapping.
push_back(FilenameIndex);
377 for (
auto I : VirtualFileMapping) {
378 Filenames.push_back(TranslationUnitFilenames[
I]);
383 if (
auto Err =
readSize(NumExpressions))
391 for (
size_t I = 0;
I < NumExpressions; ++
I) {
392 if (
auto Err = readCounter(Expressions[
I].
LHS))
394 if (
auto Err = readCounter(Expressions[
I].
RHS))
399 for (
unsigned InferredFileID = 0, S = VirtualFileMapping.
size();
400 InferredFileID < S; ++InferredFileID) {
401 if (
auto Err = readMappingRegionsSubArray(MappingRegions, InferredFileID,
402 VirtualFileMapping.
size()))
412 FileIDExpansionRegionMapping.
resize(VirtualFileMapping.
size(),
nullptr);
414 for (
auto &R : MappingRegions) {
417 assert(!FileIDExpansionRegionMapping[R.ExpandedFileID]);
418 FileIDExpansionRegionMapping[R.ExpandedFileID] = &R;
420 for (
auto &R : MappingRegions) {
421 if (FileIDExpansionRegionMapping[R.FileID]) {
422 FileIDExpansionRegionMapping[R.FileID]->Count = R.Count;
423 FileIDExpansionRegionMapping[R.FileID] =
nullptr;
435 return std::move(Err);
436 if (NumFileMappings != 1)
441 readIntMax(FilenameIndex, std::numeric_limits<unsigned>::max()))
442 return std::move(Err);
445 return std::move(Err);
446 if (NumExpressions != 0)
450 return std::move(Err);
455 std::numeric_limits<unsigned>::max()))
456 return std::move(Err);
466 Address = Section.getAddress();
510struct CovMapFuncRecordReader {
511 virtual ~CovMapFuncRecordReader() =
default;
521 const char *CovBufEnd) = 0;
534 readFunctionRecords(
const char *FuncRecBuf,
const char *FuncRecBufEnd,
535 std::optional<FilenameRange> OutOfLineFileRange,
536 const char *OutOfLineMappingBuf,
537 const char *OutOfLineMappingBufEnd) = 0;
539 template <
class IntPtrT, support::endianness Endian>
542 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
StringRef D,
543 std::vector<std::string> &
F);
547template <CovMapVersion Version,
class IntPtrT, support::endianness Endian>
548class VersionedCovMapFuncRecordReader :
public CovMapFuncRecordReader {
549 using FuncRecordType =
558 std::vector<std::string> &Filenames;
559 std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records;
571 Error insertFunctionRecordIfNeeded(
const FuncRecordType *CFR,
575 uint64_t FuncHash = CFR->template getFuncHash<Endian>();
576 NameRefType NameRef = CFR->template getFuncNameRef<Endian>();
578 FunctionRecords.
insert(std::make_pair(NameRef, Records.size()));
579 if (InsertResult.second) {
581 if (
Error Err = CFR->template getFuncName<Endian>(ProfileNames, FuncName))
583 if (FuncName.
empty())
584 return make_error<InstrProfError>(instrprof_error::malformed,
585 "function name is empty");
586 ++CovMapNumUsedRecords;
587 Records.emplace_back(Version, FuncName, FuncHash, Mapping,
592 size_t OldRecordIndex = InsertResult.first->second;
594 Records[OldRecordIndex];
599 if (!*OldIsDummyExpected)
605 if (*NewIsDummyExpected)
607 ++CovMapNumUsedRecords;
616 VersionedCovMapFuncRecordReader(
618 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
StringRef D,
619 std::vector<std::string> &
F)
620 : ProfileNames(
P), CompilationDir(
D), Filenames(
F), Records(
R) {}
622 ~VersionedCovMapFuncRecordReader()
override =
default;
625 const char *CovBufEnd)
override {
626 using namespace support;
629 return make_error<CoverageMapError>(
630 coveragemap_error::malformed,
631 "coverage mapping header section is larger than buffer size");
632 auto CovHeader =
reinterpret_cast<const CovMapHeader *
>(CovBuf);
637 CovBuf =
reinterpret_cast<const char *
>(CovHeader + 1);
642 const char *FuncRecBuf =
nullptr;
643 const char *FuncRecBufEnd =
nullptr;
644 if (Version < CovMapVersion::Version4)
646 CovBuf += NRecords *
sizeof(FuncRecordType);
647 if (Version < CovMapVersion::Version4)
648 FuncRecBufEnd = CovBuf;
651 if (CovBuf + FilenamesSize > CovBufEnd)
652 return make_error<CoverageMapError>(
653 coveragemap_error::malformed,
654 "filenames section is larger than buffer size");
655 size_t FilenamesBegin = Filenames.size();
656 StringRef FilenameRegion(CovBuf, FilenamesSize);
659 if (
auto Err = Reader.read(Version))
660 return std::move(Err);
661 CovBuf += FilenamesSize;
662 FilenameRange FileRange(FilenamesBegin, Filenames.size() - FilenamesBegin);
664 if (Version >= CovMapVersion::Version4) {
667 int64_t FilenamesRef =
670 FileRangeMap.
insert(std::make_pair(FilenamesRef, FileRange));
674 auto It = Filenames.begin();
681 FileRange = OrigRange;
691 const char *MappingBuf = CovBuf;
692 if (Version >= CovMapVersion::Version4 && CoverageSize != 0)
693 return make_error<CoverageMapError>(coveragemap_error::malformed,
694 "coverage mapping size is not zero");
695 CovBuf += CoverageSize;
696 const char *MappingEnd = CovBuf;
698 if (CovBuf > CovBufEnd)
699 return make_error<CoverageMapError>(
700 coveragemap_error::malformed,
701 "function records section is larger than buffer size");
703 if (Version < CovMapVersion::Version4) {
705 if (
Error E = readFunctionRecords(FuncRecBuf, FuncRecBufEnd, FileRange,
706 MappingBuf, MappingEnd))
717 Error readFunctionRecords(
const char *FuncRecBuf,
const char *FuncRecBufEnd,
718 std::optional<FilenameRange> OutOfLineFileRange,
719 const char *OutOfLineMappingBuf,
720 const char *OutOfLineMappingBufEnd)
override {
721 auto CFR =
reinterpret_cast<const FuncRecordType *
>(FuncRecBuf);
722 while ((
const char *)CFR < FuncRecBufEnd) {
724 const char *NextMappingBuf;
725 const FuncRecordType *NextCFR;
726 std::tie(NextMappingBuf, NextCFR) =
727 CFR->template advanceByOne<Endian>(OutOfLineMappingBuf);
728 if (Version < CovMapVersion::Version4)
729 if (NextMappingBuf > OutOfLineMappingBufEnd)
730 return make_error<CoverageMapError>(
731 coveragemap_error::malformed,
732 "next mapping buffer is larger than buffer size");
735 std::optional<FilenameRange> FileRange;
736 if (Version < CovMapVersion::Version4) {
737 FileRange = OutOfLineFileRange;
739 uint64_t FilenamesRef = CFR->template getFilenamesRef<Endian>();
740 auto It = FileRangeMap.
find(FilenamesRef);
741 if (It == FileRangeMap.
end())
742 return make_error<CoverageMapError>(
743 coveragemap_error::malformed,
744 "no filename found for function with hash=0x" +
747 FileRange = It->getSecond();
751 if (FileRange && !FileRange->isInvalid()) {
753 CFR->template getCoverageMapping<Endian>(OutOfLineMappingBuf);
754 if (Version >= CovMapVersion::Version4 &&
755 Mapping.
data() + Mapping.
size() > FuncRecBufEnd)
756 return make_error<CoverageMapError>(
757 coveragemap_error::malformed,
758 "coverage mapping data is larger than buffer size");
759 if (
Error Err = insertFunctionRecordIfNeeded(CFR, Mapping, *FileRange))
763 std::tie(OutOfLineMappingBuf, CFR) = std::tie(NextMappingBuf, NextCFR);
771template <
class IntPtrT, support::endianness Endian>
774 std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
StringRef D,
775 std::vector<std::string> &
F) {
776 using namespace coverage;
780 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<
809template <
typename T, support::endianness Endian>
812 std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
813 StringRef CompilationDir, std::vector<std::string> &Filenames) {
814 using namespace coverage;
823 CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames, Records,
824 CompilationDir, Filenames);
827 auto Reader = std::move(ReaderExpected.
get());
828 const char *CovBuf = CovMap.
data();
829 const char *CovBufEnd = CovBuf + CovMap.
size();
830 const char *FuncRecBuf = FuncRecords.
data();
831 const char *FuncRecBufEnd = FuncRecords.
data() + FuncRecords.
size();
832 while (CovBuf < CovBufEnd) {
839 auto NextOrErr = Reader->readCoverageHeader(CovBuf, CovBufEnd);
840 if (
auto E = NextOrErr.takeError())
842 CovBuf = NextOrErr.get();
847 return Reader->readFunctionRecords(FuncRecBuf, FuncRecBufEnd, std::nullopt,
857 std::unique_ptr<BinaryCoverageReader> Reader(
859 Reader->ProfileNames = std::move(ProfileNames);
860 StringRef FuncRecordsRef = Reader->FuncRecords->getBuffer();
861 if (BytesInAddress == 4 &&
Endian == support::endianness::little) {
863 readCoverageMappingData<uint32_t, support::endianness::little>(
864 Reader->ProfileNames, Coverage, FuncRecordsRef,
865 Reader->MappingRecords, CompilationDir, Reader->Filenames))
867 }
else if (BytesInAddress == 4 &&
Endian == support::endianness::big) {
868 if (
Error E = readCoverageMappingData<uint32_t, support::endianness::big>(
869 Reader->ProfileNames, Coverage, FuncRecordsRef,
870 Reader->MappingRecords, CompilationDir, Reader->Filenames))
872 }
else if (BytesInAddress == 8 &&
Endian == support::endianness::little) {
874 readCoverageMappingData<uint64_t, support::endianness::little>(
875 Reader->ProfileNames, Coverage, FuncRecordsRef,
876 Reader->MappingRecords, CompilationDir, Reader->Filenames))
878 }
else if (BytesInAddress == 8 &&
Endian == support::endianness::big) {
879 if (
Error E = readCoverageMappingData<uint64_t, support::endianness::big>(
880 Reader->ProfileNames, Coverage, FuncRecordsRef,
881 Reader->MappingRecords, CompilationDir, Reader->Filenames))
884 return make_error<CoverageMapError>(
886 "not supported endianness or bytes in address");
887 return std::move(Reader);
892 uint8_t BytesInAddress = 8;
899 "the size of data is too small");
900 auto TestingVersion =
901 support::endian::byte_swap<uint64_t, support::endianness::little>(
911 return make_error<CoverageMapError>(
913 "the size of TestingFormatMagic is too big");
921 "the size of ULEB128 is too big");
923 if (
Data.size() < ProfileNamesSize)
925 "the size of ProfileNames is too big");
929 Data =
Data.substr(ProfileNamesSize);
938 "the size of ULEB128 is too big");
941 return make_error<CoverageMapError>(
943 "the size of CoverageMapping is teoo small");
950 if (
Data.size() < Pad)
952 "insufficient padding");
955 return make_error<CoverageMapError>(
957 "coverage mapping header section is larger than data size");
958 auto const *CovHeader =
reinterpret_cast<const CovMapHeader *
>(
961 CovMapVersion(CovHeader->getVersion<support::endianness::little>());
966 CoverageMappingSize =
Data.size();
969 CovHeader->getFilenamesSize<support::endianness::little>();
970 CoverageMappingSize =
sizeof(
CovMapHeader) + FilenamesSize;
975 Data =
Data.substr(CoverageMappingSize);
981 "data is not empty");
986 if (
Data.size() < Pad)
988 "insufficient padding");
996 BytesInAddress,
Endian, CompilationDir);
1006 bool IsCOFF = isa<COFFObjectFile>(OF);
1008 return IsCOFF ?
N.split(
'$').first :
N;
1012 std::vector<SectionRef> Sections;
1013 for (
const auto &Section : OF.
sections()) {
1017 if (stripSuffix(*NameOrErr) ==
Name)
1018 Sections.push_back(Section);
1020 if (Sections.empty())
1027 std::unique_ptr<InstrProfCorrelator> Correlator;
1030 if (
auto E = Correlator->correlateCovUnusedFuncNames(0))
1032 if (
auto E = ProfileNames.
create(
1033 StringRef(Correlator->getCovUnusedFuncNamesPointer(),
1034 Correlator->getCovUnusedFuncNamesSize())))
1043 std::unique_ptr<ObjectFile> OF;
1044 if (
auto *Universal = dyn_cast<MachOUniversalBinary>(
Bin.get())) {
1047 auto ObjectFileOrErr = Universal->getMachOObjectForArch(Arch);
1048 if (!ObjectFileOrErr)
1049 return ObjectFileOrErr.takeError();
1050 OF = std::move(ObjectFileOrErr.get());
1051 }
else if (isa<ObjectFile>(
Bin.get())) {
1053 OF.reset(cast<ObjectFile>(
Bin.release()));
1055 if (!Arch.
empty() && OF->getArch() !=
Triple(Arch).getArch())
1060 "binary is not an object file");
1063 uint8_t BytesInAddress = OF->getBytesInAddress();
1065 ? support::endianness::little
1066 : support::endianness::big;
1069 auto ObjFormat = OF->getTripleObjectFormat();
1079 if (
auto E = NamesSection.takeError()) {
1080 if (OF->hasDebugInfo()) {
1087 std::vector<SectionRef> NamesSectionRefs = *NamesSection;
1088 if (NamesSectionRefs.size() != 1)
1090 if (
Error E = ProfileNames.
create(NamesSectionRefs.back()))
1091 return std::move(
E);
1094 auto CoverageSection =
1097 if (
auto E = CoverageSection.takeError())
1098 return std::move(
E);
1099 std::vector<SectionRef> CoverageSectionRefs = *CoverageSection;
1100 if (CoverageSectionRefs.size() != 1)
1102 "the size of name section is not one");
1103 auto CoverageMappingOrErr = CoverageSectionRefs.back().getContents();
1104 if (!CoverageMappingOrErr)
1105 return CoverageMappingOrErr.takeError();
1109 auto CoverageRecordsSections =
1114 if (
auto E = CoverageRecordsSections.takeError()) {
1122 const Align RecordAlignment(8);
1124 for (
SectionRef Section : *CoverageRecordsSections) {
1125 auto CoverageRecordsOrErr = Section.getContents();
1126 if (!CoverageRecordsOrErr)
1127 return CoverageRecordsOrErr.takeError();
1128 FuncRecordsSize +=
alignTo(CoverageRecordsOrErr->size(), RecordAlignment);
1130 auto WritableBuffer =
1132 char *FuncRecordsBuffer = WritableBuffer->getBufferStart();
1134 "Allocated memory is correctly aligned");
1136 for (
SectionRef Section : *CoverageRecordsSections) {
1137 auto CoverageRecordsOrErr = Section.getContents();
1138 if (!CoverageRecordsOrErr)
1139 return CoverageRecordsOrErr.takeError();
1140 const auto &CoverageRecords = CoverageRecordsOrErr.get();
1141 FuncRecordsBuffer = std::copy(CoverageRecords.begin(),
1142 CoverageRecords.end(), FuncRecordsBuffer);
1144 std::fill_n(FuncRecordsBuffer,
1145 alignAddr(FuncRecordsBuffer, RecordAlignment) -
1146 (uintptr_t)FuncRecordsBuffer,
1149 assert(FuncRecordsBuffer == WritableBuffer->getBufferEnd() &&
1151 FuncRecords = std::move(WritableBuffer);
1159 BytesInAddress,
Endian, CompilationDir);
1166 if (
auto *Universal = dyn_cast<MachOUniversalBinary>(
Bin)) {
1167 for (
auto &ObjForArch : Universal->objects())
1168 if (Arch == ObjForArch.getArchFlagName())
1181 std::vector<std::unique_ptr<BinaryCoverageReader>> Readers;
1185 support::endian::byte_swap<uint64_t, support::endianness::little>(
1192 return ReaderOrErr.takeError();
1193 Readers.push_back(std::move(ReaderOrErr.get()));
1194 return std::move(Readers);
1200 return BinOrErr.takeError();
1201 std::unique_ptr<Binary>
Bin = std::move(BinOrErr.get());
1204 return make_error<CoverageMapError>(
1209 if (
auto *Universal = dyn_cast<MachOUniversalBinary>(
Bin.get())) {
1210 for (
auto &ObjForArch : Universal->objects()) {
1212 std::string ObjArch = ObjForArch.getArchFlagName();
1213 if (Arch != ObjArch)
1216 auto ArchiveOrErr = ObjForArch.getAsArchive();
1217 if (!ArchiveOrErr) {
1224 ArchiveOrErr.get()->getMemoryBufferRef(), Arch,
1225 ObjectFileBuffers, ProfSymTab, CompilationDir, BinaryIDs);
1230 if (
auto *Ar = dyn_cast<Archive>(
Bin.get())) {
1232 for (
auto &Child : Ar->children(Err)) {
1238 ChildBufOrErr.
get(), Arch, ObjectFileBuffers, ProfSymTab,
1239 CompilationDir, BinaryIDs);
1240 if (!ChildReadersOrErr)
1241 return ChildReadersOrErr.takeError();
1242 for (
auto &Reader : ChildReadersOrErr.get())
1243 Readers.push_back(std::move(Reader));
1246 return std::move(Err);
1252 for (
auto &Buffer : Ar->takeThinBuffers())
1253 ObjectFileBuffers.push_back(std::move(Buffer));
1255 return std::move(Readers);
1261 BinaryIDs ? &BinaryID :
nullptr);
1263 return ReaderOrErr.takeError();
1264 Readers.push_back(std::move(ReaderOrErr.get()));
1265 if (!BinaryID.
empty())
1267 return std::move(Readers);
1271 if (CurrentRecord >= MappingRecords.size())
1274 FunctionsFilenames.clear();
1275 Expressions.clear();
1276 MappingRegions.clear();
1277 auto &R = MappingRecords[CurrentRecord];
1278 auto F =
ArrayRef(Filenames).
slice(R.FilenamesBegin, R.FilenamesSize);
1280 Expressions, MappingRegions);
1281 if (
auto Err = Reader.
read())
1284 Record.FunctionName = R.FunctionName;
1285 Record.FunctionHash = R.FunctionHash;
1286 Record.Filenames = FunctionsFilenames;
1287 Record.Expressions = Expressions;
1288 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, InstrProfSymtab &ProfSymTab, 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 Error getProfileNamesFromDebugInfo(StringRef FileName, InstrProfSymtab &ProfileNames)
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.
static llvm::Expected< std::unique_ptr< InstrProfCorrelator > > get(StringRef DebugInfoFilename)
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, InstrProfSymtab &IndexedProfSymTab, StringRef CompilationDir="", SmallVectorImpl< object::BuildIDRef > *BinaryIDs=nullptr)
static Expected< std::unique_ptr< BinaryCoverageReader > > createCoverageReaderFromBuffer(StringRef Coverage, FuncRecordsStorage &&FuncRecords, InstrProfSymtab &&ProfileNames, uint8_t BytesInAddress, support::endianness Endian, StringRef CompilationDir="")
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...
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.