@@ -30,7 +30,7 @@ pub struct CrateCoverageContext<'ll, 'tcx> {
3030 pub ( crate ) function_coverage_map :
3131 RefCell < FxIndexMap < Instance < ' tcx > , FunctionCoverageCollector < ' tcx > > > ,
3232 pub ( crate ) pgo_func_name_var_map : RefCell < FxHashMap < Instance < ' tcx > , & ' ll llvm:: Value > > ,
33- pub ( crate ) mcdc_condition_bitmap_map : RefCell < FxHashMap < Instance < ' tcx > , & ' ll llvm:: Value > > ,
33+ pub ( crate ) mcdc_condition_bitmap_map : RefCell < FxHashMap < Instance < ' tcx > , Vec < & ' ll llvm:: Value > > > ,
3434}
3535
3636impl < ' ll , ' tcx > CrateCoverageContext < ' ll , ' tcx > {
@@ -49,9 +49,20 @@ impl<'ll, 'tcx> CrateCoverageContext<'ll, 'tcx> {
4949 }
5050
5151 /// LLVM use a temp value to record evaluated mcdc test vector of each decision, which is called condition bitmap.
52- /// This value is named `mcdc.addr` (same as clang) and is a 32-bit integer.
53- fn try_get_mcdc_condition_bitmap ( & self , instance : & Instance < ' tcx > ) -> Option < & ' ll llvm:: Value > {
54- self . mcdc_condition_bitmap_map . borrow ( ) . get ( instance) . copied ( )
52+ /// In order to handle nested decisions, several condition bitmaps can be
53+ /// allocated for a function body.
54+ /// These values are named `mcdc.addr.{i}` and are a 32-bit integers.
55+ /// They respectively hold the condition bitmaps for decisions with a depth of `i`.
56+ fn try_get_mcdc_condition_bitmap (
57+ & self ,
58+ instance : & Instance < ' tcx > ,
59+ decision_depth : u16 ,
60+ ) -> Option < & ' ll llvm:: Value > {
61+ self . mcdc_condition_bitmap_map
62+ . borrow ( )
63+ . get ( instance)
64+ . and_then ( |bitmap_map| bitmap_map. get ( decision_depth as usize ) )
65+ . copied ( ) // Dereference Option<&&Value> to Option<&Value>
5566 }
5667}
5768
@@ -151,7 +162,7 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
151162 "ConditionId of evaluated conditions should never be zero"
152163 ) ;
153164 let cond_bitmap = coverage_context
154- . try_get_mcdc_condition_bitmap ( & instance)
165+ . try_get_mcdc_condition_bitmap ( & instance, 0 )
155166 . expect ( "mcdc cond bitmap should have been allocated for updating" ) ;
156167 let cond_loc = bx. const_i32 ( id. as_u32 ( ) as i32 - 1 ) ;
157168 let bool_value = bx. const_bool ( value) ;
@@ -162,7 +173,7 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
162173 CoverageKind :: TestVectorBitmapUpdate { bitmap_idx } => {
163174 drop ( coverage_map) ;
164175 let cond_bitmap = coverage_context
165- . try_get_mcdc_condition_bitmap ( & instance)
176+ . try_get_mcdc_condition_bitmap ( & instance, 0 )
166177 . expect ( "mcdc cond bitmap should have been allocated for merging into the global bitmap" ) ;
167178 let bitmap_bytes = bx. tcx ( ) . coverage_ids_info ( instance. def ) . mcdc_bitmap_bytes ;
168179 assert ! ( bitmap_idx < bitmap_bytes, "bitmap index of the decision out of range" ) ;
@@ -195,7 +206,7 @@ fn ensure_mcdc_parameters<'ll, 'tcx>(
195206 let fn_name = bx. get_pgo_func_name_var ( instance) ;
196207 let hash = bx. const_u64 ( function_coverage_info. function_source_hash ) ;
197208 let bitmap_bytes = bx. const_u32 ( function_coverage_info. mcdc_bitmap_bytes ) ;
198- let cond_bitmap = bx. mcdc_parameters ( fn_name, hash, bitmap_bytes) ;
209+ let cond_bitmap = bx. mcdc_parameters ( fn_name, hash, bitmap_bytes, 1_u32 ) ;
199210 bx. coverage_context ( )
200211 . expect ( "already checked above" )
201212 . mcdc_condition_bitmap_map
0 commit comments