1
1
use std:: cell:: { OnceCell , RefCell } ;
2
2
use std:: ffi:: { CStr , CString } ;
3
3
4
- use libc:: c_uint;
5
4
use rustc_abi:: Size ;
6
5
use rustc_codegen_ssa:: traits:: {
7
6
BuilderMethods , ConstCodegenMethods , CoverageInfoBuilderMethods , MiscCodegenMethods ,
8
7
} ;
9
8
use rustc_data_structures:: fx:: { FxHashMap , FxIndexMap } ;
10
- use rustc_llvm:: RustString ;
11
9
use rustc_middle:: mir:: coverage:: CoverageKind ;
12
10
use rustc_middle:: ty:: Instance ;
13
11
use rustc_middle:: ty:: layout:: HasTyCtxt ;
14
12
use tracing:: { debug, instrument} ;
15
13
16
14
use crate :: builder:: Builder ;
17
- use crate :: common:: { AsCCharPtr , CodegenCx } ;
15
+ use crate :: common:: CodegenCx ;
18
16
use crate :: coverageinfo:: map_data:: FunctionCoverageCollector ;
19
17
use crate :: llvm;
20
18
21
19
pub ( crate ) mod ffi;
20
+ mod llvm_cov;
22
21
pub ( crate ) mod map_data;
23
22
mod mapgen;
24
23
@@ -80,12 +79,9 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
80
79
/// - `__LLVM_COV,__llvm_covfun` on macOS (includes `__LLVM_COV,` segment prefix)
81
80
/// - `.lcovfun$M` on Windows (includes `$M` sorting suffix)
82
81
fn covfun_section_name ( & self ) -> & CStr {
83
- self . coverage_cx ( ) . covfun_section_name . get_or_init ( || {
84
- CString :: new ( llvm:: build_byte_buffer ( |s| unsafe {
85
- llvm:: LLVMRustCoverageWriteFuncSectionNameToString ( self . llmod , s) ;
86
- } ) )
87
- . expect ( "covfun section name should not contain NUL" )
88
- } )
82
+ self . coverage_cx ( )
83
+ . covfun_section_name
84
+ . get_or_init ( || llvm_cov:: covfun_section_name ( self . llmod ) )
89
85
}
90
86
91
87
/// For LLVM codegen, returns a function-specific `Value` for a global
@@ -95,9 +91,11 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
95
91
fn get_pgo_func_name_var ( & self , instance : Instance < ' tcx > ) -> & ' ll llvm:: Value {
96
92
debug ! ( "getting pgo_func_name_var for instance={:?}" , instance) ;
97
93
let mut pgo_func_name_var_map = self . coverage_cx ( ) . pgo_func_name_var_map . borrow_mut ( ) ;
98
- pgo_func_name_var_map
99
- . entry ( instance)
100
- . or_insert_with ( || create_pgo_func_name_var ( self , instance) )
94
+ pgo_func_name_var_map. entry ( instance) . or_insert_with ( || {
95
+ let llfn = self . get_fn ( instance) ;
96
+ let mangled_fn_name: & str = self . tcx . symbol_name ( instance) . name ;
97
+ llvm_cov:: create_pgo_func_name_var ( llfn, mangled_fn_name)
98
+ } )
101
99
}
102
100
}
103
101
@@ -225,80 +223,3 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
225
223
}
226
224
}
227
225
}
228
-
229
- /// Calls llvm::createPGOFuncNameVar() with the given function instance's
230
- /// mangled function name. The LLVM API returns an llvm::GlobalVariable
231
- /// containing the function name, with the specific variable name and linkage
232
- /// required by LLVM InstrProf source-based coverage instrumentation. Use
233
- /// `bx.get_pgo_func_name_var()` to ensure the variable is only created once per
234
- /// `Instance`.
235
- fn create_pgo_func_name_var < ' ll , ' tcx > (
236
- cx : & CodegenCx < ' ll , ' tcx > ,
237
- instance : Instance < ' tcx > ,
238
- ) -> & ' ll llvm:: Value {
239
- let mangled_fn_name: & str = cx. tcx . symbol_name ( instance) . name ;
240
- let llfn = cx. get_fn ( instance) ;
241
- unsafe {
242
- llvm:: LLVMRustCoverageCreatePGOFuncNameVar (
243
- llfn,
244
- mangled_fn_name. as_c_char_ptr ( ) ,
245
- mangled_fn_name. len ( ) ,
246
- )
247
- }
248
- }
249
-
250
- pub ( crate ) fn write_filenames_section_to_buffer < ' a > (
251
- filenames : impl IntoIterator < Item = & ' a str > ,
252
- buffer : & RustString ,
253
- ) {
254
- let ( pointers, lengths) = filenames
255
- . into_iter ( )
256
- . map ( |s : & str | ( s. as_c_char_ptr ( ) , s. len ( ) ) )
257
- . unzip :: < _ , _ , Vec < _ > , Vec < _ > > ( ) ;
258
-
259
- unsafe {
260
- llvm:: LLVMRustCoverageWriteFilenamesSectionToBuffer (
261
- pointers. as_ptr ( ) ,
262
- pointers. len ( ) ,
263
- lengths. as_ptr ( ) ,
264
- lengths. len ( ) ,
265
- buffer,
266
- ) ;
267
- }
268
- }
269
-
270
- pub ( crate ) fn write_mapping_to_buffer (
271
- virtual_file_mapping : Vec < u32 > ,
272
- expressions : Vec < ffi:: CounterExpression > ,
273
- code_regions : & [ ffi:: CodeRegion ] ,
274
- branch_regions : & [ ffi:: BranchRegion ] ,
275
- mcdc_branch_regions : & [ ffi:: MCDCBranchRegion ] ,
276
- mcdc_decision_regions : & [ ffi:: MCDCDecisionRegion ] ,
277
- buffer : & RustString ,
278
- ) {
279
- unsafe {
280
- llvm:: LLVMRustCoverageWriteMappingToBuffer (
281
- virtual_file_mapping. as_ptr ( ) ,
282
- virtual_file_mapping. len ( ) as c_uint ,
283
- expressions. as_ptr ( ) ,
284
- expressions. len ( ) as c_uint ,
285
- code_regions. as_ptr ( ) ,
286
- code_regions. len ( ) as c_uint ,
287
- branch_regions. as_ptr ( ) ,
288
- branch_regions. len ( ) as c_uint ,
289
- mcdc_branch_regions. as_ptr ( ) ,
290
- mcdc_branch_regions. len ( ) as c_uint ,
291
- mcdc_decision_regions. as_ptr ( ) ,
292
- mcdc_decision_regions. len ( ) as c_uint ,
293
- buffer,
294
- ) ;
295
- }
296
- }
297
-
298
- pub ( crate ) fn hash_bytes ( bytes : & [ u8 ] ) -> u64 {
299
- unsafe { llvm:: LLVMRustCoverageHashByteArray ( bytes. as_c_char_ptr ( ) , bytes. len ( ) ) }
300
- }
301
-
302
- pub ( crate ) fn mapping_version ( ) -> u32 {
303
- unsafe { llvm:: LLVMRustCoverageMappingVersion ( ) }
304
- }
0 commit comments