1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 03:02:36 +01:00

[llvm-cov] Allow specifying distinct architectures for each loaded binary

The coverage tool needs to know which slice to look at when it's handed
a universal binary. Some projects need to look at aggregate coverage
reports for a variety of slices in different binaries: this patch adds
support for these kinds of projects to llvm-cov.

rdar://problem/33579007

llvm-svn: 309747
This commit is contained in:
Vedant Kumar 2017-08-01 21:23:26 +00:00
parent a8ad1b51ee
commit 95aaeaf3f0
5 changed files with 39 additions and 19 deletions

View File

@ -222,12 +222,13 @@ OPTIONS
Enable or disable color output. By default this is autodetected. Enable or disable color output. By default this is autodetected.
.. option:: -arch=<name> .. option:: -arch=[*NAMES*]
If the covered binary is a universal binary, select the architecture to use. Specify a list of architectures such that the Nth entry in the list
It is an error to specify an architecture that is not included in the corresponds to the Nth specified binary. If the covered object is a universal
universal binary or to use an architecture that does not match a binary, this specifies the architecture to use. It is an error to specify an
non-universal binary. architecture that is not included in the universal binary or to use an
architecture that does not match a non-universal binary.
.. option:: -name=<NAME> .. option:: -name=<NAME>

View File

@ -449,14 +449,16 @@ public:
CoverageMapping(const CoverageMapping &) = delete; CoverageMapping(const CoverageMapping &) = delete;
CoverageMapping &operator=(const CoverageMapping &) = delete; CoverageMapping &operator=(const CoverageMapping &) = delete;
/// \brief Load the coverage mapping using the given readers. /// Load the coverage mapping using the given readers.
static Expected<std::unique_ptr<CoverageMapping>> static Expected<std::unique_ptr<CoverageMapping>>
load(ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders, load(ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
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.
static Expected<std::unique_ptr<CoverageMapping>> static Expected<std::unique_ptr<CoverageMapping>>
load(ArrayRef<StringRef> ObjectFilenames, StringRef ProfileFilename, load(ArrayRef<StringRef> ObjectFilenames, StringRef ProfileFilename,
StringRef Arch = StringRef()); ArrayRef<StringRef> Arches = None);
/// \brief The number of functions that couldn't have their profiles mapped. /// \brief The number of functions that couldn't have their profiles mapped.
/// ///

View File

@ -260,7 +260,7 @@ Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load(
Expected<std::unique_ptr<CoverageMapping>> Expected<std::unique_ptr<CoverageMapping>>
CoverageMapping::load(ArrayRef<StringRef> ObjectFilenames, CoverageMapping::load(ArrayRef<StringRef> ObjectFilenames,
StringRef ProfileFilename, StringRef Arch) { StringRef ProfileFilename, ArrayRef<StringRef> Arches) {
auto ProfileReaderOrErr = IndexedInstrProfReader::create(ProfileFilename); auto ProfileReaderOrErr = IndexedInstrProfReader::create(ProfileFilename);
if (Error E = ProfileReaderOrErr.takeError()) if (Error E = ProfileReaderOrErr.takeError())
return std::move(E); return std::move(E);
@ -268,10 +268,11 @@ CoverageMapping::load(ArrayRef<StringRef> ObjectFilenames,
SmallVector<std::unique_ptr<CoverageMappingReader>, 4> Readers; SmallVector<std::unique_ptr<CoverageMappingReader>, 4> Readers;
SmallVector<std::unique_ptr<MemoryBuffer>, 4> Buffers; SmallVector<std::unique_ptr<MemoryBuffer>, 4> Buffers;
for (StringRef ObjectFilename : ObjectFilenames) { for (const auto &File : llvm::enumerate(ObjectFilenames)) {
auto CovMappingBufOrErr = MemoryBuffer::getFileOrSTDIN(ObjectFilename); auto CovMappingBufOrErr = MemoryBuffer::getFileOrSTDIN(File.value());
if (std::error_code EC = CovMappingBufOrErr.getError()) if (std::error_code EC = CovMappingBufOrErr.getError())
return errorCodeToError(EC); return errorCodeToError(EC);
StringRef Arch = Arches.empty() ? StringRef() : Arches[File.index()];
auto CoverageReaderOrErr = auto CoverageReaderOrErr =
BinaryCoverageReader::create(CovMappingBufOrErr.get(), Arch); BinaryCoverageReader::create(CovMappingBufOrErr.get(), Arch);
if (Error E = CoverageReaderOrErr.takeError()) if (Error E = CoverageReaderOrErr.takeError())

View File

@ -7,9 +7,18 @@ int main(int argc, const char *argv[]) {}
// RUN: llvm-cov show %S/Inputs/universal-binary -instr-profile %t.profdata -filename-equivalence %s -arch x86_64 | FileCheck %s // RUN: llvm-cov show %S/Inputs/universal-binary -instr-profile %t.profdata -filename-equivalence %s -arch x86_64 | FileCheck %s
// RUN: llvm-cov export %S/Inputs/universal-binary -instr-profile %t.profdata -arch x86_64 2>&1 | FileCheck %S/Inputs/universal-binary.json // RUN: llvm-cov export %S/Inputs/universal-binary -instr-profile %t.profdata -arch x86_64 2>&1 | FileCheck %S/Inputs/universal-binary.json
// RUN: llvm-cov report %S/Inputs/universal-binary -arch x86_64 -object %S/Inputs/templateInstantiations.covmapping -arch i386 -instr-profile %t.profdata 2>&1 | FileCheck %s --check-prefix=COMBINED
// COMBINED: showTemplateInstantiations.cpp
// COMBINED-NEXT: universal-binary.c
// RUN: not llvm-cov show %S/Inputs/universal-binary -instr-profile %t.profdata -filename-equivalence %s -arch i386 2>&1 | FileCheck --check-prefix=WRONG-ARCH %s // RUN: not llvm-cov show %S/Inputs/universal-binary -instr-profile %t.profdata -filename-equivalence %s -arch i386 2>&1 | FileCheck --check-prefix=WRONG-ARCH %s
// WRONG-ARCH: Failed to load coverage // WRONG-ARCH: Failed to load coverage
// RUN: not llvm-cov show %S/Inputs/universal-binary -instr-profile %t.profdata -filename-equivalence %s -arch definitly_a_made_up_architecture 2>&1 | FileCheck --check-prefix=MADE-UP-ARCH %s
// MADE-UP-ARCH: Unknown architecture: definitly_a_made_up_architecture
// RUN: not llvm-cov show %S/Inputs/universal-binary -instr-profile %t.profdata -filename-equivalence %s -arch=x86_64 -arch=x86_64 2>&1 | FileCheck --check-prefix=TOO-MANY-ARCH %s
// TOO-MANY-ARCH: Number of architectures doesn't match the number of objects
//
// RUN: not llvm-cov report -instr-profile %t.profdata 2>&1 | FileCheck --check-prefix=MISSING-BINARY %s // RUN: not llvm-cov report -instr-profile %t.profdata 2>&1 | FileCheck --check-prefix=MISSING-BINARY %s
// MISSING-BINARY: No filenames specified! // MISSING-BINARY: No filenames specified!

View File

@ -133,7 +133,7 @@ private:
StringMap<std::string> RemappedFilenames; StringMap<std::string> RemappedFilenames;
/// The architecture the coverage mapping data targets. /// The architecture the coverage mapping data targets.
std::string CoverageArch; std::vector<StringRef> CoverageArches;
/// A cache for demangled symbols. /// A cache for demangled symbols.
DemangleCache DC; DemangleCache DC;
@ -329,7 +329,7 @@ std::unique_ptr<CoverageMapping> CodeCoverageTool::load() {
warning("profile data may be out of date - object is newer", warning("profile data may be out of date - object is newer",
ObjectFilename); ObjectFilename);
auto CoverageOrErr = auto CoverageOrErr =
CoverageMapping::load(ObjectFilenames, PGOFilename, CoverageArch); CoverageMapping::load(ObjectFilenames, PGOFilename, CoverageArches);
if (Error E = CoverageOrErr.takeError()) { if (Error E = CoverageOrErr.takeError()) {
error("Failed to load coverage: " + toString(std::move(E)), error("Failed to load coverage: " + toString(std::move(E)),
join(ObjectFilenames.begin(), ObjectFilenames.end(), ", ")); join(ObjectFilenames.begin(), ObjectFilenames.end(), ", "));
@ -499,8 +499,8 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
cl::desc( cl::desc(
"File with the profile data obtained after an instrumented run")); "File with the profile data obtained after an instrumented run"));
cl::opt<std::string> Arch( cl::list<std::string> Arches(
"arch", cl::desc("architecture of the coverage mapping binary")); "arch", cl::desc("architectures of the coverage mapping binaries"));
cl::opt<bool> DebugDump("dump", cl::Optional, cl::opt<bool> DebugDump("dump", cl::Optional,
cl::desc("Show internal debug dump")); cl::desc("Show internal debug dump"));
@ -632,12 +632,19 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
Filters.push_back(std::unique_ptr<CoverageFilter>(StatFilterer)); Filters.push_back(std::unique_ptr<CoverageFilter>(StatFilterer));
} }
if (!Arch.empty() && if (!Arches.empty()) {
Triple(Arch).getArch() == llvm::Triple::ArchType::UnknownArch) { for (const std::string &Arch : Arches) {
error("Unknown architecture: " + Arch); if (Triple(Arch).getArch() == llvm::Triple::ArchType::UnknownArch) {
return 1; error("Unknown architecture: " + Arch);
return 1;
}
CoverageArches.emplace_back(Arch);
}
if (CoverageArches.size() != ObjectFilenames.size()) {
error("Number of architectures doesn't match the number of objects");
return 1;
}
} }
CoverageArch = Arch;
for (const std::string &File : InputSourceFiles) for (const std::string &File : InputSourceFiles)
collectPaths(File); collectPaths(File);