[llvm] 5042e1e - [llvm-cov] Allow multiple remaps in --path-equivalence
Keith Smiley via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 23 15:28:08 PDT 2023
Author: Tomas Camin
Date: 2023-08-23T15:27:56-07:00
New Revision: 5042e1e56d39a02517abecbe00e72eea698d309a
URL: https://github.com/llvm/llvm-project/commit/5042e1e56d39a02517abecbe00e72eea698d309a
DIFF: https://github.com/llvm/llvm-project/commit/5042e1e56d39a02517abecbe00e72eea698d309a.diff
LOG: [llvm-cov] Allow multiple remaps in --path-equivalence
Previously the --path-equivalence parameter would allow to specify a single remap pair (coverage data path - local source file path). This patch changes this allowing to pass as many remaps as needed.
Reviewed By: keith
Differential Revision: https://reviews.llvm.org/D154223
Added:
llvm/test/tools/llvm-cov/Inputs/multiple-path_equivalence.covmapping
llvm/test/tools/llvm-cov/Inputs/multiple-path_equivalence.proftext
llvm/test/tools/llvm-cov/multiple-path_equivalence.test
Modified:
llvm/docs/CommandGuide/llvm-cov.rst
llvm/test/tools/llvm-cov/path_equivalence.c
llvm/tools/llvm-cov/CodeCoverage.cpp
Removed:
################################################################################
diff --git a/llvm/docs/CommandGuide/llvm-cov.rst b/llvm/docs/CommandGuide/llvm-cov.rst
index 44bb135371512a..792f9629dbfbd0 100644
--- a/llvm/docs/CommandGuide/llvm-cov.rst
+++ b/llvm/docs/CommandGuide/llvm-cov.rst
@@ -340,7 +340,11 @@ OPTIONS
Map the paths in the coverage data to local source file paths. This allows you
to generate the coverage data on one machine, and then use llvm-cov on a
-
diff erent machine where you have the same files on a
diff erent path.
+
diff erent machine where you have the same files on a
diff erent path. Multiple
+ `-path-equivalence` arguments can be passed to specify
diff erent mappings. Each
+ argument consists of a source path `<from>` and its corresponding local path `<to>`.
+ The mappings are applied in the order they are specified. If multiple mappings can
+ be applied to a single path, the first mapping encountered is used.
.. option:: -coverage-watermark=<high>,<low>
diff --git a/llvm/test/tools/llvm-cov/Inputs/multiple-path_equivalence.covmapping b/llvm/test/tools/llvm-cov/Inputs/multiple-path_equivalence.covmapping
new file mode 100644
index 00000000000000..3e229a8c301a75
Binary files /dev/null and b/llvm/test/tools/llvm-cov/Inputs/multiple-path_equivalence.covmapping
diff er
diff --git a/llvm/test/tools/llvm-cov/Inputs/multiple-path_equivalence.proftext b/llvm/test/tools/llvm-cov/Inputs/multiple-path_equivalence.proftext
new file mode 100644
index 00000000000000..1be93b71b77a7f
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/Inputs/multiple-path_equivalence.proftext
@@ -0,0 +1,19 @@
+f1
+0x0
+1
+1
+
+f2
+0x0
+1
+1
+
+f3
+0x0
+1
+1
+
+f4
+0x0
+1
+1
diff --git a/llvm/test/tools/llvm-cov/multiple-path_equivalence.test b/llvm/test/tools/llvm-cov/multiple-path_equivalence.test
new file mode 100644
index 00000000000000..1c8ec9a82a81cf
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/multiple-path_equivalence.test
@@ -0,0 +1,32 @@
+# multiple-path_equivalence.covmapping contains references to 4 files:
+# /tmp/coverage/main.c
+# /tmp/coverage/f1.c
+# /tmp/coverage/a/f2.c
+# /tmp/coverage/b/f3.c
+# /tmp/coverage/b/c/f4.c
+
+# Setup
+// RUN: touch %/T/main.c; touch %/T/f1.c; touch %/T/f2.c; touch %/T/f3.c; touch %/T/f4.c
+// RUN: llvm-profdata merge %S/Inputs/multiple-path_equivalence.proftext -o %t.profdata
+
+# Make sure that remapping follows the specified order with the first matching entry being used first (f4 comes before f3)
+// RUN: llvm-cov show %S/Inputs/multiple-path_equivalence.covmapping -instr-profile=%t.profdata -path-equivalence=/tmp/coverage/a,%/T -path-equivalence=/tmp/coverage/b/c,%/T -path-equivalence=/tmp/coverage/b,%/T -path-equivalence=/tmp/coverage,%/T 2>&1 | FileCheck %s
+
+// CHECK-DAG: {{/|\\}}tmp{{/|\\}}coverage{{/|\\}}main.c:
+// CHECK-DAG: {{/|\\}}tmp{{/|\\}}coverage{{/|\\}}f1.c:
+// CHECK-DAG: {{/|\\}}tmp{{/|\\}}coverage{{/|\\}}a{{/|\\}}f2.c:
+// CHECK-DAG: {{/|\\}}tmp{{/|\\}}coverage{{/|\\}}b{{/|\\}}f3.c:
+// CHECK-DAG: {{/|\\}}tmp{{/|\\}}coverage{{/|\\}}b{{/|\\}}c{{/|\\}}f4.c:
+// CHECK-NOT: isn't covered.
+
+# Make sure remapping follows the specified order by proving paths in an overriding order (f4 comes after f3)
+// RUN: llvm-cov show %S/Inputs/multiple-path_equivalence.covmapping -instr-profile=%t.profdata -path-equivalence=/tmp/coverage/a,%/T -path-equivalence=/tmp/coverage/b,%/T -path-equivalence=/tmp/coverage/b/c,%/T -path-equivalence=/tmp/coverage,%/T 2>&1 | FileCheck %s -check-prefix=OVERRIDING_ORDER
+
+// OVERRIDING_ORDER-DAG: {{/|\\}}tmp{{/|\\}}coverage{{/|\\}}main.c:
+// OVERRIDING_ORDER-DAG: {{/|\\}}tmp{{/|\\}}coverage{{/|\\}}f1.c:
+// OVERRIDING_ORDER-DAG: {{/|\\}}tmp{{/|\\}}coverage{{/|\\}}a{{/|\\}}f2.c:
+// OVERRIDING_ORDER-DAG: {{/|\\}}tmp{{/|\\}}coverage{{/|\\}}b{{/|\\}}f3.c:
+// OVERRIDING_ORDER-DAG: warning: The file '{{/|\\}}tmp{{/|\\}}coverage{{/|\\}}b{{/|\\}}c{{/|\\}}f4.c' isn't covered.
+
+// RUN: not llvm-cov show %S/Inputs/multiple-path_equivalence.covmapping -instr-profile=%t.profdata -path-equivalence=/tmp/coverage/a,%/T -path-equivalence=/tmp/coverage/b, -path-equivalence=/tmp/coverage/b/c,%/T -path-equivalence=/tmp/coverage,%/T 2>&1 | FileCheck %s -check-prefix=EMPTY_PATH
+// EMPTY_PATH: must be in format 'from,to'
\ No newline at end of file
diff --git a/llvm/test/tools/llvm-cov/path_equivalence.c b/llvm/test/tools/llvm-cov/path_equivalence.c
index 26a35b78d2d743..38422ce5600842 100644
--- a/llvm/test/tools/llvm-cov/path_equivalence.c
+++ b/llvm/test/tools/llvm-cov/path_equivalence.c
@@ -5,3 +5,6 @@ int main() {} // CHECK: [[@LINE]]| 1|int main() {}
// RUN: not llvm-cov show --instr-profile=/dev/null -path-equivalence=foo /dev/null 2>&1 | FileCheck --check-prefix=INVALID %s
// INVALID: error: -path-equivalence: invalid argument 'foo', must be in format 'from,to'
+
+// RUN: not llvm-cov show --instr-profile=/dev/null -path-equivalence=,foo /dev/null 2>&1 | FileCheck --check-prefix=EMPTY_PATH %s
+// EMPTY_PATH: error: -path-equivalence: invalid argument ',foo', must be in format 'from,to'
diff --git a/llvm/tools/llvm-cov/CodeCoverage.cpp b/llvm/tools/llvm-cov/CodeCoverage.cpp
index 02448dcd31a161..3992dfa8932c35 100644
--- a/llvm/tools/llvm-cov/CodeCoverage.cpp
+++ b/llvm/tools/llvm-cov/CodeCoverage.cpp
@@ -162,7 +162,8 @@ class CodeCoverageTool {
/// The coverage data path to be remapped from, and the source path to be
/// remapped to, when using -path-equivalence.
- std::optional<std::pair<std::string, std::string>> PathRemapping;
+ std::optional<std::vector<std::pair<std::string, std::string>>>
+ PathRemappings;
/// File status cache used when finding the same file.
StringMap<std::optional<sys::fs::file_status>> FileStatusCache;
@@ -228,7 +229,7 @@ void CodeCoverageTool::collectPaths(const std::string &Path) {
llvm::sys::fs::file_status Status;
llvm::sys::fs::status(Path, Status);
if (!llvm::sys::fs::exists(Status)) {
- if (PathRemapping)
+ if (PathRemappings)
addCollectedPath(Path);
else
warning("Source file doesn't exist, proceeded by ignoring it.", Path);
@@ -474,7 +475,7 @@ std::unique_ptr<CoverageMapping> CodeCoverageTool::load() {
}
void CodeCoverageTool::remapPathNames(const CoverageMapping &Coverage) {
- if (!PathRemapping)
+ if (!PathRemappings)
return;
// Convert remapping paths to native paths with trailing seperators.
@@ -488,17 +489,23 @@ void CodeCoverageTool::remapPathNames(const CoverageMapping &Coverage) {
NativePath += sys::path::get_separator();
return NativePath.c_str();
};
- std::string RemapFrom = nativeWithTrailing(PathRemapping->first);
- std::string RemapTo = nativeWithTrailing(PathRemapping->second);
- // Create a mapping from coverage data file paths to local paths.
- for (StringRef Filename : Coverage.getUniqueSourceFiles()) {
- SmallString<128> NativeFilename;
- sys::path::native(Filename, NativeFilename);
- sys::path::remove_dots(NativeFilename, true);
- if (NativeFilename.startswith(RemapFrom)) {
- RemappedFilenames[Filename] =
- RemapTo + NativeFilename.substr(RemapFrom.size()).str();
+ for (std::pair<std::string, std::string> &PathRemapping : *PathRemappings) {
+ std::string RemapFrom = nativeWithTrailing(PathRemapping.first);
+ std::string RemapTo = nativeWithTrailing(PathRemapping.second);
+
+ // Create a mapping from coverage data file paths to local paths.
+ for (StringRef Filename : Coverage.getUniqueSourceFiles()) {
+ if (RemappedFilenames.count(Filename) == 1)
+ continue;
+
+ SmallString<128> NativeFilename;
+ sys::path::native(Filename, NativeFilename);
+ sys::path::remove_dots(NativeFilename, true);
+ if (NativeFilename.startswith(RemapFrom)) {
+ RemappedFilenames[Filename] =
+ RemapTo + NativeFilename.substr(RemapFrom.size()).str();
+ }
}
}
@@ -674,7 +681,7 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
"lcov tracefile output")),
cl::init(CoverageViewOptions::OutputFormat::Text));
- cl::opt<std::string> PathRemap(
+ cl::list<std::string> PathRemaps(
"path-equivalence", cl::Optional,
cl::desc("<from>,<to> Map coverage data paths to local source file "
"paths"));
@@ -812,19 +819,23 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
break;
}
- // If path-equivalence was given and is a comma seperated pair then set
- // PathRemapping.
- if (!PathRemap.empty()) {
- auto EquivPair = StringRef(PathRemap).split(',');
- if (EquivPair.first.empty() || EquivPair.second.empty()) {
- error("invalid argument '" + PathRemap +
- "', must be in format 'from,to'",
- "-path-equivalence");
- return 1;
+ if (!PathRemaps.empty()) {
+ std::vector<std::pair<std::string, std::string>> Remappings;
+
+ for (const std::string &PathRemap : PathRemaps) {
+ auto EquivPair = StringRef(PathRemap).split(',');
+ if (EquivPair.first.empty() || EquivPair.second.empty()) {
+ error("invalid argument '" + PathRemap +
+ "', must be in format 'from,to'",
+ "-path-equivalence");
+ return 1;
+ }
+
+ Remappings.push_back(
+ {std::string(EquivPair.first), std::string(EquivPair.second)});
}
- PathRemapping = {std::string(EquivPair.first),
- std::string(EquivPair.second)};
+ PathRemappings = Remappings;
}
// If a demangler is supplied, check if it exists and register it.
More information about the llvm-commits
mailing list