@@ -30,7 +30,7 @@ pub struct CrateCoverageContext<'ll, 'tcx> {
30
30
pub ( crate ) function_coverage_map :
31
31
RefCell < FxIndexMap < Instance < ' tcx > , FunctionCoverageCollector < ' tcx > > > ,
32
32
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 > > > ,
34
34
}
35
35
36
36
impl < ' ll , ' tcx > CrateCoverageContext < ' ll , ' tcx > {
@@ -49,9 +49,20 @@ impl<'ll, 'tcx> CrateCoverageContext<'ll, 'tcx> {
49
49
}
50
50
51
51
/// 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>
55
66
}
56
67
}
57
68
@@ -151,7 +162,7 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
151
162
"ConditionId of evaluated conditions should never be zero"
152
163
) ;
153
164
let cond_bitmap = coverage_context
154
- . try_get_mcdc_condition_bitmap ( & instance)
165
+ . try_get_mcdc_condition_bitmap ( & instance, 0 )
155
166
. expect ( "mcdc cond bitmap should have been allocated for updating" ) ;
156
167
let cond_loc = bx. const_i32 ( id. as_u32 ( ) as i32 - 1 ) ;
157
168
let bool_value = bx. const_bool ( value) ;
@@ -162,7 +173,7 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
162
173
CoverageKind :: TestVectorBitmapUpdate { bitmap_idx } => {
163
174
drop ( coverage_map) ;
164
175
let cond_bitmap = coverage_context
165
- . try_get_mcdc_condition_bitmap ( & instance)
176
+ . try_get_mcdc_condition_bitmap ( & instance, 0 )
166
177
. expect ( "mcdc cond bitmap should have been allocated for merging into the global bitmap" ) ;
167
178
let bitmap_bytes = bx. tcx ( ) . coverage_ids_info ( instance. def ) . mcdc_bitmap_bytes ;
168
179
assert ! ( bitmap_idx < bitmap_bytes, "bitmap index of the decision out of range" ) ;
@@ -195,7 +206,7 @@ fn ensure_mcdc_parameters<'ll, 'tcx>(
195
206
let fn_name = bx. get_pgo_func_name_var ( instance) ;
196
207
let hash = bx. const_u64 ( function_coverage_info. function_source_hash ) ;
197
208
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 ) ;
199
210
bx. coverage_context ( )
200
211
. expect ( "already checked above" )
201
212
. mcdc_condition_bitmap_map
0 commit comments