@@ -13,10 +13,10 @@ use rustc_codegen_ssa::traits::{
13
13
use rustc_data_structures:: fx:: { FxHashMap , FxIndexMap } ;
14
14
use rustc_llvm:: RustString ;
15
15
use rustc_middle:: bug;
16
- use rustc_middle:: mir:: coverage:: { CoverageKind , FunctionCoverageInfo } ;
16
+ use rustc_middle:: mir:: coverage:: CoverageKind ;
17
17
use rustc_middle:: ty:: layout:: HasTyCtxt ;
18
18
use rustc_middle:: ty:: Instance ;
19
- use rustc_target:: abi:: Align ;
19
+ use rustc_target:: abi:: { Align , Size } ;
20
20
21
21
use std:: cell:: RefCell ;
22
22
@@ -91,6 +91,42 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
91
91
}
92
92
93
93
impl < ' tcx > CoverageInfoBuilderMethods < ' tcx > for Builder < ' _ , ' _ , ' tcx > {
94
+ fn init_coverage ( & mut self , instance : Instance < ' tcx > ) {
95
+ let Some ( function_coverage_info) =
96
+ self . tcx . instance_mir ( instance. def ) . function_coverage_info . as_deref ( )
97
+ else {
98
+ return ;
99
+ } ;
100
+
101
+ // If there are no MC/DC bitmaps to set up, return immediately.
102
+ if function_coverage_info. mcdc_bitmap_bytes == 0 {
103
+ return ;
104
+ }
105
+
106
+ let fn_name = self . get_pgo_func_name_var ( instance) ;
107
+ let hash = self . const_u64 ( function_coverage_info. function_source_hash ) ;
108
+ let bitmap_bytes = self . const_u32 ( function_coverage_info. mcdc_bitmap_bytes ) ;
109
+ self . mcdc_parameters ( fn_name, hash, bitmap_bytes) ;
110
+
111
+ // Create pointers named `mcdc.addr.{i}` to stack-allocated condition bitmaps.
112
+ let mut cond_bitmaps = vec ! [ ] ;
113
+ for i in 0 ..function_coverage_info. mcdc_num_condition_bitmaps {
114
+ // MC/DC intrinsics will perform loads/stores that use the ABI default
115
+ // alignment for i32, so our variable declaration should match.
116
+ let align = self . tcx . data_layout . i32_align . abi ;
117
+ let cond_bitmap = self . alloca ( Size :: from_bytes ( 4 ) , align) ;
118
+ llvm:: set_value_name ( cond_bitmap, format ! ( "mcdc.addr.{i}" ) . as_bytes ( ) ) ;
119
+ self . store ( self . const_i32 ( 0 ) , cond_bitmap, align) ;
120
+ cond_bitmaps. push ( cond_bitmap) ;
121
+ }
122
+
123
+ self . coverage_context ( )
124
+ . expect ( "always present when coverage is enabled" )
125
+ . mcdc_condition_bitmap_map
126
+ . borrow_mut ( )
127
+ . insert ( instance, cond_bitmaps) ;
128
+ }
129
+
94
130
#[ instrument( level = "debug" , skip( self ) ) ]
95
131
fn add_coverage ( & mut self , instance : Instance < ' tcx > , kind : & CoverageKind ) {
96
132
// Our caller should have already taken care of inlining subtleties,
@@ -109,10 +145,6 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
109
145
return ;
110
146
} ;
111
147
112
- if function_coverage_info. mcdc_bitmap_bytes > 0 {
113
- ensure_mcdc_parameters ( bx, instance, function_coverage_info) ;
114
- }
115
-
116
148
let Some ( coverage_context) = bx. coverage_context ( ) else { return } ;
117
149
let mut coverage_map = coverage_context. function_coverage_map . borrow_mut ( ) ;
118
150
let func_coverage = coverage_map
@@ -193,28 +225,6 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
193
225
}
194
226
}
195
227
196
- fn ensure_mcdc_parameters < ' ll , ' tcx > (
197
- bx : & mut Builder < ' _ , ' ll , ' tcx > ,
198
- instance : Instance < ' tcx > ,
199
- function_coverage_info : & FunctionCoverageInfo ,
200
- ) {
201
- let Some ( cx) = bx. coverage_context ( ) else { return } ;
202
- if cx. mcdc_condition_bitmap_map . borrow ( ) . contains_key ( & instance) {
203
- return ;
204
- }
205
-
206
- let fn_name = bx. get_pgo_func_name_var ( instance) ;
207
- let hash = bx. const_u64 ( function_coverage_info. function_source_hash ) ;
208
- let bitmap_bytes = bx. const_u32 ( function_coverage_info. mcdc_bitmap_bytes ) ;
209
- let max_decision_depth = function_coverage_info. mcdc_max_decision_depth ;
210
- let cond_bitmap = bx. mcdc_parameters ( fn_name, hash, bitmap_bytes, max_decision_depth as u32 ) ;
211
- bx. coverage_context ( )
212
- . expect ( "already checked above" )
213
- . mcdc_condition_bitmap_map
214
- . borrow_mut ( )
215
- . insert ( instance, cond_bitmap) ;
216
- }
217
-
218
228
/// Calls llvm::createPGOFuncNameVar() with the given function instance's
219
229
/// mangled function name. The LLVM API returns an llvm::GlobalVariable
220
230
/// containing the function name, with the specific variable name and linkage
0 commit comments