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:
parent
a8ad1b51ee
commit
95aaeaf3f0
@ -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>
|
||||||
|
|
||||||
|
@ -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.
|
||||||
///
|
///
|
||||||
|
@ -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())
|
||||||
|
@ -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!
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user