From 0859cec65255e34221b3b443f4bdd751549fd4c3 Mon Sep 17 00:00:00 2001 From: Rich Kadel Date: Tue, 23 Mar 2021 14:25:52 -0700 Subject: Changes from review comments --- .../rustc_codegen_llvm/src/coverageinfo/mod.rs | 26 +++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'compiler/rustc_codegen_llvm/src') diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs index 2854717bb6e..32f4fc76b3d 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs @@ -73,10 +73,26 @@ impl CoverageInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { } } + /// Functions with MIR-based coverage are normally codegenned _only_ if + /// called. LLVM coverage tools typically expect every function to be + /// defined (even if unused), with at least one call to LLVM intrinsic + /// `instrprof.increment`. + /// + /// Codegen a small function that will never be called, with one counter + /// that will never be incremented. + /// + /// For used/called functions, the coverageinfo was already added to the + /// `function_coverage_map` (keyed by function `Instance`) during codegen. + /// But in this case, since the unused function was _not_ previously + /// codegenned, collect the coverage `CodeRegion`s from the MIR and add + /// them. The first `CodeRegion` is used to add a single counter, with the + /// same counter ID used in the injected `instrprof.increment` intrinsic + /// call. Since the function is never called, all other `CodeRegion`s can be + /// added as `unreachable_region`s. fn define_unused_fn(&self, def_id: DefId) { let instance = declare_unused_fn(self, &def_id); codegen_unused_fn_and_counter(self, instance); - add_function_coverage(self, instance, def_id); + add_unused_function_coverage(self, instance, def_id); } } @@ -200,7 +216,7 @@ fn declare_unused_fn(cx: &CodegenCx<'ll, 'tcx>, def_id: &DefId) -> Instance<'tcx llvm::set_linkage(llfn, llvm::Linkage::WeakAnyLinkage); llvm::set_visibility(llfn, llvm::Visibility::Hidden); - cx.instances.borrow_mut().insert(instance, llfn); + assert!(cx.instances.borrow_mut().insert(instance, llfn).is_none()); instance } @@ -221,7 +237,11 @@ fn codegen_unused_fn_and_counter(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<' bx.ret_void(); } -fn add_function_coverage(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>, def_id: DefId) { +fn add_unused_function_coverage( + cx: &CodegenCx<'ll, 'tcx>, + instance: Instance<'tcx>, + def_id: DefId, +) { let tcx = cx.tcx; let mut function_coverage = FunctionCoverage::unused(tcx, instance); -- cgit 1.4.1-3-g733a5