Skip to content

Commit 4b102c3

Browse files
committed
[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
1 parent 5288921 commit 4b102c3

File tree

5 files changed

+39
-19
lines changed

5 files changed

+39
-19
lines changed

llvm/docs/CommandGuide/llvm-cov.rst

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -222,12 +222,13 @@ OPTIONS
222222

223223
Enable or disable color output. By default this is autodetected.
224224

225-
.. option:: -arch=<name>
225+
.. option:: -arch=[*NAMES*]
226226

227-
If the covered binary is a universal binary, select the architecture to use.
228-
It is an error to specify an architecture that is not included in the
229-
universal binary or to use an architecture that does not match a
230-
non-universal binary.
227+
Specify a list of architectures such that the Nth entry in the list
228+
corresponds to the Nth specified binary. If the covered object is a universal
229+
binary, this specifies the architecture to use. It is an error to specify an
230+
architecture that is not included in the universal binary or to use an
231+
architecture that does not match a non-universal binary.
231232

232233
.. option:: -name=<NAME>
233234

llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -449,14 +449,16 @@ class CoverageMapping {
449449
CoverageMapping(const CoverageMapping &) = delete;
450450
CoverageMapping &operator=(const CoverageMapping &) = delete;
451451

452-
/// \brief Load the coverage mapping using the given readers.
452+
/// Load the coverage mapping using the given readers.
453453
static Expected<std::unique_ptr<CoverageMapping>>
454454
load(ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
455455
IndexedInstrProfReader &ProfileReader);
456456

457+
/// Load the coverage mapping from the given object files and profile. If
458+
/// \p Arches is non-empty, it must specify an architecture for each object.
457459
static Expected<std::unique_ptr<CoverageMapping>>
458460
load(ArrayRef<StringRef> ObjectFilenames, StringRef ProfileFilename,
459-
StringRef Arch = StringRef());
461+
ArrayRef<StringRef> Arches = None);
460462

461463
/// \brief The number of functions that couldn't have their profiles mapped.
462464
///

llvm/lib/ProfileData/Coverage/CoverageMapping.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -260,18 +260,19 @@ Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load(
260260

261261
Expected<std::unique_ptr<CoverageMapping>>
262262
CoverageMapping::load(ArrayRef<StringRef> ObjectFilenames,
263-
StringRef ProfileFilename, StringRef Arch) {
263+
StringRef ProfileFilename, ArrayRef<StringRef> Arches) {
264264
auto ProfileReaderOrErr = IndexedInstrProfReader::create(ProfileFilename);
265265
if (Error E = ProfileReaderOrErr.takeError())
266266
return std::move(E);
267267
auto ProfileReader = std::move(ProfileReaderOrErr.get());
268268

269269
SmallVector<std::unique_ptr<CoverageMappingReader>, 4> Readers;
270270
SmallVector<std::unique_ptr<MemoryBuffer>, 4> Buffers;
271-
for (StringRef ObjectFilename : ObjectFilenames) {
272-
auto CovMappingBufOrErr = MemoryBuffer::getFileOrSTDIN(ObjectFilename);
271+
for (const auto &File : llvm::enumerate(ObjectFilenames)) {
272+
auto CovMappingBufOrErr = MemoryBuffer::getFileOrSTDIN(File.value());
273273
if (std::error_code EC = CovMappingBufOrErr.getError())
274274
return errorCodeToError(EC);
275+
StringRef Arch = Arches.empty() ? StringRef() : Arches[File.index()];
275276
auto CoverageReaderOrErr =
276277
BinaryCoverageReader::create(CovMappingBufOrErr.get(), Arch);
277278
if (Error E = CoverageReaderOrErr.takeError())

llvm/test/tools/llvm-cov/universal-binary.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,18 @@ int main(int argc, const char *argv[]) {}
77
// RUN: llvm-cov show %S/Inputs/universal-binary -instr-profile %t.profdata -filename-equivalence %s -arch x86_64 | FileCheck %s
88
// RUN: llvm-cov export %S/Inputs/universal-binary -instr-profile %t.profdata -arch x86_64 2>&1 | FileCheck %S/Inputs/universal-binary.json
99

10+
// 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
11+
// COMBINED: showTemplateInstantiations.cpp
12+
// COMBINED-NEXT: universal-binary.c
1013

1114
// 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
1215
// WRONG-ARCH: Failed to load coverage
1316

17+
// 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
18+
// MADE-UP-ARCH: Unknown architecture: definitly_a_made_up_architecture
19+
20+
// 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
21+
// TOO-MANY-ARCH: Number of architectures doesn't match the number of objects
22+
//
1423
// RUN: not llvm-cov report -instr-profile %t.profdata 2>&1 | FileCheck --check-prefix=MISSING-BINARY %s
1524
// MISSING-BINARY: No filenames specified!

llvm/tools/llvm-cov/CodeCoverage.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ class CodeCoverageTool {
133133
StringMap<std::string> RemappedFilenames;
134134

135135
/// The architecture the coverage mapping data targets.
136-
std::string CoverageArch;
136+
std::vector<StringRef> CoverageArches;
137137

138138
/// A cache for demangled symbols.
139139
DemangleCache DC;
@@ -329,7 +329,7 @@ std::unique_ptr<CoverageMapping> CodeCoverageTool::load() {
329329
warning("profile data may be out of date - object is newer",
330330
ObjectFilename);
331331
auto CoverageOrErr =
332-
CoverageMapping::load(ObjectFilenames, PGOFilename, CoverageArch);
332+
CoverageMapping::load(ObjectFilenames, PGOFilename, CoverageArches);
333333
if (Error E = CoverageOrErr.takeError()) {
334334
error("Failed to load coverage: " + toString(std::move(E)),
335335
join(ObjectFilenames.begin(), ObjectFilenames.end(), ", "));
@@ -499,8 +499,8 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
499499
cl::desc(
500500
"File with the profile data obtained after an instrumented run"));
501501

502-
cl::opt<std::string> Arch(
503-
"arch", cl::desc("architecture of the coverage mapping binary"));
502+
cl::list<std::string> Arches(
503+
"arch", cl::desc("architectures of the coverage mapping binaries"));
504504

505505
cl::opt<bool> DebugDump("dump", cl::Optional,
506506
cl::desc("Show internal debug dump"));
@@ -632,12 +632,19 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
632632
Filters.push_back(std::unique_ptr<CoverageFilter>(StatFilterer));
633633
}
634634

635-
if (!Arch.empty() &&
636-
Triple(Arch).getArch() == llvm::Triple::ArchType::UnknownArch) {
637-
error("Unknown architecture: " + Arch);
638-
return 1;
635+
if (!Arches.empty()) {
636+
for (const std::string &Arch : Arches) {
637+
if (Triple(Arch).getArch() == llvm::Triple::ArchType::UnknownArch) {
638+
error("Unknown architecture: " + Arch);
639+
return 1;
640+
}
641+
CoverageArches.emplace_back(Arch);
642+
}
643+
if (CoverageArches.size() != ObjectFilenames.size()) {
644+
error("Number of architectures doesn't match the number of objects");
645+
return 1;
646+
}
639647
}
640-
CoverageArch = Arch;
641648

642649
for (const std::string &File : InputSourceFiles)
643650
collectPaths(File);

0 commit comments

Comments
 (0)