11use crate :: llvm;
22
3- use crate :: abi:: Abi ;
43use crate :: builder:: Builder ;
54use crate :: common:: CodegenCx ;
65use crate :: coverageinfo:: ffi:: { CounterExpression , CounterMappingRegion } ;
@@ -12,25 +11,19 @@ use rustc_codegen_ssa::traits::{
1211 StaticMethods ,
1312} ;
1413use rustc_data_structures:: fx:: FxHashMap ;
15- use rustc_hir as hir;
16- use rustc_hir:: def_id:: DefId ;
1714use rustc_llvm:: RustString ;
1815use rustc_middle:: bug;
19- use rustc_middle:: mir:: coverage:: { CounterId , CoverageKind } ;
16+ use rustc_middle:: mir:: coverage:: CoverageKind ;
2017use 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 ;
2419use rustc_middle:: ty:: Instance ;
25- use rustc_middle:: ty:: Ty ;
2620
2721use std:: cell:: RefCell ;
2822
2923pub ( crate ) mod ffi;
3024pub ( crate ) mod map_data;
3125pub mod mapgen;
32-
33- const UNUSED_FUNCTION_COUNTER_ID : CounterId = CounterId :: START ;
26+ mod unused;
3427
3528const VAR_ALIGN_BYTES : usize = 8 ;
3629
@@ -76,28 +69,6 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
7669 bug ! ( "Could not get the `coverage_context`" ) ;
7770 }
7871 }
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- }
10172}
10273
10374impl < ' tcx > CoverageInfoBuilderMethods < ' tcx > for Builder < ' _ , ' _ , ' tcx > {
@@ -165,85 +136,6 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
165136 }
166137}
167138
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-
247139/// Calls llvm::createPGOFuncNameVar() with the given function instance's
248140/// mangled function name. The LLVM API returns an llvm::GlobalVariable
249141/// containing the function name, with the specific variable name and linkage
0 commit comments