@@ -32,13 +32,18 @@ pub struct CrateCoverageContext<'ll, 'tcx> {
32
32
pub ( crate ) function_coverage_map :
33
33
RefCell < FxIndexMap < Instance < ' tcx > , FunctionCoverageCollector < ' tcx > > > ,
34
34
pub ( crate ) pgo_func_name_var_map : RefCell < FxHashMap < Instance < ' tcx > , & ' ll llvm:: Value > > ,
35
+
36
+ /// When MCDC is enabled, holds references to the stack-allocated function-wise
37
+ /// condition bitmaps.
38
+ pub ( crate ) mcdc_condbitmap_map : RefCell < FxHashMap < Instance < ' tcx > , & ' ll llvm:: Value > > ,
35
39
}
36
40
37
41
impl < ' ll , ' tcx > CrateCoverageContext < ' ll , ' tcx > {
38
42
pub fn new ( ) -> Self {
39
43
Self {
40
44
function_coverage_map : Default :: default ( ) ,
41
45
pgo_func_name_var_map : Default :: default ( ) ,
46
+ mcdc_condbitmap_map : Default :: default ( ) ,
42
47
}
43
48
}
44
49
@@ -105,20 +110,6 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
105
110
| CoverageKind :: MCDCDecisionMarker { .. } => unreachable ! (
106
111
"marker statement {kind:?} should have been removed by CleanupPostBorrowck"
107
112
) ,
108
- CoverageKind :: MCDCBitmapRequire { needed_bytes } => {
109
- // We need to explicitly drop the `RefMut` before calling into `instrprof_mcdc_parameters`,
110
- // as that needs an exclusive borrow.
111
- drop ( coverage_map) ;
112
-
113
- let fn_name = bx. get_pgo_func_name_var ( instance) ;
114
- let hash = bx. const_u64 ( function_coverage_info. function_source_hash ) ;
115
- let num_bitmap_bytes = bx. const_u32 ( needed_bytes) ;
116
- debug ! (
117
- "codegen intrinsic instrprof.mcdc.parameters(fn_name={:?}, hash={:?}, bitmap_bytes={:?})" ,
118
- fn_name, hash, num_bitmap_bytes,
119
- ) ;
120
- bx. instrprof_mcdc_parameters ( fn_name, hash, num_bitmap_bytes) ;
121
- }
122
113
CoverageKind :: CounterIncrement { id } => {
123
114
func_coverage. mark_counter_id_seen ( id) ;
124
115
// We need to explicitly drop the `RefMut` before calling into `instrprof_increment`,
@@ -150,6 +141,39 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
150
141
CoverageKind :: ExpressionUsed { id } => {
151
142
func_coverage. mark_expression_id_seen ( id) ;
152
143
}
144
+ CoverageKind :: MCDCBitmapRequire { needed_bytes } => {
145
+ // We need to explicitly drop the `RefMut` before calling into `instrprof_mcdc_parameters`,
146
+ // as that needs an exclusive borrow.
147
+ drop ( coverage_map) ;
148
+
149
+ let fn_name = bx. get_pgo_func_name_var ( instance) ;
150
+ let hash = bx. const_u64 ( function_coverage_info. function_source_hash ) ;
151
+ let num_bitmap_bytes = bx. const_u32 ( needed_bytes) ;
152
+ debug ! (
153
+ "codegen intrinsic instrprof.mcdc.parameters(fn_name={:?}, hash={:?}, bitmap_bytes={:?})" ,
154
+ fn_name, hash, num_bitmap_bytes,
155
+ ) ;
156
+ // Call the intrinsic to ask LLVM to allocate a global variable for the
157
+ // test vector bitmaps in the function body.
158
+ bx. instrprof_mcdc_parameters ( fn_name, hash, num_bitmap_bytes) ;
159
+
160
+ // Allocates an integer in the function stackframe that will be
161
+ // used for the condition bitmaps of the decisions.
162
+ let cond_bitmap_addr = bx. alloca (
163
+ bx. type_uint_from_ty ( rustc_middle:: ty:: UintTy :: U32 ) ,
164
+ Align :: from_bytes ( 4 ) . expect ( "4 bytes alignment failed" ) ,
165
+ ) ;
166
+
167
+ // Acquire a new handle to coverage_context.
168
+ let coverage_context = bx. coverage_context ( ) . expect ( "Presence checked" ) ;
169
+ coverage_context
170
+ . mcdc_condbitmap_map
171
+ . borrow_mut ( )
172
+ . insert ( instance, cond_bitmap_addr) ;
173
+ }
174
+ CoverageKind :: MCDCCondBitmapReset => todo ! ( ) ,
175
+ CoverageKind :: MCDCCondBitmapUpdate { condition_id : _, bool_value : _ } => todo ! ( ) ,
176
+ CoverageKind :: MCDCTestBitmapUpdate { needed_bytes : _, decision_index : _ } => todo ! ( ) ,
153
177
}
154
178
}
155
179
}
0 commit comments