1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +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.
.. option:: -arch=<name>
.. option:: -arch=[*NAMES*]
If the covered binary is a universal binary, select the architecture to use.
It is an error to specify an architecture that is not included in the
universal binary or to use an architecture that does not match a
non-universal binary.
Specify a list of architectures such that the Nth entry in the list
corresponds to the Nth specified binary. If the covered object is a universal
binary, this specifies the architecture to use. It is an error to specify an
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>

View File

@ -449,14 +449,16 @@ public:
CoverageMapping(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>>
load(ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
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>>
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.
///

View File

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

View File

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