diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs index 03fc2ae425b..eb1071448ce 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs @@ -154,7 +154,7 @@ fn add_coverage(&mut self, instance: Instance<'tcx>, kind: &CoverageKind) { CoverageKind::ExpressionUsed { id } => { func_coverage.mark_expression_id_seen(id); } - CoverageKind::CondBitmapUpdate { id, value, .. } => { + CoverageKind::CondBitmapUpdate { id, value, decision_depth } => { drop(coverage_map); assert_ne!( id.as_u32(), @@ -162,7 +162,7 @@ fn add_coverage(&mut self, instance: Instance<'tcx>, kind: &CoverageKind) { "ConditionId of evaluated conditions should never be zero" ); let cond_bitmap = coverage_context - .try_get_mcdc_condition_bitmap(&instance, 0) + .try_get_mcdc_condition_bitmap(&instance, decision_depth) .expect("mcdc cond bitmap should have been allocated for updating"); let cond_loc = bx.const_i32(id.as_u32() as i32 - 1); let bool_value = bx.const_bool(value); @@ -170,10 +170,10 @@ fn add_coverage(&mut self, instance: Instance<'tcx>, kind: &CoverageKind) { let hash = bx.const_u64(function_coverage_info.function_source_hash); bx.mcdc_condbitmap_update(fn_name, hash, cond_loc, cond_bitmap, bool_value); } - CoverageKind::TestVectorBitmapUpdate { bitmap_idx } => { + CoverageKind::TestVectorBitmapUpdate { bitmap_idx, decision_depth } => { drop(coverage_map); let cond_bitmap = coverage_context - .try_get_mcdc_condition_bitmap(&instance, 0) + .try_get_mcdc_condition_bitmap(&instance, decision_depth) .expect("mcdc cond bitmap should have been allocated for merging into the global bitmap"); let bitmap_bytes = bx.tcx().coverage_ids_info(instance.def).mcdc_bitmap_bytes; assert!(bitmap_idx < bitmap_bytes, "bitmap index of the decision out of range"); diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs index 04011fd4194..6383074742d 100644 --- a/compiler/rustc_middle/src/mir/coverage.rs +++ b/compiler/rustc_middle/src/mir/coverage.rs @@ -132,7 +132,7 @@ pub enum CoverageKind { /// /// If this statement does not survive MIR optimizations, the condition would never be /// taken as evaluated. - CondBitmapUpdate { id: ConditionId, value: bool }, + CondBitmapUpdate { id: ConditionId, value: bool, decision_depth: u16 }, /// Marks the point in MIR control flow represented by a evaluated decision. /// @@ -140,7 +140,7 @@ pub enum CoverageKind { /// /// If this statement does not survive MIR optimizations, the decision would never be /// taken as evaluated. - TestVectorBitmapUpdate { bitmap_idx: u32 }, + TestVectorBitmapUpdate { bitmap_idx: u32, decision_depth: u16 }, } impl Debug for CoverageKind { @@ -151,11 +151,17 @@ fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result { BlockMarker { id } => write!(fmt, "BlockMarker({:?})", id.index()), CounterIncrement { id } => write!(fmt, "CounterIncrement({:?})", id.index()), ExpressionUsed { id } => write!(fmt, "ExpressionUsed({:?})", id.index()), - CondBitmapUpdate { id, value } => { - write!(fmt, "CondBitmapUpdate({:?}, {:?})", id.index(), value) + CondBitmapUpdate { id, value, decision_depth } => { + write!( + fmt, + "CondBitmapUpdate({:?}, {:?}, depth={:?})", + id.index(), + value, + decision_depth + ) } - TestVectorBitmapUpdate { bitmap_idx } => { - write!(fmt, "TestVectorUpdate({:?})", bitmap_idx) + TestVectorBitmapUpdate { bitmap_idx, decision_depth } => { + write!(fmt, "TestVectorUpdate({:?}, depth={:?})", bitmap_idx, decision_depth) } } } @@ -319,6 +325,7 @@ pub struct MCDCBranchSpan { pub condition_info: Option, pub true_marker: BlockMarkerId, pub false_marker: BlockMarkerId, + pub decision_depth: u16, } #[derive(Copy, Clone, Debug)] @@ -334,4 +341,5 @@ pub struct MCDCDecisionSpan { pub span: Span, pub conditions_num: usize, pub end_markers: Vec, + pub decision_depth: u16, } diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 7a91d7383e5..32cd3183410 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -496,20 +496,27 @@ fn write_coverage_branch_info( )?; } - for coverage::MCDCBranchSpan { span, condition_info, true_marker, false_marker } in - mcdc_branch_spans + for coverage::MCDCBranchSpan { + span, + condition_info, + true_marker, + false_marker, + decision_depth, + } in mcdc_branch_spans { writeln!( w, - "{INDENT}coverage mcdc branch {{ condition_id: {:?}, true: {true_marker:?}, false: {false_marker:?} }} => {span:?}", + "{INDENT}coverage mcdc branch {{ condition_id: {:?}, true: {true_marker:?}, false: {false_marker:?}, depth: {decision_depth:?} }} => {span:?}", condition_info.map(|info| info.condition_id) )?; } - for coverage::MCDCDecisionSpan { span, conditions_num, end_markers } in mcdc_decision_spans { + for coverage::MCDCDecisionSpan { span, conditions_num, end_markers, decision_depth } in + mcdc_decision_spans + { writeln!( w, - "{INDENT}coverage mcdc decision {{ conditions_num: {conditions_num:?}, end: {end_markers:?} }} => {span:?}" + "{INDENT}coverage mcdc decision {{ conditions_num: {conditions_num:?}, end: {end_markers:?}, depth: {decision_depth:?} }} => {span:?}" )?; } diff --git a/compiler/rustc_mir_build/src/build/coverageinfo.rs b/compiler/rustc_mir_build/src/build/coverageinfo.rs index 9e9ccd3dc2d..1818be2c1bd 100644 --- a/compiler/rustc_mir_build/src/build/coverageinfo.rs +++ b/compiler/rustc_mir_build/src/build/coverageinfo.rs @@ -262,6 +262,7 @@ fn record_conditions(&mut self, op: LogicalOp, span: Span) { span, conditions_num: 0, end_markers: vec![], + decision_depth: 0, }), }; @@ -371,6 +372,7 @@ pub(crate) fn visit_coverage_branch_condition( condition_info, true_marker, false_marker, + decision_depth: 0, }); return; } diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs index 0b15c52c281..a4c9e5ac0bc 100644 --- a/compiler/rustc_mir_transform/src/coverage/mod.rs +++ b/compiler/rustc_mir_transform/src/coverage/mod.rs @@ -145,16 +145,17 @@ fn create_mappings<'tcx>( |BcbMapping { kind: bcb_mapping_kind, span }| { let kind = match *bcb_mapping_kind { BcbMappingKind::Code(bcb) => MappingKind::Code(term_for_bcb(bcb)), - BcbMappingKind::MCDCBranch { true_bcb, false_bcb, condition_info: None } => { - MappingKind::Branch { - true_term: term_for_bcb(true_bcb), - false_term: term_for_bcb(false_bcb), - } - } + BcbMappingKind::MCDCBranch { + true_bcb, false_bcb, condition_info: None, .. + } => MappingKind::Branch { + true_term: term_for_bcb(true_bcb), + false_term: term_for_bcb(false_bcb), + }, BcbMappingKind::MCDCBranch { true_bcb, false_bcb, condition_info: Some(mcdc_params), + .. } => MappingKind::MCDCBranch { true_term: term_for_bcb(true_bcb), false_term: term_for_bcb(false_bcb), @@ -246,24 +247,28 @@ fn inject_mcdc_statements<'tcx>( } // Inject test vector update first because `inject_statement` always insert new statement at head. - for (end_bcbs, bitmap_idx) in + for (end_bcbs, bitmap_idx, decision_depth) in coverage_spans.mappings.iter().filter_map(|mapping| match &mapping.kind { - BcbMappingKind::MCDCDecision { end_bcbs, bitmap_idx, .. } => { - Some((end_bcbs, *bitmap_idx)) + BcbMappingKind::MCDCDecision { end_bcbs, bitmap_idx, decision_depth, .. } => { + Some((end_bcbs, *bitmap_idx, *decision_depth)) } _ => None, }) { for end in end_bcbs { let end_bb = basic_coverage_blocks[*end].leader_bb(); - inject_statement(mir_body, CoverageKind::TestVectorBitmapUpdate { bitmap_idx }, end_bb); + inject_statement( + mir_body, + CoverageKind::TestVectorBitmapUpdate { bitmap_idx, decision_depth }, + end_bb, + ); } } - for (true_bcb, false_bcb, condition_id) in + for (true_bcb, false_bcb, condition_id, decision_depth) in coverage_spans.mappings.iter().filter_map(|mapping| match mapping.kind { - BcbMappingKind::MCDCBranch { true_bcb, false_bcb, condition_info } => { - Some((true_bcb, false_bcb, condition_info?.condition_id)) + BcbMappingKind::MCDCBranch { true_bcb, false_bcb, condition_info, decision_depth } => { + Some((true_bcb, false_bcb, condition_info?.condition_id, decision_depth)) } _ => None, }) @@ -271,13 +276,13 @@ fn inject_mcdc_statements<'tcx>( let true_bb = basic_coverage_blocks[true_bcb].leader_bb(); inject_statement( mir_body, - CoverageKind::CondBitmapUpdate { id: condition_id, value: true }, + CoverageKind::CondBitmapUpdate { id: condition_id, value: true, decision_depth }, true_bb, ); let false_bb = basic_coverage_blocks[false_bcb].leader_bb(); inject_statement( mir_body, - CoverageKind::CondBitmapUpdate { id: condition_id, value: false }, + CoverageKind::CondBitmapUpdate { id: condition_id, value: false, decision_depth }, false_bb, ); } diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index 88f18b72085..b64b1212cec 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -26,9 +26,15 @@ pub(super) enum BcbMappingKind { /// If `None`, this actually represents a normal branch mapping inserted /// for code that was too complex for MC/DC. condition_info: Option, + decision_depth: u16, }, /// Associates a mcdc decision with its join BCB. - MCDCDecision { end_bcbs: BTreeSet, bitmap_idx: u32, conditions_num: u16 }, + MCDCDecision { + end_bcbs: BTreeSet, + bitmap_idx: u32, + conditions_num: u16, + decision_depth: u16, + }, } #[derive(Debug)] diff --git a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs index 64f21d74b1c..142dfc17fb8 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs @@ -453,15 +453,25 @@ pub(super) fn extract_mcdc_mappings( Some((span, true_bcb, false_bcb)) }; - let mcdc_branch_filter_map = - |&MCDCBranchSpan { span: raw_span, true_marker, false_marker, condition_info }| { - check_branch_bcb(raw_span, true_marker, false_marker).map( - |(span, true_bcb, false_bcb)| BcbMapping { - kind: BcbMappingKind::MCDCBranch { true_bcb, false_bcb, condition_info }, - span, + let mcdc_branch_filter_map = |&MCDCBranchSpan { + span: raw_span, + true_marker, + false_marker, + condition_info, + decision_depth, + }| { + check_branch_bcb(raw_span, true_marker, false_marker).map(|(span, true_bcb, false_bcb)| { + BcbMapping { + kind: BcbMappingKind::MCDCBranch { + true_bcb, + false_bcb, + condition_info, + decision_depth, }, - ) - }; + span, + } + }) + }; let mut next_bitmap_idx = 0; @@ -482,6 +492,7 @@ pub(super) fn extract_mcdc_mappings( end_bcbs, bitmap_idx, conditions_num: decision.conditions_num as u16, + decision_depth: decision.decision_depth, }, span, })