@@ -73,10 +73,26 @@ impl CoverageInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
73
73
}
74
74
}
75
75
76
+ /// Functions with MIR-based coverage are normally codegenned _only_ if
77
+ /// called. LLVM coverage tools typically expect every function to be
78
+ /// defined (even if unused), with at least one call to LLVM intrinsic
79
+ /// `instrprof.increment`.
80
+ ///
81
+ /// Codegen a small function that will never be called, with one counter
82
+ /// that will never be incremented.
83
+ ///
84
+ /// For used/called functions, the coverageinfo was already added to the
85
+ /// `function_coverage_map` (keyed by function `Instance`) during codegen.
86
+ /// But in this case, since the unused function was _not_ previously
87
+ /// codegenned, collect the coverage `CodeRegion`s from the MIR and add
88
+ /// them. The first `CodeRegion` is used to add a single counter, with the
89
+ /// same counter ID used in the injected `instrprof.increment` intrinsic
90
+ /// call. Since the function is never called, all other `CodeRegion`s can be
91
+ /// added as `unreachable_region`s.
76
92
fn define_unused_fn ( & self , def_id : DefId ) {
77
93
let instance = declare_unused_fn ( self , & def_id) ;
78
94
codegen_unused_fn_and_counter ( self , instance) ;
79
- add_function_coverage ( self , instance, def_id) ;
95
+ add_unused_function_coverage ( self , instance, def_id) ;
80
96
}
81
97
}
82
98
@@ -200,7 +216,7 @@ fn declare_unused_fn(cx: &CodegenCx<'ll, 'tcx>, def_id: &DefId) -> Instance<'tcx
200
216
llvm:: set_linkage ( llfn, llvm:: Linkage :: WeakAnyLinkage ) ;
201
217
llvm:: set_visibility ( llfn, llvm:: Visibility :: Hidden ) ;
202
218
203
- cx. instances . borrow_mut ( ) . insert ( instance, llfn) ;
219
+ assert ! ( cx. instances. borrow_mut( ) . insert( instance, llfn) . is_none ( ) ) ;
204
220
205
221
instance
206
222
}
@@ -221,7 +237,11 @@ fn codegen_unused_fn_and_counter(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'
221
237
bx. ret_void ( ) ;
222
238
}
223
239
224
- fn add_function_coverage ( cx : & CodegenCx < ' ll , ' tcx > , instance : Instance < ' tcx > , def_id : DefId ) {
240
+ fn add_unused_function_coverage (
241
+ cx : & CodegenCx < ' ll , ' tcx > ,
242
+ instance : Instance < ' tcx > ,
243
+ def_id : DefId ,
244
+ ) {
225
245
let tcx = cx. tcx ;
226
246
227
247
let mut function_coverage = FunctionCoverage :: unused ( tcx, instance) ;
0 commit comments