Skip to content

Commit 47ea6d9

Browse files
committed
Auto merge of #74091 - richkadel:llvm-coverage-map-gen-4, r=tmandry
Generating the coverage map @tmandry @wesleywiser rustc now generates the coverage map and can support (limited) coverage report generation, at the function level. Example commands to generate a coverage report: ```shell $ BUILD=$HOME/rust/build/x86_64-unknown-linux-gnu $ $BUILD/stage1/bin/rustc -Zinstrument-coverage \ $HOME/rust/src/test/run-make-fulldeps/instrument-coverage/main.rs $ LLVM_PROFILE_FILE="main.profraw" ./main called $ $BUILD/llvm/bin/llvm-profdata merge -sparse main.profraw -o main.profdata $ $BUILD/llvm/bin/llvm-cov show --instr-profile=main.profdata main ``` ![rust coverage report only 20200706](https://user-images.githubusercontent.com/3827298/86697299-1cbe8f80-bfc3-11ea-8955-451b48626991.png) r? @wesleywiser Rust compiler MCP rust-lang/compiler-team#278 Relevant issue: #34701 - Implement support for LLVMs code coverage instrumentation
2 parents 0701419 + a6f8b8a commit 47ea6d9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1724
-262
lines changed

Cargo.lock

+7
Original file line numberDiff line numberDiff line change
@@ -2821,6 +2821,13 @@ dependencies = [
28212821
"rls-span",
28222822
]
28232823

2824+
[[package]]
2825+
name = "rust-demangler"
2826+
version = "0.0.0"
2827+
dependencies = [
2828+
"rustc-demangle",
2829+
]
2830+
28242831
[[package]]
28252832
name = "rustbook"
28262833
version = "0.1.0"

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ members = [
1717
"src/tools/remote-test-client",
1818
"src/tools/remote-test-server",
1919
"src/tools/rust-installer",
20+
"src/tools/rust-demangler",
2021
"src/tools/cargo",
2122
"src/tools/rustdoc",
2223
"src/tools/rls",

src/bootstrap/builder.rs

+1
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ impl<'a> Builder<'a> {
370370
tool::Cargo,
371371
tool::Rls,
372372
tool::RustAnalyzer,
373+
tool::RustDemangler,
373374
tool::Rustdoc,
374375
tool::Clippy,
375376
tool::CargoClippy,

src/bootstrap/test.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,10 @@ impl Step for Compiletest {
10221022
cmd.arg("--rustdoc-path").arg(builder.rustdoc(compiler));
10231023
}
10241024

1025+
if mode == "run-make" && suite.ends_with("fulldeps") {
1026+
cmd.arg("--rust-demangler-path").arg(builder.tool_exe(Tool::RustDemangler));
1027+
}
1028+
10251029
cmd.arg("--src-base").arg(builder.src.join("src/test").join(suite));
10261030
cmd.arg("--build-base").arg(testdir(builder, compiler.host).join(suite));
10271031
cmd.arg("--stage-id").arg(format!("stage{}-{}", compiler.stage, target));

src/bootstrap/tool.rs

+1
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ bootstrap_tool!(
361361
Compiletest, "src/tools/compiletest", "compiletest", is_unstable_tool = true;
362362
BuildManifest, "src/tools/build-manifest", "build-manifest";
363363
RemoteTestClient, "src/tools/remote-test-client", "remote-test-client";
364+
RustDemangler, "src/tools/rust-demangler", "rust-demangler";
364365
RustInstaller, "src/tools/rust-installer", "fabricate", is_external_tool = true;
365366
RustdocTheme, "src/tools/rustdoc-themes", "rustdoc-themes";
366367
ExpandYamlAnchors, "src/tools/expand-yaml-anchors", "expand-yaml-anchors";

src/libcore/intrinsics.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -1958,15 +1958,23 @@ extern "rust-intrinsic" {
19581958
/// Internal placeholder for injecting code coverage counters when the "instrument-coverage"
19591959
/// option is enabled. The placeholder is replaced with `llvm.instrprof.increment` during code
19601960
/// generation.
1961+
#[cfg(not(bootstrap))]
19611962
#[lang = "count_code_region"]
1962-
pub fn count_code_region(index: u32, start_byte_pos: u32, end_byte_pos: u32);
1963+
pub fn count_code_region(
1964+
function_source_hash: u64,
1965+
index: u32,
1966+
start_byte_pos: u32,
1967+
end_byte_pos: u32,
1968+
);
19631969

19641970
/// Internal marker for code coverage expressions, injected into the MIR when the
19651971
/// "instrument-coverage" option is enabled. This intrinsic is not converted into a
19661972
/// backend intrinsic call, but its arguments are extracted during the production of a
19671973
/// "coverage map", which is injected into the generated code, as additional data.
19681974
/// This marker identifies a code region and two other counters or counter expressions
19691975
/// whose sum is the number of times the code region was executed.
1976+
#[cfg(not(bootstrap))]
1977+
#[lang = "coverage_counter_add"]
19701978
pub fn coverage_counter_add(
19711979
index: u32,
19721980
left_index: u32,
@@ -1978,6 +1986,8 @@ extern "rust-intrinsic" {
19781986
/// This marker identifies a code region and two other counters or counter expressions
19791987
/// whose difference is the number of times the code region was executed.
19801988
/// (See `coverage_counter_add` for more information.)
1989+
#[cfg(not(bootstrap))]
1990+
#[lang = "coverage_counter_subtract"]
19811991
pub fn coverage_counter_subtract(
19821992
index: u32,
19831993
left_index: u32,

src/librustc_codegen_llvm/attributes.rs

+3
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,9 @@ fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
133133
return;
134134
}
135135

136+
// FIXME(richkadel): Make sure probestack plays nice with `-Z instrument-coverage`
137+
// or disable it if not, similar to above early exits.
138+
136139
// Flag our internal `__rust_probestack` function as the stack probe symbol.
137140
// This is defined in the `compiler-builtins` crate for each architecture.
138141
llvm::AddFunctionAttrStringValue(

src/librustc_codegen_llvm/base.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -144,17 +144,18 @@ pub fn compile_codegen_unit(
144144
}
145145
}
146146

147+
// Finalize code coverage by injecting the coverage map. Note, the coverage map will
148+
// also be added to the `llvm.used` variable, created next.
149+
if cx.sess().opts.debugging_opts.instrument_coverage {
150+
cx.coverageinfo_finalize();
151+
}
152+
147153
// Create the llvm.used variable
148154
// This variable has type [N x i8*] and is stored in the llvm.metadata section
149155
if !cx.used_statics().borrow().is_empty() {
150156
cx.create_used_variable()
151157
}
152158

153-
// Finalize code coverage by injecting the coverage map
154-
if cx.sess().opts.debugging_opts.instrument_coverage {
155-
cx.coverageinfo_finalize();
156-
}
157-
158159
// Finalize debuginfo
159160
if cx.sess().opts.debuginfo != DebugInfo::None {
160161
cx.debuginfo_finalize();

src/librustc_codegen_llvm/builder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1060,7 +1060,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
10601060
fn_name, hash, num_counters, index
10611061
);
10621062

1063-
let llfn = unsafe { llvm::LLVMRustGetInstrprofIncrementIntrinsic(self.cx().llmod) };
1063+
let llfn = unsafe { llvm::LLVMRustGetInstrProfIncrementIntrinsic(self.cx().llmod) };
10641064
let args = &[fn_name, hash, num_counters, index];
10651065
let args = self.check_call("call", llfn, args);
10661066

src/librustc_codegen_llvm/consts.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -493,10 +493,14 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> {
493493
}
494494

495495
if attrs.flags.contains(CodegenFnAttrFlags::USED) {
496-
// This static will be stored in the llvm.used variable which is an array of i8*
497-
let cast = llvm::LLVMConstPointerCast(g, self.type_i8p());
498-
self.used_statics.borrow_mut().push(cast);
496+
self.add_used_global(g);
499497
}
500498
}
501499
}
500+
501+
/// Add a global value to a list to be stored in the `llvm.used` variable, an array of i8*.
502+
fn add_used_global(&self, global: &'ll Value) {
503+
let cast = unsafe { llvm::LLVMConstPointerCast(global, self.type_i8p()) };
504+
self.used_statics.borrow_mut().push(cast);
505+
}
502506
}

0 commit comments

Comments
 (0)