Skip to content

Commit a6f8b8a

Browse files
author
Rich Kadel
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

Lines changed: 7 additions & 0 deletions
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 4 additions & 0 deletions
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 11 additions & 1 deletion
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

Lines changed: 3 additions & 0 deletions
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

Lines changed: 6 additions & 5 deletions
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 7 additions & 3 deletions
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)