@@ -32,13 +32,18 @@ pub struct CrateCoverageContext<'ll, 'tcx> {
3232 pub ( crate ) function_coverage_map :
3333 RefCell < FxIndexMap < Instance < ' tcx > , FunctionCoverageCollector < ' tcx > > > ,
3434 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 > > ,
3539}
3640
3741impl < ' ll , ' tcx > CrateCoverageContext < ' ll , ' tcx > {
3842 pub fn new ( ) -> Self {
3943 Self {
4044 function_coverage_map : Default :: default ( ) ,
4145 pgo_func_name_var_map : Default :: default ( ) ,
46+ mcdc_condbitmap_map : Default :: default ( ) ,
4247 }
4348 }
4449
@@ -105,20 +110,6 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
105110 | CoverageKind :: MCDCDecisionMarker { .. } => unreachable ! (
106111 "marker statement {kind:?} should have been removed by CleanupPostBorrowck"
107112 ) ,
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- }
122113 CoverageKind :: CounterIncrement { id } => {
123114 func_coverage. mark_counter_id_seen ( id) ;
124115 // We need to explicitly drop the `RefMut` before calling into `instrprof_increment`,
@@ -150,6 +141,39 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
150141 CoverageKind :: ExpressionUsed { id } => {
151142 func_coverage. mark_expression_id_seen ( id) ;
152143 }
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 ! ( ) ,
153177 }
154178 }
155179}
0 commit comments