Skip to content

[Profiler] Avoid quadratic search for coverage filename in WMO #66053

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 14 additions & 8 deletions lib/IRGen/GenCoverage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,19 @@ void IRGenModule::emitCoverageMaps(ArrayRef<const SILCoverageMap *> Mappings) {
llvm::getCoverageUnusedNamesVarName());
}

std::vector<StringRef> Files;
llvm::DenseMap<StringRef, unsigned> RawFileIndices;
llvm::SmallVector<StringRef, 8> RawFiles;
for (const auto &M : Mappings) {
if (std::find(Files.begin(), Files.end(), M->getFilename()) == Files.end())
Files.push_back(M->getFilename());
auto Filename = M->getFilename();
auto Inserted = RawFileIndices.insert({Filename, RawFiles.size()}).second;
if (!Inserted)
continue;
RawFiles.push_back(Filename);
}
const auto &Remapper = getOptions().CoveragePrefixMap;

llvm::SmallVector<std::string, 8> FilenameStrs;
FilenameStrs.reserve(Files.size() + 1);
FilenameStrs.reserve(RawFiles.size() + 1);

// First element needs to be the current working directory. Note if this
// scheme ever changes, the FileID computation below will need updating.
Expand All @@ -103,7 +107,7 @@ void IRGenModule::emitCoverageMaps(ArrayRef<const SILCoverageMap *> Mappings) {
// Following elements are the filenames present. We use their relative path,
// which llvm-cov will turn back into absolute paths using the working
// directory element.
for (auto Name : Files)
for (auto Name : RawFiles)
FilenameStrs.emplace_back(Remapper.remapPath(Name));

// Encode the filenames.
Expand All @@ -130,9 +134,11 @@ void IRGenModule::emitCoverageMaps(ArrayRef<const SILCoverageMap *> Mappings) {

// The file ID needs to be bumped by 1 to account for the working directory
// as the first element.
unsigned FileID = 1 +
std::find(Files.begin(), Files.end(), M->getFilename()) -
Files.begin();
unsigned FileID = [&]() {
auto Result = RawFileIndices.find(M->getFilename());
assert(Result != RawFileIndices.end());
return Result->second + 1;
}();
assert(FileID < FilenameStrs.size());

std::vector<CounterMappingRegion> Regions;
Expand Down
2 changes: 1 addition & 1 deletion test/Profiler/coverage_relative_path.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@
//
// ABSOLUTE: @__llvm_coverage_mapping = {{.*"\\02.*root[^/\\]*nested[/\\]*coverage_relative_path\.swift}}

// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -Xllvm -enable-name-compression=false -coverage-prefix-map %/t/root=. -emit-ir %/t/root/nested/coverage_relative_path.swift | %FileCheck -check-prefix=RELATIVE %s
// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -Xllvm -enable-name-compression=false -coverage-prefix-map %t/root=. -emit-ir %t/root/nested/coverage_relative_path.swift | %FileCheck -check-prefix=RELATIVE %s
//
// RELATIVE: @__llvm_coverage_mapping = {{.*"\\02.*\\01[^/]*\.[/\\]*nested[/\\]*coverage_relative_path\.swift}}
12 changes: 7 additions & 5 deletions test/Profiler/coverage_relative_path_exec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,24 @@

// This test is to make sure llvm-cov can deal with a coverage-prefix-map.

// To make sure this test is resilient to directory changes, we create nested directories inside of the
// temporary test directory and assert those exist, or don't exist, in the emitted ir
// To make sure this test is resilient to directory changes, we create nested
// directories inside of the temporary test directory.
//
// RUN: %empty-directory(%t)
// RUN: mkdir -p %t/root/nested
// RUN: echo "func coverage() {}" > %t/root/nested/coverage_relative_path.swift
// RUN: cd %t/root

// RUN: %target-build-swift -profile-generate -profile-coverage-mapping -Xfrontend -coverage-prefix-map -Xfrontend %/t/root=. -Xfrontend -disable-incremental-llvm-codegen -o %t/main %/t/root/nested/coverage_relative_path.swift
// RUN: %target-build-swift -profile-generate -profile-coverage-mapping -Xfrontend -coverage-prefix-map -Xfrontend %t/root=. -Xfrontend -disable-incremental-llvm-codegen -o %t/main %t/root/nested/coverage_relative_path.swift

// This unusual use of 'sh' allows the path of the profraw file to be
// substituted by %target-run.
// RUN: %target-codesign %t/main
// RUN: %target-run sh -c 'env LLVM_PROFILE_FILE=$1 $2' -- %t/default.profraw %t/main

// RUN: %llvm-profdata merge %t/default.profraw -o %t/default.profdata
// RUN: %llvm-cov show %t/main -instr-profile=%t/default.profdata | %FileCheck %s
// RUN: %llvm-cov show %t/main -instr-profile=%t/default.profdata | %FileCheck --check-prefix SHOW %s
// RUN: %llvm-cov report %t/main -instr-profile=%t/default.profdata | %FileCheck --check-prefix REPORT %s

// CHECK: func coverage
// SHOW: func coverage
// REPORT: coverage_relative_path.swift