1
1
use crate :: llvm;
2
2
3
- use crate :: abi:: Abi ;
4
3
use crate :: builder:: Builder ;
5
4
use crate :: common:: CodegenCx ;
6
5
use crate :: coverageinfo:: ffi:: { CounterExpression , CounterMappingRegion } ;
@@ -12,25 +11,19 @@ use rustc_codegen_ssa::traits::{
12
11
StaticMethods ,
13
12
} ;
14
13
use rustc_data_structures:: fx:: FxHashMap ;
15
- use rustc_hir as hir;
16
- use rustc_hir:: def_id:: DefId ;
17
14
use rustc_llvm:: RustString ;
18
15
use rustc_middle:: bug;
19
- use rustc_middle:: mir:: coverage:: { CounterId , CoverageKind } ;
16
+ use rustc_middle:: mir:: coverage:: CoverageKind ;
20
17
use rustc_middle:: mir:: Coverage ;
21
- use rustc_middle:: ty;
22
- use rustc_middle:: ty:: layout:: { FnAbiOf , HasTyCtxt } ;
23
- use rustc_middle:: ty:: GenericArgs ;
18
+ use rustc_middle:: ty:: layout:: HasTyCtxt ;
24
19
use rustc_middle:: ty:: Instance ;
25
- use rustc_middle:: ty:: Ty ;
26
20
27
21
use std:: cell:: RefCell ;
28
22
29
23
pub ( crate ) mod ffi;
30
24
pub ( crate ) mod map_data;
31
25
pub mod mapgen;
32
-
33
- const UNUSED_FUNCTION_COUNTER_ID : CounterId = CounterId :: START ;
26
+ mod unused;
34
27
35
28
const VAR_ALIGN_BYTES : usize = 8 ;
36
29
@@ -76,28 +69,6 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
76
69
bug ! ( "Could not get the `coverage_context`" ) ;
77
70
}
78
71
}
79
-
80
- /// Functions with MIR-based coverage are normally codegenned _only_ if
81
- /// called. LLVM coverage tools typically expect every function to be
82
- /// defined (even if unused), with at least one call to LLVM intrinsic
83
- /// `instrprof.increment`.
84
- ///
85
- /// Codegen a small function that will never be called, with one counter
86
- /// that will never be incremented.
87
- ///
88
- /// For used/called functions, the coverageinfo was already added to the
89
- /// `function_coverage_map` (keyed by function `Instance`) during codegen.
90
- /// But in this case, since the unused function was _not_ previously
91
- /// codegenned, collect the coverage `CodeRegion`s from the MIR and add
92
- /// them. The first `CodeRegion` is used to add a single counter, with the
93
- /// same counter ID used in the injected `instrprof.increment` intrinsic
94
- /// call. Since the function is never called, all other `CodeRegion`s can be
95
- /// added as `unreachable_region`s.
96
- fn define_unused_fn ( & self , def_id : DefId ) {
97
- let instance = declare_unused_fn ( self , def_id) ;
98
- codegen_unused_fn_and_counter ( self , instance) ;
99
- add_unused_function_coverage ( self , instance, def_id) ;
100
- }
101
72
}
102
73
103
74
impl < ' tcx > CoverageInfoBuilderMethods < ' tcx > for Builder < ' _ , ' _ , ' tcx > {
@@ -165,85 +136,6 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
165
136
}
166
137
}
167
138
168
- fn declare_unused_fn < ' tcx > ( cx : & CodegenCx < ' _ , ' tcx > , def_id : DefId ) -> Instance < ' tcx > {
169
- let tcx = cx. tcx ;
170
-
171
- let instance = Instance :: new (
172
- def_id,
173
- GenericArgs :: for_item ( tcx, def_id, |param, _| {
174
- if let ty:: GenericParamDefKind :: Lifetime = param. kind {
175
- tcx. lifetimes . re_erased . into ( )
176
- } else {
177
- tcx. mk_param_from_def ( param)
178
- }
179
- } ) ,
180
- ) ;
181
-
182
- let llfn = cx. declare_fn (
183
- tcx. symbol_name ( instance) . name ,
184
- cx. fn_abi_of_fn_ptr (
185
- ty:: Binder :: dummy ( tcx. mk_fn_sig (
186
- [ Ty :: new_unit ( tcx) ] ,
187
- Ty :: new_unit ( tcx) ,
188
- false ,
189
- hir:: Unsafety :: Unsafe ,
190
- Abi :: Rust ,
191
- ) ) ,
192
- ty:: List :: empty ( ) ,
193
- ) ,
194
- None ,
195
- ) ;
196
-
197
- llvm:: set_linkage ( llfn, llvm:: Linkage :: PrivateLinkage ) ;
198
- llvm:: set_visibility ( llfn, llvm:: Visibility :: Default ) ;
199
-
200
- assert ! ( cx. instances. borrow_mut( ) . insert( instance, llfn) . is_none( ) ) ;
201
-
202
- instance
203
- }
204
-
205
- fn codegen_unused_fn_and_counter < ' tcx > ( cx : & CodegenCx < ' _ , ' tcx > , instance : Instance < ' tcx > ) {
206
- let llfn = cx. get_fn ( instance) ;
207
- let llbb = Builder :: append_block ( cx, llfn, "unused_function" ) ;
208
- let mut bx = Builder :: build ( cx, llbb) ;
209
- let fn_name = bx. get_pgo_func_name_var ( instance) ;
210
- let hash = bx. const_u64 ( 0 ) ;
211
- let num_counters = bx. const_u32 ( 1 ) ;
212
- let index = bx. const_u32 ( u32:: from ( UNUSED_FUNCTION_COUNTER_ID ) ) ;
213
- debug ! (
214
- "codegen intrinsic instrprof.increment(fn_name={:?}, hash={:?}, num_counters={:?},
215
- index={:?}) for unused function: {:?}" ,
216
- fn_name, hash, num_counters, index, instance
217
- ) ;
218
- bx. instrprof_increment ( fn_name, hash, num_counters, index) ;
219
- bx. ret_void ( ) ;
220
- }
221
-
222
- fn add_unused_function_coverage < ' tcx > (
223
- cx : & CodegenCx < ' _ , ' tcx > ,
224
- instance : Instance < ' tcx > ,
225
- def_id : DefId ,
226
- ) {
227
- let tcx = cx. tcx ;
228
-
229
- let mut function_coverage = FunctionCoverage :: unused ( tcx, instance) ;
230
- for ( index, & code_region) in tcx. covered_code_regions ( def_id) . iter ( ) . enumerate ( ) {
231
- if index == 0 {
232
- // Insert at least one real counter so the LLVM CoverageMappingReader will find expected
233
- // definitions.
234
- function_coverage. add_counter ( UNUSED_FUNCTION_COUNTER_ID , code_region. clone ( ) ) ;
235
- } else {
236
- function_coverage. add_unreachable_region ( code_region. clone ( ) ) ;
237
- }
238
- }
239
-
240
- if let Some ( coverage_context) = cx. coverage_context ( ) {
241
- coverage_context. function_coverage_map . borrow_mut ( ) . insert ( instance, function_coverage) ;
242
- } else {
243
- bug ! ( "Could not get the `coverage_context`" ) ;
244
- }
245
- }
246
-
247
139
/// Calls llvm::createPGOFuncNameVar() with the given function instance's
248
140
/// mangled function name. The LLVM API returns an llvm::GlobalVariable
249
141
/// containing the function name, with the specific variable name and linkage
0 commit comments