diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/docs/CoverageMappingFormat.rst | 11 | ||||
-rw-r--r-- | llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h | 5 | ||||
-rw-r--r-- | llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h | 22 | ||||
-rw-r--r-- | llvm/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h | 4 | ||||
-rw-r--r-- | llvm/include/llvm/ProfileData/InstrProfData.inc | 2 | ||||
-rw-r--r-- | llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp | 95 | ||||
-rw-r--r-- | llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp | 2 | ||||
-rwxr-xr-x | llvm/test/tools/llvm-cov/Inputs/binary-formats.v6.linux64l | bin | 130352 -> 0 bytes | |||
-rw-r--r-- | llvm/test/tools/llvm-cov/binary-formats.c | 1 | ||||
-rw-r--r-- | llvm/unittests/ProfileData/CoverageMappingTest.cpp | 22 |
10 files changed, 73 insertions, 91 deletions
diff --git a/llvm/docs/CoverageMappingFormat.rst b/llvm/docs/CoverageMappingFormat.rst index 0dc5ce6e..4dc9dc3 100644 --- a/llvm/docs/CoverageMappingFormat.rst +++ b/llvm/docs/CoverageMappingFormat.rst @@ -266,16 +266,7 @@ too deeply). [32 x i8] c"..." ; Encoded data (dissected later) }, section "__llvm_covmap", align 8 -The current version of the format is version 6. - -There is one difference between versions 6 and 5: - -* The first entry in the filename list is the compilation directory. When the - filename is relative, the compilation directory is combined with the relative - path to get an absolute path. This can reduce size by omitting the duplicate - prefix in filenames. - -There is one difference between versions 5 and 4: +The current version of the format is version 5. There is one difference from version 4: * The notion of branch region has been introduced along with a corresponding region kind. Branch regions encode two counters, one to track how many diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h index 957dfe9..09f2167 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -996,10 +996,7 @@ enum CovMapVersion { Version4 = 3, // Branch regions referring to two counters are added Version5 = 4, - // Compilation directory is stored separately and combined with relative - // filenames to produce an absolute file path. - Version6 = 5, - // The current version is Version6. + // The current version is Version5. CurrentVersion = INSTR_PROF_COVMAP_VERSION }; diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h index 86a3c4a..3a611bc 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h @@ -125,14 +125,14 @@ public: /// Reader for the raw coverage mapping data. class RawCoverageMappingReader : public RawCoverageReader { - ArrayRef<std::string> &TranslationUnitFilenames; + ArrayRef<StringRef> TranslationUnitFilenames; std::vector<StringRef> &Filenames; std::vector<CounterExpression> &Expressions; std::vector<CounterMappingRegion> &MappingRegions; public: RawCoverageMappingReader(StringRef MappingData, - ArrayRef<std::string> &TranslationUnitFilenames, + ArrayRef<StringRef> TranslationUnitFilenames, std::vector<StringRef> &Filenames, std::vector<CounterExpression> &Expressions, std::vector<CounterMappingRegion> &MappingRegions) @@ -174,8 +174,10 @@ public: FilenamesBegin(FilenamesBegin), FilenamesSize(FilenamesSize) {} }; + using DecompressedData = std::vector<std::unique_ptr<SmallVector<char, 0>>>; + private: - std::vector<std::string> Filenames; + std::vector<StringRef> Filenames; std::vector<ProfileMappingRecord> MappingRecords; InstrProfSymtab ProfileNames; size_t CurrentRecord = 0; @@ -188,6 +190,10 @@ private: // D69471, which can split up function records into multiple sections on ELF. std::string FuncRecords; + // Used to tie the lifetimes of decompressed strings to the lifetime of this + // BinaryCoverageReader instance. + DecompressedData Decompressed; + BinaryCoverageReader(std::string &&FuncRecords) : FuncRecords(std::move(FuncRecords)) {} @@ -210,20 +216,20 @@ public: /// Reader for the raw coverage filenames. class RawCoverageFilenamesReader : public RawCoverageReader { - std::vector<std::string> &Filenames; + std::vector<StringRef> &Filenames; // Read an uncompressed sequence of filenames. - Error readUncompressed(CovMapVersion Version, uint64_t NumFilenames); + Error readUncompressed(uint64_t NumFilenames); public: - RawCoverageFilenamesReader(StringRef Data, - std::vector<std::string> &Filenames) + RawCoverageFilenamesReader(StringRef Data, std::vector<StringRef> &Filenames) : RawCoverageReader(Data), Filenames(Filenames) {} RawCoverageFilenamesReader(const RawCoverageFilenamesReader &) = delete; RawCoverageFilenamesReader & operator=(const RawCoverageFilenamesReader &) = delete; - Error read(CovMapVersion Version); + Error read(CovMapVersion Version, + BinaryCoverageReader::DecompressedData &Decompressed); }; } // end namespace coverage diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h index 1420675..303e518 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h @@ -27,10 +27,10 @@ namespace coverage { /// Writer of the filenames section for the instrumentation /// based code coverage. class CoverageFilenamesSectionWriter { - ArrayRef<std::string> Filenames; + ArrayRef<StringRef> Filenames; public: - CoverageFilenamesSectionWriter(ArrayRef<std::string> Filenames); + CoverageFilenamesSectionWriter(ArrayRef<StringRef> Filenames); /// Write encoded filenames to the given output stream. If \p Compress is /// true, attempt to compress the filenames. diff --git a/llvm/include/llvm/ProfileData/InstrProfData.inc b/llvm/include/llvm/ProfileData/InstrProfData.inc index 9112c9f..3ee7af7 100644 --- a/llvm/include/llvm/ProfileData/InstrProfData.inc +++ b/llvm/include/llvm/ProfileData/InstrProfData.inc @@ -649,7 +649,7 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure, /* Indexed profile format version (start from 1). */ #define INSTR_PROF_INDEX_VERSION 7 /* Coverage mapping format version (start from 0). */ -#define INSTR_PROF_COVMAP_VERSION 5 +#define INSTR_PROF_COVMAP_VERSION 4 /* Profile version is always of type uint64_t. Reserve the upper 8 bits in the * version for other variants of profile. We set the lowest bit of the upper 8 diff --git a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp index 942f8e7..1acdcb4 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp @@ -97,7 +97,9 @@ Error RawCoverageReader::readString(StringRef &Result) { return Error::success(); } -Error RawCoverageFilenamesReader::read(CovMapVersion Version) { +Error RawCoverageFilenamesReader::read( + CovMapVersion Version, + BinaryCoverageReader::DecompressedData &Decompressed) { uint64_t NumFilenames; if (auto Err = readSize(NumFilenames)) return Err; @@ -105,7 +107,7 @@ Error RawCoverageFilenamesReader::read(CovMapVersion Version) { return make_error<CoverageMapError>(coveragemap_error::malformed); if (Version < CovMapVersion::Version4) - return readUncompressed(Version, NumFilenames); + return readUncompressed(NumFilenames); // The uncompressed length may exceed the size of the encoded filenames. // Skip size validation. @@ -122,8 +124,11 @@ Error RawCoverageFilenamesReader::read(CovMapVersion Version) { return make_error<CoverageMapError>( coveragemap_error::decompression_failed); - // Allocate memory for the decompressed filenames. - SmallVector<char, 0> StorageBuf; + // Allocate memory for the decompressed filenames. Transfer ownership of + // the memory to BinaryCoverageReader. + auto DecompressedStorage = std::make_unique<SmallVector<char, 0>>(); + SmallVectorImpl<char> &StorageBuf = *DecompressedStorage.get(); + Decompressed.push_back(std::move(DecompressedStorage)); // Read compressed filenames. StringRef CompressedFilenames = Data.substr(0, CompressedLen); @@ -138,40 +143,19 @@ Error RawCoverageFilenamesReader::read(CovMapVersion Version) { StringRef UncompressedFilenames(StorageBuf.data(), StorageBuf.size()); RawCoverageFilenamesReader Delegate(UncompressedFilenames, Filenames); - return Delegate.readUncompressed(Version, NumFilenames); + return Delegate.readUncompressed(NumFilenames); } - return readUncompressed(Version, NumFilenames); + return readUncompressed(NumFilenames); } -Error RawCoverageFilenamesReader::readUncompressed(CovMapVersion Version, - uint64_t NumFilenames) { +Error RawCoverageFilenamesReader::readUncompressed(uint64_t NumFilenames) { // Read uncompressed filenames. - if (Version < CovMapVersion::Version6) { - for (size_t I = 0; I < NumFilenames; ++I) { - StringRef Filename; - if (auto Err = readString(Filename)) - return Err; - Filenames.push_back(Filename.str()); - } - } else { - StringRef CWD; - if (auto Err = readString(CWD)) + for (size_t I = 0; I < NumFilenames; ++I) { + StringRef Filename; + if (auto Err = readString(Filename)) return Err; - Filenames.push_back(CWD.str()); - - for (size_t I = 1; I < NumFilenames; ++I) { - StringRef Filename; - if (auto Err = readString(Filename)) - return Err; - if (sys::path::is_absolute(Filename)) { - Filenames.push_back(Filename.str()); - } else { - SmallString<256> P(CWD); - llvm::sys::path::append(P, Filename); - Filenames.push_back(static_cast<std::string>(P)); - } - } + Filenames.push_back(Filename); } return Error::success(); } @@ -497,8 +481,9 @@ struct CovMapFuncRecordReader { // // Returns a pointer to the next \c CovHeader if it exists, or to an address // greater than \p CovEnd if not. - virtual Expected<const char *> readCoverageHeader(const char *CovBuf, - const char *CovBufEnd) = 0; + virtual Expected<const char *> + readCoverageHeader(const char *CovBuf, const char *CovBufEnd, + BinaryCoverageReader::DecompressedData &Decompressed) = 0; // Read function records. // @@ -520,7 +505,7 @@ struct CovMapFuncRecordReader { static Expected<std::unique_ptr<CovMapFuncRecordReader>> get(CovMapVersion Version, InstrProfSymtab &P, std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, - std::vector<std::string> &F); + std::vector<StringRef> &F); }; // A class for reading coverage mapping function records for a module. @@ -534,7 +519,7 @@ class VersionedCovMapFuncRecordReader : public CovMapFuncRecordReader { // in \c Records. DenseMap<NameRefType, size_t> FunctionRecords; InstrProfSymtab &ProfileNames; - std::vector<std::string> &Filenames; + std::vector<StringRef> &Filenames; std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records; // Maps a hash of the filenames in a TU to a \c FileRange. The range @@ -594,13 +579,14 @@ public: VersionedCovMapFuncRecordReader( InstrProfSymtab &P, std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, - std::vector<std::string> &F) + std::vector<StringRef> &F) : ProfileNames(P), Filenames(F), Records(R) {} ~VersionedCovMapFuncRecordReader() override = default; - Expected<const char *> readCoverageHeader(const char *CovBuf, - const char *CovBufEnd) override { + Expected<const char *> readCoverageHeader( + const char *CovBuf, const char *CovBufEnd, + BinaryCoverageReader::DecompressedData &Decompressed) override { using namespace support; if (CovBuf + sizeof(CovMapHeader) > CovBufEnd) @@ -629,7 +615,7 @@ public: size_t FilenamesBegin = Filenames.size(); StringRef FilenameRegion(CovBuf, FilenamesSize); RawCoverageFilenamesReader Reader(FilenameRegion, Filenames); - if (auto Err = Reader.read(Version)) + if (auto Err = Reader.read(Version, Decompressed)) return std::move(Err); CovBuf += FilenamesSize; FilenameRange FileRange(FilenamesBegin, Filenames.size() - FilenamesBegin); @@ -735,7 +721,7 @@ template <class IntPtrT, support::endianness Endian> Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get( CovMapVersion Version, InstrProfSymtab &P, std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, - std::vector<std::string> &F) { + std::vector<StringRef> &F) { using namespace coverage; switch (Version) { @@ -746,7 +732,6 @@ Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get( case CovMapVersion::Version3: case CovMapVersion::Version4: case CovMapVersion::Version5: - case CovMapVersion::Version6: // Decompress the name data. if (Error E = P.create(P.getNameData())) return std::move(E); @@ -762,9 +747,6 @@ Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get( else if (Version == CovMapVersion::Version5) return std::make_unique<VersionedCovMapFuncRecordReader< CovMapVersion::Version5, IntPtrT, Endian>>(P, R, F); - else if (Version == CovMapVersion::Version6) - return std::make_unique<VersionedCovMapFuncRecordReader< - CovMapVersion::Version6, IntPtrT, Endian>>(P, R, F); } llvm_unreachable("Unsupported version"); } @@ -773,7 +755,8 @@ template <typename T, support::endianness Endian> static Error readCoverageMappingData( InstrProfSymtab &ProfileNames, StringRef CovMap, StringRef FuncRecords, std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records, - std::vector<std::string> &Filenames) { + std::vector<StringRef> &Filenames, + BinaryCoverageReader::DecompressedData &Decompressed) { using namespace coverage; // Read the records in the coverage data section. @@ -799,7 +782,8 @@ static Error readCoverageMappingData( // header. // // Return a pointer to the next coverage header. - auto NextOrErr = Reader->readCoverageHeader(CovBuf, CovBufEnd); + auto NextOrErr = + Reader->readCoverageHeader(CovBuf, CovBufEnd, Decompressed); if (auto E = NextOrErr.takeError()) return E; CovBuf = NextOrErr.get(); @@ -826,23 +810,25 @@ BinaryCoverageReader::createCoverageReaderFromBuffer( if (Error E = readCoverageMappingData<uint32_t, support::endianness::little>( Reader->ProfileNames, Coverage, FuncRecordsRef, - Reader->MappingRecords, Reader->Filenames)) + Reader->MappingRecords, Reader->Filenames, + Reader->Decompressed)) return std::move(E); } else if (BytesInAddress == 4 && Endian == support::endianness::big) { if (Error E = readCoverageMappingData<uint32_t, support::endianness::big>( Reader->ProfileNames, Coverage, FuncRecordsRef, - Reader->MappingRecords, Reader->Filenames)) + Reader->MappingRecords, Reader->Filenames, Reader->Decompressed)) return std::move(E); } else if (BytesInAddress == 8 && Endian == support::endianness::little) { if (Error E = readCoverageMappingData<uint64_t, support::endianness::little>( Reader->ProfileNames, Coverage, FuncRecordsRef, - Reader->MappingRecords, Reader->Filenames)) + Reader->MappingRecords, Reader->Filenames, + Reader->Decompressed)) return std::move(E); } else if (BytesInAddress == 8 && Endian == support::endianness::big) { if (Error E = readCoverageMappingData<uint64_t, support::endianness::big>( Reader->ProfileNames, Coverage, FuncRecordsRef, - Reader->MappingRecords, Reader->Filenames)) + Reader->MappingRecords, Reader->Filenames, Reader->Decompressed)) return std::move(E); } else return make_error<CoverageMapError>(coveragemap_error::malformed); @@ -1089,9 +1075,10 @@ Error BinaryCoverageReader::readNextRecord(CoverageMappingRecord &Record) { Expressions.clear(); MappingRegions.clear(); auto &R = MappingRecords[CurrentRecord]; - auto F = makeArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize); - RawCoverageMappingReader Reader(R.CoverageMapping, F, FunctionsFilenames, - Expressions, MappingRegions); + RawCoverageMappingReader Reader( + R.CoverageMapping, + makeArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize), + FunctionsFilenames, Expressions, MappingRegions); if (auto Err = Reader.read()) return Err; diff --git a/llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp b/llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp index 6a9258f..65b83d1 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp @@ -27,7 +27,7 @@ using namespace llvm; using namespace coverage; CoverageFilenamesSectionWriter::CoverageFilenamesSectionWriter( - ArrayRef<std::string> Filenames) + ArrayRef<StringRef> Filenames) : Filenames(Filenames) { #ifndef NDEBUG StringSet<> NameSet; diff --git a/llvm/test/tools/llvm-cov/Inputs/binary-formats.v6.linux64l b/llvm/test/tools/llvm-cov/Inputs/binary-formats.v6.linux64l Binary files differdeleted file mode 100755 index bd00cd0..0000000 --- a/llvm/test/tools/llvm-cov/Inputs/binary-formats.v6.linux64l +++ /dev/null diff --git a/llvm/test/tools/llvm-cov/binary-formats.c b/llvm/test/tools/llvm-cov/binary-formats.c index a5bfc01..009583c 100644 --- a/llvm/test/tools/llvm-cov/binary-formats.c +++ b/llvm/test/tools/llvm-cov/binary-formats.c @@ -8,6 +8,5 @@ int main(int argc, const char *argv[]) {} // RUN: llvm-cov show %S/Inputs/binary-formats.macho64l -instr-profile %t.profdata -path-equivalence=/tmp,%S %s | FileCheck %s // RUN: llvm-cov show %S/Inputs/binary-formats.macho32b -instr-profile %t.profdata -path-equivalence=/tmp,%S %s | FileCheck %s // RUN: llvm-cov show %S/Inputs/binary-formats.v3.macho64l -instr-profile %t.profdata -path-equivalence=/tmp,%S %s | FileCheck %s -// RUN: llvm-cov show %S/Inputs/binary-formats.v6.linux64l -instr-profile %t.profdata -path-equivalence=/tmp,%S %s | FileCheck %s // RUN: llvm-cov export %S/Inputs/binary-formats.macho64l -instr-profile %t.profdata | FileCheck %S/Inputs/binary-formats.canonical.json diff --git a/llvm/unittests/ProfileData/CoverageMappingTest.cpp b/llvm/unittests/ProfileData/CoverageMappingTest.cpp index 44b7a13..cbe9c1e 100644 --- a/llvm/unittests/ProfileData/CoverageMappingTest.cpp +++ b/llvm/unittests/ProfileData/CoverageMappingTest.cpp @@ -129,7 +129,6 @@ struct InputFunctionCoverageData { struct CoverageMappingTest : ::testing::TestWithParam<std::pair<bool, bool>> { bool UseMultipleReaders; StringMap<unsigned> Files; - std::vector<std::string> Filenames; std::vector<InputFunctionCoverageData> InputFunctions; std::vector<OutputFunctionCoverageData> OutputFunctions; @@ -147,7 +146,7 @@ struct CoverageMappingTest : ::testing::TestWithParam<std::pair<bool, bool>> { auto R = Files.find(Name); if (R != Files.end()) return R->second; - unsigned Index = Files.size() + 1; + unsigned Index = Files.size(); Files.try_emplace(Name, Index); return Index; } @@ -201,12 +200,11 @@ struct CoverageMappingTest : ::testing::TestWithParam<std::pair<bool, bool>> { void readCoverageRegions(const std::string &Coverage, OutputFunctionCoverageData &Data) { - Filenames.resize(Files.size() + 1); + SmallVector<StringRef, 8> Filenames(Files.size()); for (const auto &E : Files) - Filenames[E.getValue()] = E.getKey().str(); + Filenames[E.getValue()] = E.getKey(); std::vector<CounterExpression> Expressions; - ArrayRef<std::string> FilenameRefs = llvm::makeArrayRef(Filenames); - RawCoverageMappingReader Reader(Coverage, FilenameRefs, Data.Filenames, + RawCoverageMappingReader Reader(Coverage, Filenames, Data.Filenames, Expressions, Data.Regions); EXPECT_THAT_ERROR(Reader.read(), Succeeded()); } @@ -897,7 +895,7 @@ INSTANTIATE_TEST_CASE_P(ParameterizedCovMapTest, CoverageMappingTest, std::pair<bool, bool>({true, true})),); TEST(CoverageMappingTest, filename_roundtrip) { - std::vector<std::string> Paths({"", "a", "b", "c", "d", "e"}); + std::vector<StringRef> Paths({"a", "b", "c", "d", "e"}); for (bool Compress : {false, true}) { std::string EncodedFilenames; @@ -907,12 +905,16 @@ TEST(CoverageMappingTest, filename_roundtrip) { Writer.write(OS, Compress); } - std::vector<std::string> ReadFilenames; + std::vector<StringRef> ReadFilenames; RawCoverageFilenamesReader Reader(EncodedFilenames, ReadFilenames); - EXPECT_THAT_ERROR(Reader.read(CovMapVersion::CurrentVersion), Succeeded()); + BinaryCoverageReader::DecompressedData Decompressed; + EXPECT_THAT_ERROR(Reader.read(CovMapVersion::CurrentVersion, Decompressed), + Succeeded()); + if (!Compress) + ASSERT_EQ(Decompressed.size(), 0U); ASSERT_EQ(ReadFilenames.size(), Paths.size()); - for (unsigned I = 1; I < Paths.size(); ++I) + for (unsigned I = 0; I < Paths.size(); ++I) ASSERT_TRUE(ReadFilenames[I] == Paths[I]); } } |