mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[IRGen] Update coverage mapping for version 6
The coverage format version we use is automatically set to whatever the latest version LLVM has. This resulting in us outputting version 6 as our format without having made the changes necessary to reflect the new format. Update the emission logic to take account for [the new changes in version 6][1] (we need to include the current working directory as the first element of the list of files we output). Additionally, add a `static_assert` so we don't get caught out by version bumps in the future. Note we can't pin our version, as it must stay in sync with the version Clang is using. [1]: https://llvm.org/docs/CoverageMappingFormat.html#llvm-ir-representation
This commit is contained in:
@@ -27,16 +27,24 @@
|
|||||||
#include "llvm/ProfileData/InstrProf.h"
|
#include "llvm/ProfileData/InstrProf.h"
|
||||||
#include "llvm/Support/FileSystem.h"
|
#include "llvm/Support/FileSystem.h"
|
||||||
|
|
||||||
// This selects the coverage mapping format defined when `InstrProfData.inc`
|
|
||||||
// is textually included.
|
|
||||||
#define COVMAP_V3
|
|
||||||
|
|
||||||
using namespace swift;
|
using namespace swift;
|
||||||
using namespace irgen;
|
using namespace irgen;
|
||||||
|
|
||||||
using llvm::coverage::CounterMappingRegion;
|
using llvm::coverage::CounterMappingRegion;
|
||||||
using llvm::coverage::CovMapVersion;
|
using llvm::coverage::CovMapVersion;
|
||||||
|
|
||||||
|
// This affects the coverage mapping format defined when `InstrProfData.inc`
|
||||||
|
// is textually included. Note that it means 'version >= 3', not 'version == 3'.
|
||||||
|
#define COVMAP_V3
|
||||||
|
|
||||||
|
/// This assert is here to make sure we make all the necessary code generation
|
||||||
|
/// changes that are needed to support the new coverage mapping format. Note we
|
||||||
|
/// cannot pin our version, as it must remain in sync with the version Clang is
|
||||||
|
/// using.
|
||||||
|
/// Do not bump without at least filing a bug and pinging a coverage maintainer.
|
||||||
|
static_assert(CovMapVersion::CurrentVersion == CovMapVersion::Version6,
|
||||||
|
"Coverage mapping emission needs updating");
|
||||||
|
|
||||||
static std::string getInstrProfSection(IRGenModule &IGM,
|
static std::string getInstrProfSection(IRGenModule &IGM,
|
||||||
llvm::InstrProfSectKind SK) {
|
llvm::InstrProfSectKind SK) {
|
||||||
return llvm::getInstrProfSectionName(SK, IGM.Triple.getObjectFormat());
|
return llvm::getInstrProfSectionName(SK, IGM.Triple.getObjectFormat());
|
||||||
@@ -77,18 +85,26 @@ void IRGenModule::emitCoverageMaps(ArrayRef<const SILCoverageMap *> Mappings) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<StringRef> Files;
|
std::vector<StringRef> Files;
|
||||||
for (const auto &M : Mappings)
|
for (const auto &M : Mappings) {
|
||||||
if (std::find(Files.begin(), Files.end(), M->getFilename()) == Files.end())
|
if (std::find(Files.begin(), Files.end(), M->getFilename()) == Files.end())
|
||||||
Files.push_back(M->getFilename());
|
Files.push_back(M->getFilename());
|
||||||
|
}
|
||||||
auto remapper = getOptions().CoveragePrefixMap;
|
const auto &Remapper = getOptions().CoveragePrefixMap;
|
||||||
|
|
||||||
llvm::SmallVector<std::string, 8> FilenameStrs;
|
llvm::SmallVector<std::string, 8> FilenameStrs;
|
||||||
for (StringRef Name : Files) {
|
FilenameStrs.reserve(Files.size() + 1);
|
||||||
llvm::SmallString<256> Path(Name);
|
|
||||||
llvm::sys::fs::make_absolute(Path);
|
// First element needs to be the current working directory. Note if this
|
||||||
FilenameStrs.push_back(remapper.remapPath(Path));
|
// scheme ever changes, the FileID computation below will need updating.
|
||||||
}
|
SmallString<256> WorkingDirectory;
|
||||||
|
llvm::sys::fs::current_path(WorkingDirectory);
|
||||||
|
FilenameStrs.emplace_back(Remapper.remapPath(WorkingDirectory));
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
FilenameStrs.emplace_back(Remapper.remapPath(Name));
|
||||||
|
|
||||||
// Encode the filenames.
|
// Encode the filenames.
|
||||||
std::string Filenames;
|
std::string Filenames;
|
||||||
@@ -112,13 +128,21 @@ void IRGenModule::emitCoverageMaps(ArrayRef<const SILCoverageMap *> Mappings) {
|
|||||||
const uint64_t NameHash = llvm::IndexedInstrProf::ComputeHash(NameValue);
|
const uint64_t NameHash = llvm::IndexedInstrProf::ComputeHash(NameValue);
|
||||||
std::string FuncRecordName = "__covrec_" + llvm::utohexstr(NameHash);
|
std::string FuncRecordName = "__covrec_" + llvm::utohexstr(NameHash);
|
||||||
|
|
||||||
unsigned FileID =
|
// The file ID needs to be bumped by 1 to account for the working directory
|
||||||
std::find(Files.begin(), Files.end(), M->getFilename()) - Files.begin();
|
// as the first element.
|
||||||
|
unsigned FileID = 1 +
|
||||||
|
std::find(Files.begin(), Files.end(), M->getFilename()) -
|
||||||
|
Files.begin();
|
||||||
|
assert(FileID < FilenameStrs.size());
|
||||||
|
|
||||||
std::vector<CounterMappingRegion> Regions;
|
std::vector<CounterMappingRegion> Regions;
|
||||||
for (const auto &MR : M->getMappedRegions())
|
for (const auto &MR : M->getMappedRegions()) {
|
||||||
|
// The SubFileID here is 0, because it's an index into VirtualFileMapping,
|
||||||
|
// and we only ever have a single file associated for a function.
|
||||||
Regions.emplace_back(CounterMappingRegion::makeRegion(
|
Regions.emplace_back(CounterMappingRegion::makeRegion(
|
||||||
MR.Counter, /*FileID=*/0, MR.StartLine, MR.StartCol, MR.EndLine,
|
MR.Counter, /*SubFileID*/ 0, MR.StartLine, MR.StartCol, MR.EndLine,
|
||||||
MR.EndCol));
|
MR.EndCol));
|
||||||
|
}
|
||||||
// Append each function's regions into the encoded buffer.
|
// Append each function's regions into the encoded buffer.
|
||||||
ArrayRef<unsigned> VirtualFileMapping(FileID);
|
ArrayRef<unsigned> VirtualFileMapping(FileID);
|
||||||
llvm::coverage::CoverageMappingWriter W(VirtualFileMapping,
|
llvm::coverage::CoverageMappingWriter W(VirtualFileMapping,
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
// To make sure this test is resilient to directory changes, we create nested directories inside of the
|
// 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
|
// temporary test directory and assert those exist, or don't exist, in the emitted ir
|
||||||
//
|
//
|
||||||
// RUN: rm -rf %t
|
// RUN: %empty-directory(%t)
|
||||||
// RUN: mkdir -p %t/root/nested
|
// RUN: mkdir -p %t/root/nested
|
||||||
// RUN: echo "func coverage() {}" > %t/root/nested/coverage_relative_path.swift
|
// RUN: echo "func coverage() {}" > %t/root/nested/coverage_relative_path.swift
|
||||||
// RUN: cd %t/root
|
// RUN: cd %t/root
|
||||||
|
|
||||||
// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -Xllvm -enable-name-compression=false -emit-ir nested/coverage_relative_path.swift | %FileCheck -check-prefix=ABSOLUTE %s
|
// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -Xllvm -enable-name-compression=false -emit-ir nested/coverage_relative_path.swift | %FileCheck -check-prefix=ABSOLUTE %s
|
||||||
//
|
//
|
||||||
// ABSOLUTE: @__llvm_coverage_mapping = {{.*"\\01.*root.*nested.*coverage_relative_path\.swift}}
|
// 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 = {{.*"\\01[^/]*}}.{{/|\\}}nested{{.*coverage_relative_path\.swift}}
|
// RELATIVE: @__llvm_coverage_mapping = {{.*"\\02.*\\01[^/]*\.[/\\]*nested[/\\]*coverage_relative_path\.swift}}
|
||||||
|
|||||||
25
test/Profiler/coverage_relative_path_exec.swift
Normal file
25
test/Profiler/coverage_relative_path_exec.swift
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
// REQUIRES: profile_runtime
|
||||||
|
// REQUIRES: executable_test
|
||||||
|
// REQUIRES: OS=macosx
|
||||||
|
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// CHECK: func coverage
|
||||||
Reference in New Issue
Block a user