Skip to content

Commit a6f8b8a

Browse files
committed
Generating the coverage map
rustc now generates the coverage map and can support (limited) coverage report generation, at the function level. Example: $ 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 1| 1|pub fn will_be_called() { 2| 1| println!("called"); 3| 1|} 4| | 5| 0|pub fn will_not_be_called() { 6| 0| println!("should not have been called"); 7| 0|} 8| | 9| 1|fn main() { 10| 1| let less = 1; 11| 1| let more = 100; 12| 1| 13| 1| if less < more { 14| 1| will_be_called(); 15| 1| } else { 16| 1| will_not_be_called(); 17| 1| } 18| 1|}
1 parent c2dbebd commit a6f8b8a

File tree

52 files changed

+1724
-262
lines changed

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
@@ -2788,6 +2788,13 @@ dependencies = [
27882788
"rls-span",
27892789
]
27902790

2791+
[[package]]
2792+
name = "rust-demangler"
2793+
version = "0.0.0"
2794+
dependencies = [
2795+
"rustc-demangle",
2796+
]
2797+
27912798
[[package]]
27922799
name = "rustbook"
27932800
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
@@ -369,6 +369,7 @@ impl<'a> Builder<'a> {
369369
tool::Cargo,
370370
tool::Rls,
371371
tool::RustAnalyzer,
372+
tool::RustDemangler,
372373
tool::Rustdoc,
373374
tool::Clippy,
374375
tool::CargoClippy,

src/bootstrap/test.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1019,6 +1019,10 @@ impl Step for Compiletest {
10191019
cmd.arg("--rustdoc-path").arg(builder.rustdoc(compiler));
10201020
}
10211021

1022+
if mode == "run-make" && suite.ends_with("fulldeps") {
1023+
cmd.arg("--rust-demangler-path").arg(builder.tool_exe(Tool::RustDemangler));
1024+
}
1025+
10221026
cmd.arg("--src-base").arg(builder.src.join("src/test").join(suite));
10231027
cmd.arg("--build-base").arg(testdir(builder, compiler.host).join(suite));
10241028
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
@@ -1957,15 +1957,23 @@ extern "rust-intrinsic" {
19571957
/// Internal placeholder for injecting code coverage counters when the "instrument-coverage"
19581958
/// option is enabled. The placeholder is replaced with `llvm.instrprof.increment` during code
19591959
/// generation.
1960+
#[cfg(not(bootstrap))]
19601961
#[lang = "count_code_region"]
1961-
pub fn count_code_region(index: u32, start_byte_pos: u32, end_byte_pos: u32);
1962+
pub fn count_code_region(
1963+
function_source_hash: u64,
1964+
index: u32,
1965+
start_byte_pos: u32,
1966+
end_byte_pos: u32,
1967+
);
19621968

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