Revert "[llvm-cov] Add support for baseline coverage" (#144121)

Reverts llvm/llvm-project#117910

```
/home/buildbots/llvm-external-buildbots/workers/ppc64le-lld-multistage-test/ppc64le-lld-multistage-test/llvm-project/llvm/unittests/ProfileData/CoverageMappingTest.cpp
/home/buildbots/llvm-external-buildbots/workers/ppc64le-lld-multistage-test/ppc64le-lld-multistage-test/llvm-project/llvm/unittests/ProfileData/CoverageMappingTest.cpp:281:28: error: 'std::reference_wrapper' may not intend to support class template argument deduction [-Werror,-Wctad-maybe-unsupported]
  281 |         std::make_optional(std::reference_wrapper(*ProfileReader));
      |                            ^
/usr/lib/gcc/ppc64le-redhat-linux/8/../../../../include/c++/8/bits/refwrap.h:289:11: note: add a deduction guide to suppress this warning
  289 |     class reference_wrapper
      |           ^
```
This commit is contained in:
Keith Smiley
2025-06-13 10:04:45 -07:00
committed by GitHub
parent 2704b27a0b
commit 65d88d31ea
6 changed files with 86 additions and 195 deletions

View File

@@ -380,11 +380,6 @@ OPTIONS
Fail if an object file cannot be found for a binary ID present in the profile,
neither on the command line nor via binary ID lookup.
.. option:: -empty-profile
Display the baseline coverage of the binaries with all zero execution counts.
Mutually exclusive with -instr-profile.
.. program:: llvm-cov report
.. _llvm-cov-report:
@@ -475,11 +470,6 @@ OPTIONS
Fail if an object file cannot be found for a binary ID present in the profile,
neither on the command line nor via binary ID lookup.
.. option:: -empty-profile
Display the baseline coverage of the binaries with all zero execution counts.
Mutually exclusive with -instr-profile.
.. program:: llvm-cov export
.. _llvm-cov-export:
@@ -572,11 +562,6 @@ OPTIONS
Fail if an object file cannot be found for a binary ID present in the profile,
neither on the command line nor via binary ID lookup.
.. option:: -empty-profile
Export the baseline coverage of the binaries with all zero execution counts.
Mutually exclusive with -instr-profile.
CONVERT-FOR-TESTING COMMAND
---------------------------

View File

@@ -991,23 +991,18 @@ class CoverageMapping {
// Load coverage records from readers.
static Error loadFromReaders(
ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
std::optional<std::reference_wrapper<IndexedInstrProfReader>>
&ProfileReader,
CoverageMapping &Coverage);
IndexedInstrProfReader &ProfileReader, CoverageMapping &Coverage);
// Load coverage records from file.
static Error
loadFromFile(StringRef Filename, StringRef Arch, StringRef CompilationDir,
std::optional<std::reference_wrapper<IndexedInstrProfReader>>
&ProfileReader,
CoverageMapping &Coverage, bool &DataFound,
IndexedInstrProfReader &ProfileReader, CoverageMapping &Coverage,
bool &DataFound,
SmallVectorImpl<object::BuildID> *FoundBinaryIDs = nullptr);
/// Add a function record corresponding to \p Record.
Error loadFunctionRecord(
const CoverageMappingRecord &Record,
const std::optional<std::reference_wrapper<IndexedInstrProfReader>>
&ProfileReader);
Error loadFunctionRecord(const CoverageMappingRecord &Record,
IndexedInstrProfReader &ProfileReader);
/// Look up the indices for function records which are at least partially
/// defined in the specified file. This is guaranteed to return a superset of
@@ -1023,16 +1018,15 @@ public:
/// Load the coverage mapping using the given readers.
LLVM_ABI static Expected<std::unique_ptr<CoverageMapping>>
load(ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
std::optional<std::reference_wrapper<IndexedInstrProfReader>>
&ProfileReader);
IndexedInstrProfReader &ProfileReader);
/// Load the coverage mapping from the given object files and profile. If
/// \p Arches is non-empty, it must specify an architecture for each object.
/// Ignores non-instrumented object files unless all are not instrumented.
LLVM_ABI static Expected<std::unique_ptr<CoverageMapping>>
load(ArrayRef<StringRef> ObjectFilenames,
std::optional<StringRef> ProfileFilename, vfs::FileSystem &FS,
ArrayRef<StringRef> Arches = {}, StringRef CompilationDir = "",
load(ArrayRef<StringRef> ObjectFilenames, StringRef ProfileFilename,
vfs::FileSystem &FS, ArrayRef<StringRef> Arches = {},
StringRef CompilationDir = "",
const object::BuildIDFetcher *BIDFetcher = nullptr,
bool CheckBinaryIDs = false);

View File

@@ -823,8 +823,7 @@ public:
Error CoverageMapping::loadFunctionRecord(
const CoverageMappingRecord &Record,
const std::optional<std::reference_wrapper<IndexedInstrProfReader>>
&ProfileReader) {
IndexedInstrProfReader &ProfileReader) {
StringRef OrigFuncName = Record.FunctionName;
if (OrigFuncName.empty())
return make_error<CoverageMapError>(coveragemap_error::malformed,
@@ -838,44 +837,35 @@ Error CoverageMapping::loadFunctionRecord(
CounterMappingContext Ctx(Record.Expressions);
std::vector<uint64_t> Counts;
if (ProfileReader) {
if (Error E = ProfileReader.value().get().getFunctionCounts(
Record.FunctionName, Record.FunctionHash, Counts)) {
instrprof_error IPE = std::get<0>(InstrProfError::take(std::move(E)));
if (IPE == instrprof_error::hash_mismatch) {
FuncHashMismatches.emplace_back(std::string(Record.FunctionName),
Record.FunctionHash);
return Error::success();
}
if (IPE != instrprof_error::unknown_function)
return make_error<InstrProfError>(IPE);
Counts.assign(getMaxCounterID(Ctx, Record) + 1, 0);
if (Error E = ProfileReader.getFunctionCounts(Record.FunctionName,
Record.FunctionHash, Counts)) {
instrprof_error IPE = std::get<0>(InstrProfError::take(std::move(E)));
if (IPE == instrprof_error::hash_mismatch) {
FuncHashMismatches.emplace_back(std::string(Record.FunctionName),
Record.FunctionHash);
return Error::success();
}
} else {
if (IPE != instrprof_error::unknown_function)
return make_error<InstrProfError>(IPE);
Counts.assign(getMaxCounterID(Ctx, Record) + 1, 0);
}
Ctx.setCounts(Counts);
bool IsVersion11 =
ProfileReader && ProfileReader.value().get().getVersion() <
IndexedInstrProf::ProfVersion::Version12;
ProfileReader.getVersion() < IndexedInstrProf::ProfVersion::Version12;
BitVector Bitmap;
if (ProfileReader) {
if (Error E = ProfileReader.value().get().getFunctionBitmap(
Record.FunctionName, Record.FunctionHash, Bitmap)) {
instrprof_error IPE = std::get<0>(InstrProfError::take(std::move(E)));
if (IPE == instrprof_error::hash_mismatch) {
FuncHashMismatches.emplace_back(std::string(Record.FunctionName),
Record.FunctionHash);
return Error::success();
}
if (IPE != instrprof_error::unknown_function)
return make_error<InstrProfError>(IPE);
Bitmap = BitVector(getMaxBitmapSize(Record, IsVersion11));
if (Error E = ProfileReader.getFunctionBitmap(Record.FunctionName,
Record.FunctionHash, Bitmap)) {
instrprof_error IPE = std::get<0>(InstrProfError::take(std::move(E)));
if (IPE == instrprof_error::hash_mismatch) {
FuncHashMismatches.emplace_back(std::string(Record.FunctionName),
Record.FunctionHash);
return Error::success();
}
} else {
Bitmap = BitVector(getMaxBitmapSize(Record, false));
if (IPE != instrprof_error::unknown_function)
return make_error<InstrProfError>(IPE);
Bitmap = BitVector(getMaxBitmapSize(Record, IsVersion11));
}
Ctx.setBitmap(std::move(Bitmap));
@@ -969,14 +959,10 @@ Error CoverageMapping::loadFunctionRecord(
// of CoverageMappingReader instances.
Error CoverageMapping::loadFromReaders(
ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
std::optional<std::reference_wrapper<IndexedInstrProfReader>>
&ProfileReader,
CoverageMapping &Coverage) {
assert(!Coverage.SingleByteCoverage || !ProfileReader ||
*Coverage.SingleByteCoverage ==
ProfileReader.value().get().hasSingleByteCoverage());
Coverage.SingleByteCoverage =
!ProfileReader || ProfileReader.value().get().hasSingleByteCoverage();
IndexedInstrProfReader &ProfileReader, CoverageMapping &Coverage) {
assert(!Coverage.SingleByteCoverage ||
*Coverage.SingleByteCoverage == ProfileReader.hasSingleByteCoverage());
Coverage.SingleByteCoverage = ProfileReader.hasSingleByteCoverage();
for (const auto &CoverageReader : CoverageReaders) {
for (auto RecordOrErr : *CoverageReader) {
if (Error E = RecordOrErr.takeError())
@@ -991,8 +977,7 @@ Error CoverageMapping::loadFromReaders(
Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load(
ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
std::optional<std::reference_wrapper<IndexedInstrProfReader>>
&ProfileReader) {
IndexedInstrProfReader &ProfileReader) {
auto Coverage = std::unique_ptr<CoverageMapping>(new CoverageMapping());
if (Error E = loadFromReaders(CoverageReaders, ProfileReader, *Coverage))
return std::move(E);
@@ -1001,19 +986,18 @@ Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load(
// If E is a no_data_found error, returns success. Otherwise returns E.
static Error handleMaybeNoDataFoundError(Error E) {
return handleErrors(std::move(E), [](const CoverageMapError &CME) {
if (CME.get() == coveragemap_error::no_data_found)
return static_cast<Error>(Error::success());
return make_error<CoverageMapError>(CME.get(), CME.getMessage());
});
return handleErrors(
std::move(E), [](const CoverageMapError &CME) {
if (CME.get() == coveragemap_error::no_data_found)
return static_cast<Error>(Error::success());
return make_error<CoverageMapError>(CME.get(), CME.getMessage());
});
}
Error CoverageMapping::loadFromFile(
StringRef Filename, StringRef Arch, StringRef CompilationDir,
std::optional<std::reference_wrapper<IndexedInstrProfReader>>
&ProfileReader,
CoverageMapping &Coverage, bool &DataFound,
SmallVectorImpl<object::BuildID> *FoundBinaryIDs) {
IndexedInstrProfReader &ProfileReader, CoverageMapping &Coverage,
bool &DataFound, SmallVectorImpl<object::BuildID> *FoundBinaryIDs) {
auto CovMappingBufOrErr = MemoryBuffer::getFileOrSTDIN(
Filename, /*IsText=*/false, /*RequiresNullTerminator=*/false);
if (std::error_code EC = CovMappingBufOrErr.getError())
@@ -1049,23 +1033,13 @@ Error CoverageMapping::loadFromFile(
}
Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load(
ArrayRef<StringRef> ObjectFilenames,
std::optional<StringRef> ProfileFilename, vfs::FileSystem &FS,
ArrayRef<StringRef> Arches, StringRef CompilationDir,
ArrayRef<StringRef> ObjectFilenames, StringRef ProfileFilename,
vfs::FileSystem &FS, ArrayRef<StringRef> Arches, StringRef CompilationDir,
const object::BuildIDFetcher *BIDFetcher, bool CheckBinaryIDs) {
std::unique_ptr<IndexedInstrProfReader> ProfileReader;
if (ProfileFilename) {
auto ProfileReaderOrErr =
IndexedInstrProfReader::create(ProfileFilename.value(), FS);
if (Error E = ProfileReaderOrErr.takeError())
return createFileError(ProfileFilename.value(), std::move(E));
ProfileReader = std::move(ProfileReaderOrErr.get());
}
auto ProfileReaderRef =
ProfileReader
? std::optional<std::reference_wrapper<IndexedInstrProfReader>>(
*ProfileReader)
: std::nullopt;
auto ProfileReaderOrErr = IndexedInstrProfReader::create(ProfileFilename, FS);
if (Error E = ProfileReaderOrErr.takeError())
return createFileError(ProfileFilename, std::move(E));
auto ProfileReader = std::move(ProfileReaderOrErr.get());
auto Coverage = std::unique_ptr<CoverageMapping>(new CoverageMapping());
bool DataFound = false;
@@ -1079,17 +1053,16 @@ Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load(
SmallVector<object::BuildID> FoundBinaryIDs;
for (const auto &File : llvm::enumerate(ObjectFilenames)) {
if (Error E = loadFromFile(File.value(), GetArch(File.index()),
CompilationDir, ProfileReaderRef, *Coverage,
DataFound, &FoundBinaryIDs))
if (Error E =
loadFromFile(File.value(), GetArch(File.index()), CompilationDir,
*ProfileReader, *Coverage, DataFound, &FoundBinaryIDs))
return std::move(E);
}
if (BIDFetcher) {
std::vector<object::BuildID> ProfileBinaryIDs;
if (ProfileReader)
if (Error E = ProfileReader->readBinaryIds(ProfileBinaryIDs))
return createFileError(ProfileFilename.value(), std::move(E));
if (Error E = ProfileReader->readBinaryIds(ProfileBinaryIDs))
return createFileError(ProfileFilename, std::move(E));
SmallVector<object::BuildIDRef> BinaryIDsToFetch;
if (!ProfileBinaryIDs.empty()) {
@@ -1109,12 +1082,12 @@ Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load(
if (PathOpt) {
std::string Path = std::move(*PathOpt);
StringRef Arch = Arches.size() == 1 ? Arches.front() : StringRef();
if (Error E = loadFromFile(Path, Arch, CompilationDir, ProfileReaderRef,
*Coverage, DataFound))
if (Error E = loadFromFile(Path, Arch, CompilationDir, *ProfileReader,
*Coverage, DataFound))
return std::move(E);
} else if (CheckBinaryIDs) {
return createFileError(
ProfileFilename.value(),
ProfileFilename,
createStringError(errc::no_such_file_or_directory,
"Missing binary ID: " +
llvm::toHex(BinaryID, /*LowerCase=*/true)));

View File

@@ -1,37 +0,0 @@
// FULL: SF:{{.*}}showLineExecutionCounts.cpp
// FULL: FN:6,main
// FULL: FNDA:0,main
// FULL: FNF:1
// FULL: FNH:0
int main() { // FULL: DA:[[@LINE]],0
int x = 0; // FULL: DA:[[@LINE]],0
// FULL: DA:[[@LINE]],0
if (x) { // FULL: DA:[[@LINE]],0
x = 0; // FULL: DA:[[@LINE]],0
} else { // FULL: DA:[[@LINE]],0
x = 1; // FULL: DA:[[@LINE]],0
} // FULL: DA:[[@LINE]],0
// FULL: DA:[[@LINE]],0
for (int i = 0; i < 100; ++i) { // FULL: DA:[[@LINE]],0
x = 1; // FULL: DA:[[@LINE]],0
} // FULL: DA:[[@LINE]],0
// FULL: DA:[[@LINE]],0
x = x < 10 ? x + 1 : x - 1; // FULL: DA:[[@LINE]],0
x = x > 10 ? // FULL: DA:[[@LINE]],0
x - 1: // FULL: DA:[[@LINE]],0
x + 1; // FULL: DA:[[@LINE]],0
// FULL: DA:[[@LINE]],0
return 0; // FULL: DA:[[@LINE]],0
} // FULL: DA:[[@LINE]],0
// FULL: LF:20
// FULL: LH:0
// FULL: end_of_record
// RUN: llvm-cov export -format=lcov %S/Inputs/lineExecutionCounts.covmapping -empty-profile %s | FileCheck -check-prefixes=FULL %s
// RUN: llvm-cov export -format=lcov -summary-only %S/Inputs/lineExecutionCounts.covmapping -empty-profile %s | FileCheck -check-prefixes=SUMMARYONLY %s
// SUMMARYONLY: SF:{{.*}}showLineExecutionCounts.cpp
// SUMMARYONLY: FNF:1
// SUMMARYONLY: FNH:0
// SUMMARYONLY: LF:20
// SUMMARYONLY: LH:0
// SUMMARYONLY: end_of_record

View File

@@ -153,7 +153,7 @@ private:
bool HadSourceFiles = false;
/// The path to the indexed profile.
std::optional<std::string> PGOFilename;
std::string PGOFilename;
/// A list of input source files.
std::vector<std::string> SourceFiles;
@@ -455,12 +455,10 @@ static bool modifiedTimeGT(StringRef LHS, StringRef RHS) {
}
std::unique_ptr<CoverageMapping> CodeCoverageTool::load() {
if (PGOFilename) {
for (StringRef ObjectFilename : ObjectFilenames)
if (modifiedTimeGT(ObjectFilename, PGOFilename.value()))
warning("profile data may be out of date - object is newer",
ObjectFilename);
}
for (StringRef ObjectFilename : ObjectFilenames)
if (modifiedTimeGT(ObjectFilename, PGOFilename))
warning("profile data may be out of date - object is newer",
ObjectFilename);
auto FS = vfs::getRealFileSystem();
auto CoverageOrErr = CoverageMapping::load(
ObjectFilenames, PGOFilename, *FS, CoverageArches,
@@ -670,16 +668,11 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
"dump-collected-paths", cl::Optional, cl::Hidden,
cl::desc("Show the collected paths to source files"));
cl::opt<std::string> PGOFilename(
"instr-profile", cl::Optional,
cl::opt<std::string, true> PGOFilename(
"instr-profile", cl::Required, cl::location(this->PGOFilename),
cl::desc(
"File with the profile data obtained after an instrumented run"));
cl::opt<bool> EmptyProfile(
"empty-profile", cl::Optional,
cl::desc("Use a synthetic profile with no data to generate "
"baseline coverage"));
cl::list<std::string> Arches(
"arch", cl::desc("architectures of the coverage mapping binaries"));
@@ -812,15 +805,6 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
}
this->CheckBinaryIDs = CheckBinaryIDs;
if (!PGOFilename.empty() == EmptyProfile) {
error(
"exactly one of -instr-profile and -empty-profile must be specified");
return 1;
}
if (!PGOFilename.empty()) {
this->PGOFilename = std::make_optional(PGOFilename.getValue());
}
if (!CovFilename.empty())
ObjectFilenames.emplace_back(CovFilename);
for (const std::string &Filename : CovFilenames)
@@ -1132,22 +1116,20 @@ int CodeCoverageTool::doShow(int argc, const char **argv,
}
}
if (PGOFilename) {
sys::fs::file_status Status;
if (std::error_code EC = sys::fs::status(PGOFilename.value(), Status)) {
error("could not read profile data!" + EC.message(), PGOFilename.value());
return 1;
}
sys::fs::file_status Status;
if (std::error_code EC = sys::fs::status(PGOFilename, Status)) {
error("could not read profile data!" + EC.message(), PGOFilename);
return 1;
}
if (ShowCreatedTime) {
auto ModifiedTime = Status.getLastModificationTime();
std::string ModifiedTimeStr = to_string(ModifiedTime);
size_t found = ModifiedTimeStr.rfind(':');
ViewOpts.CreatedTimeStr =
(found != std::string::npos)
? "Created: " + ModifiedTimeStr.substr(0, found)
: "Created: " + ModifiedTimeStr;
}
if (ShowCreatedTime) {
auto ModifiedTime = Status.getLastModificationTime();
std::string ModifiedTimeStr = to_string(ModifiedTime);
size_t found = ModifiedTimeStr.rfind(':');
ViewOpts.CreatedTimeStr =
(found != std::string::npos)
? "Created: " + ModifiedTimeStr.substr(0, found)
: "Created: " + ModifiedTimeStr;
}
auto Coverage = load();
@@ -1256,12 +1238,10 @@ int CodeCoverageTool::doReport(int argc, const char **argv,
return 1;
}
if (PGOFilename) {
sys::fs::file_status Status;
if (std::error_code EC = sys::fs::status(PGOFilename.value(), Status)) {
error("could not read profile data!" + EC.message(), PGOFilename.value());
return 1;
}
sys::fs::file_status Status;
if (std::error_code EC = sys::fs::status(PGOFilename, Status)) {
error("could not read profile data!" + EC.message(), PGOFilename);
return 1;
}
auto Coverage = load();
@@ -1323,12 +1303,10 @@ int CodeCoverageTool::doExport(int argc, const char **argv,
return 1;
}
if (PGOFilename) {
sys::fs::file_status Status;
if (std::error_code EC = sys::fs::status(PGOFilename.value(), Status)) {
error("could not read profile data!" + EC.message(), PGOFilename.value());
return 1;
}
sys::fs::file_status Status;
if (std::error_code EC = sys::fs::status(PGOFilename, Status)) {
error("could not read profile data!" + EC.message(), PGOFilename);
return 1;
}
auto Coverage = load();

View File

@@ -277,9 +277,7 @@ struct CoverageMappingTest : ::testing::TestWithParam<std::tuple<bool, bool>> {
CoverageReaders.push_back(
std::make_unique<CoverageMappingReaderMock>(Funcs));
}
auto ProfileReaderRef =
std::make_optional(std::reference_wrapper(*ProfileReader));
return CoverageMapping::load(CoverageReaders, ProfileReaderRef);
return CoverageMapping::load(CoverageReaders, *ProfileReader);
}
Error loadCoverageMapping(bool EmitFilenames = true) {