about summary refs log tree commit diff
path: root/compiler/rustc_mir_transform/src/coverage
diff options
context:
space:
mode:
authorZalathar <Zalathar@users.noreply.github.com>2024-05-02 12:30:07 +1000
committerZalathar <Zalathar@users.noreply.github.com>2024-05-04 11:26:02 +1000
commitaf33fc85de33e72e798fd9518c078b6b8f44c7b0 (patch)
treef51568e782074e3ffac63a3db6c5782f0cd1836a /compiler/rustc_mir_transform/src/coverage
parentd2d24e395a1e4fcee62ca17bf4cbddb1f903af97 (diff)
downloadrust-af33fc85de33e72e798fd9518c078b6b8f44c7b0.tar.gz
rust-af33fc85de33e72e798fd9518c078b6b8f44c7b0.zip
coverage: Split out MC/DC decisions from `BcbMappingKind`
Diffstat (limited to 'compiler/rustc_mir_transform/src/coverage')
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mappings.rs90
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mod.rs32
2 files changed, 71 insertions, 51 deletions
diff --git a/compiler/rustc_mir_transform/src/coverage/mappings.rs b/compiler/rustc_mir_transform/src/coverage/mappings.rs
index d364658efb6..79c335c8dd2 100644
--- a/compiler/rustc_mir_transform/src/coverage/mappings.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mappings.rs
@@ -2,8 +2,9 @@ use std::collections::BTreeSet;
 
 use rustc_data_structures::graph::DirectedGraph;
 use rustc_index::bit_set::BitSet;
+use rustc_index::IndexVec;
 use rustc_middle::mir::coverage::{
-    BlockMarkerId, BranchSpan, ConditionInfo, CoverageKind, MCDCBranchSpan, MCDCDecisionSpan,
+    BlockMarkerId, BranchSpan, ConditionInfo, CoverageKind, MCDCBranchSpan,
 };
 use rustc_middle::mir::{self, BasicBlock, StatementKind};
 use rustc_span::Span;
@@ -13,7 +14,6 @@ use crate::coverage::spans::{
     extract_refined_covspans, unexpand_into_body_span_with_visible_macro,
 };
 use crate::coverage::ExtractedHirInfo;
-use rustc_index::IndexVec;
 
 #[derive(Clone, Debug)]
 pub(super) enum BcbMappingKind {
@@ -32,13 +32,6 @@ pub(super) enum BcbMappingKind {
         condition_info: Option<ConditionInfo>,
         decision_depth: u16,
     },
-    /// Associates a mcdc decision with its join BCB.
-    MCDCDecision {
-        end_bcbs: BTreeSet<BasicCoverageBlock>,
-        bitmap_idx: u32,
-        conditions_num: u16,
-        decision_depth: u16,
-    },
 }
 
 #[derive(Debug)]
@@ -57,11 +50,22 @@ pub(super) struct BcbBranchPair {
     pub(super) false_bcb: BasicCoverageBlock,
 }
 
+/// Associates an MC/DC decision with its join BCBs.
+#[derive(Debug)]
+pub(super) struct MCDCDecision {
+    pub(super) span: Span,
+    pub(super) end_bcbs: BTreeSet<BasicCoverageBlock>,
+    pub(super) bitmap_idx: u32,
+    pub(super) conditions_num: u16,
+    pub(super) decision_depth: u16,
+}
+
 pub(super) struct CoverageSpans {
     bcb_has_mappings: BitSet<BasicCoverageBlock>,
     pub(super) mappings: Vec<BcbMapping>,
     pub(super) branch_pairs: Vec<BcbBranchPair>,
     test_vector_bitmap_bytes: u32,
+    pub(super) mcdc_decisions: Vec<MCDCDecision>,
 }
 
 impl CoverageSpans {
@@ -85,6 +89,7 @@ pub(super) fn generate_coverage_spans(
 ) -> Option<CoverageSpans> {
     let mut mappings = vec![];
     let mut branch_pairs = vec![];
+    let mut mcdc_decisions = vec![];
 
     if hir_info.is_async_fn {
         // An async function desugars into a function that returns a future,
@@ -99,10 +104,15 @@ pub(super) fn generate_coverage_spans(
 
         branch_pairs.extend(extract_branch_pairs(mir_body, hir_info, basic_coverage_blocks));
 
-        mappings.extend(extract_mcdc_mappings(mir_body, hir_info.body_span, basic_coverage_blocks));
+        mappings.extend(extract_mcdc_mappings(
+            mir_body,
+            hir_info.body_span,
+            basic_coverage_blocks,
+            &mut mcdc_decisions,
+        ));
     }
 
-    if mappings.is_empty() && branch_pairs.is_empty() {
+    if mappings.is_empty() && branch_pairs.is_empty() && mcdc_decisions.is_empty() {
         return None;
     }
 
@@ -111,7 +121,7 @@ pub(super) fn generate_coverage_spans(
     let mut insert = |bcb| {
         bcb_has_mappings.insert(bcb);
     };
-    let mut test_vector_bitmap_bytes = 0;
+
     for BcbMapping { kind, span: _ } in &mappings {
         match *kind {
             BcbMappingKind::Code(bcb) => insert(bcb),
@@ -119,13 +129,6 @@ pub(super) fn generate_coverage_spans(
                 insert(true_bcb);
                 insert(false_bcb);
             }
-            BcbMappingKind::MCDCDecision { bitmap_idx, conditions_num, .. } => {
-                // `bcb_has_mappings` is used for inject coverage counters
-                // but they are not needed for decision BCBs.
-                // While the length of test vector bitmap should be calculated here.
-                test_vector_bitmap_bytes = test_vector_bitmap_bytes
-                    .max(bitmap_idx + (1_u32 << conditions_num as u32).div_ceil(8));
-            }
         }
     }
     for &BcbBranchPair { true_bcb, false_bcb, .. } in &branch_pairs {
@@ -133,7 +136,22 @@ pub(super) fn generate_coverage_spans(
         insert(false_bcb);
     }
 
-    Some(CoverageSpans { bcb_has_mappings, mappings, branch_pairs, test_vector_bitmap_bytes })
+    // Determine the length of the test vector bitmap.
+    let test_vector_bitmap_bytes = mcdc_decisions
+        .iter()
+        .map(|&MCDCDecision { bitmap_idx, conditions_num, .. }| {
+            bitmap_idx + (1_u32 << u32::from(conditions_num)).div_ceil(8)
+        })
+        .max()
+        .unwrap_or(0);
+
+    Some(CoverageSpans {
+        bcb_has_mappings,
+        mappings,
+        branch_pairs,
+        test_vector_bitmap_bytes,
+        mcdc_decisions,
+    })
 }
 
 fn resolve_block_markers(
@@ -199,6 +217,7 @@ pub(super) fn extract_mcdc_mappings(
     mir_body: &mir::Body<'_>,
     body_span: Span,
     basic_coverage_blocks: &CoverageGraph,
+    mcdc_decisions: &mut impl Extend<MCDCDecision>,
 ) -> Vec<BcbMapping> {
     let Some(branch_info) = mir_body.coverage_branch_info.as_deref() else {
         return vec![];
@@ -245,31 +264,30 @@ pub(super) fn extract_mcdc_mappings(
 
     let mut next_bitmap_idx = 0;
 
-    let decision_filter_map = |decision: &MCDCDecisionSpan| {
-        let (span, _) = unexpand_into_body_span_with_visible_macro(decision.span, body_span)?;
+    mcdc_decisions.extend(branch_info.mcdc_decision_spans.iter().filter_map(
+        |decision: &mir::coverage::MCDCDecisionSpan| {
+            let (span, _) = unexpand_into_body_span_with_visible_macro(decision.span, body_span)?;
 
-        let end_bcbs = decision
-            .end_markers
-            .iter()
-            .map(|&marker| bcb_from_marker(marker))
-            .collect::<Option<_>>()?;
+            let end_bcbs = decision
+                .end_markers
+                .iter()
+                .map(|&marker| bcb_from_marker(marker))
+                .collect::<Option<_>>()?;
 
-        let bitmap_idx = next_bitmap_idx;
-        next_bitmap_idx += (1_u32 << decision.conditions_num).div_ceil(8);
+            let bitmap_idx = next_bitmap_idx;
+            next_bitmap_idx += (1_u32 << decision.conditions_num).div_ceil(8);
 
-        Some(BcbMapping {
-            kind: BcbMappingKind::MCDCDecision {
+            Some(MCDCDecision {
+                span,
                 end_bcbs,
                 bitmap_idx,
                 conditions_num: decision.conditions_num as u16,
                 decision_depth: decision.decision_depth,
-            },
-            span,
-        })
-    };
+            })
+        },
+    ));
 
     std::iter::empty()
         .chain(branch_info.mcdc_branch_spans.iter().filter_map(mcdc_branch_filter_map))
-        .chain(branch_info.mcdc_decision_spans.iter().filter_map(decision_filter_map))
         .collect::<Vec<_>>()
 }
diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs
index ffe61e761c5..24df197b601 100644
--- a/compiler/rustc_mir_transform/src/coverage/mod.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mod.rs
@@ -103,12 +103,9 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
     inject_mcdc_statements(mir_body, &basic_coverage_blocks, &coverage_spans);
 
     let mcdc_num_condition_bitmaps = coverage_spans
-        .mappings
+        .mcdc_decisions
         .iter()
-        .filter_map(|bcb_mapping| match bcb_mapping.kind {
-            BcbMappingKind::MCDCDecision { decision_depth, .. } => Some(decision_depth),
-            _ => None,
-        })
+        .map(|&mappings::MCDCDecision { decision_depth, .. }| decision_depth)
         .max()
         .map_or(0, |max| usize::from(max) + 1);
 
@@ -172,9 +169,6 @@ fn create_mappings<'tcx>(
                     false_term: term_for_bcb(false_bcb),
                     mcdc_params,
                 },
-                BcbMappingKind::MCDCDecision { bitmap_idx, conditions_num, .. } => {
-                    MappingKind::MCDCDecision(DecisionInfo { bitmap_idx, conditions_num })
-                }
             };
             let code_region = make_code_region(source_map, file_name, *span, body_span)?;
             Some(Mapping { kind, code_region })
@@ -191,6 +185,14 @@ fn create_mappings<'tcx>(
         },
     ));
 
+    mappings.extend(coverage_spans.mcdc_decisions.iter().filter_map(
+        |&mappings::MCDCDecision { span, bitmap_idx, conditions_num, .. }| {
+            let code_region = make_code_region(source_map, file_name, span, body_span)?;
+            let kind = MappingKind::MCDCDecision(DecisionInfo { bitmap_idx, conditions_num });
+            Some(Mapping { kind, code_region })
+        },
+    ));
+
     mappings
 }
 
@@ -258,13 +260,13 @@ fn inject_mcdc_statements<'tcx>(
     }
 
     // Inject test vector update first because `inject_statement` always insert new statement at head.
-    for (end_bcbs, bitmap_idx, decision_depth) in
-        coverage_spans.mappings.iter().filter_map(|mapping| match &mapping.kind {
-            BcbMappingKind::MCDCDecision { end_bcbs, bitmap_idx, decision_depth, .. } => {
-                Some((end_bcbs, *bitmap_idx, *decision_depth))
-            }
-            _ => None,
-        })
+    for &mappings::MCDCDecision {
+        span: _,
+        ref end_bcbs,
+        bitmap_idx,
+        conditions_num: _,
+        decision_depth,
+    } in &coverage_spans.mcdc_decisions
     {
         for end in end_bcbs {
             let end_bb = basic_coverage_blocks[*end].leader_bb();