diff options
| author | bors <bors@rust-lang.org> | 2024-07-16 05:46:31 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-07-16 05:46:31 +0000 |
| commit | 451035fff364e81cc63d15bd475da8ba32e01470 (patch) | |
| tree | b24a14bb4f49de11c1ed351b24910d00a32f4a95 /compiler/rustc_mir_transform/src | |
| parent | e90f04731a382a27962a30113f8283a59a6ab87e (diff) | |
| parent | 547ade539c578c8a39b02841c3ef4ae980f5c658 (diff) | |
| download | rust-451035fff364e81cc63d15bd475da8ba32e01470.tar.gz rust-451035fff364e81cc63d15bd475da8ba32e01470.zip | |
Auto merge of #3751 - rust-lang:rustup-2024-07-16, r=RalfJung
Automatic Rustup
Diffstat (limited to 'compiler/rustc_mir_transform/src')
| -rw-r--r-- | compiler/rustc_mir_transform/src/coroutine.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/coverage/mappings.rs | 22 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/coverage/mod.rs | 17 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/dataflow_const_prop.rs | 20 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/inline.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/jump_threading.rs | 2 |
6 files changed, 48 insertions, 21 deletions
diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index fa5da89e8ba..261dcd52d71 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -81,8 +81,8 @@ use rustc_span::symbol::sym; use rustc_span::Span; use rustc_target::abi::{FieldIdx, VariantIdx}; use rustc_target::spec::PanicStrategy; +use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt as _; use rustc_trait_selection::infer::TyCtxtInferExt as _; -use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; use rustc_trait_selection::traits::ObligationCtxt; use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode}; use std::{iter, ops}; diff --git a/compiler/rustc_mir_transform/src/coverage/mappings.rs b/compiler/rustc_mir_transform/src/coverage/mappings.rs index 25297245172..2ac08ea85d2 100644 --- a/compiler/rustc_mir_transform/src/coverage/mappings.rs +++ b/compiler/rustc_mir_transform/src/coverage/mappings.rs @@ -56,6 +56,10 @@ pub(super) struct MCDCDecision { #[derive(Default)] pub(super) struct ExtractedMappings { + /// Store our own copy of [`CoverageGraph::num_nodes`], so that we don't + /// need access to the whole graph when allocating per-BCB data. This is + /// only public so that other code can still use exhaustive destructuring. + pub(super) num_bcbs: usize, pub(super) code_mappings: Vec<CodeMapping>, pub(super) branch_pairs: Vec<BranchPair>, pub(super) mcdc_bitmap_bytes: u32, @@ -106,6 +110,7 @@ pub(super) fn extract_all_mapping_info_from_mir<'tcx>( ); ExtractedMappings { + num_bcbs: basic_coverage_blocks.num_nodes(), code_mappings, branch_pairs, mcdc_bitmap_bytes, @@ -115,12 +120,10 @@ pub(super) fn extract_all_mapping_info_from_mir<'tcx>( } impl ExtractedMappings { - pub(super) fn all_bcbs_with_counter_mappings( - &self, - basic_coverage_blocks: &CoverageGraph, // Only used for allocating a correctly-sized set - ) -> BitSet<BasicCoverageBlock> { + pub(super) fn all_bcbs_with_counter_mappings(&self) -> BitSet<BasicCoverageBlock> { // Fully destructure self to make sure we don't miss any fields that have mappings. let Self { + num_bcbs, code_mappings, branch_pairs, mcdc_bitmap_bytes: _, @@ -129,7 +132,7 @@ impl ExtractedMappings { } = self; // Identify which BCBs have one or more mappings. - let mut bcbs_with_counter_mappings = BitSet::new_empty(basic_coverage_blocks.num_nodes()); + let mut bcbs_with_counter_mappings = BitSet::new_empty(*num_bcbs); let mut insert = |bcb| { bcbs_with_counter_mappings.insert(bcb); }; @@ -156,6 +159,15 @@ impl ExtractedMappings { bcbs_with_counter_mappings } + + /// Returns the set of BCBs that have one or more `Code` mappings. + pub(super) fn bcbs_with_ordinary_code_mappings(&self) -> BitSet<BasicCoverageBlock> { + let mut bcbs = BitSet::new_empty(self.num_bcbs); + for &CodeMapping { span: _, bcb } in &self.code_mappings { + bcbs.insert(bcb); + } + bcbs + } } fn resolve_block_markers( diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs index 2efca40d180..3772a8f5118 100644 --- a/compiler/rustc_mir_transform/src/coverage/mod.rs +++ b/compiler/rustc_mir_transform/src/coverage/mod.rs @@ -25,7 +25,7 @@ use rustc_span::source_map::SourceMap; use rustc_span::{BytePos, Pos, RelativeBytePos, Span, Symbol}; use crate::coverage::counters::{CounterIncrementSite, CoverageCounters}; -use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph}; +use crate::coverage::graph::CoverageGraph; use crate::coverage::mappings::ExtractedMappings; use crate::MirPass; @@ -88,8 +88,7 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir: // every coverage span has a `Counter` or `Expression` assigned to its `BasicCoverageBlock` // and all `Expression` dependencies (operands) are also generated, for any other // `BasicCoverageBlock`s not already associated with a coverage span. - let bcbs_with_counter_mappings = - extracted_mappings.all_bcbs_with_counter_mappings(&basic_coverage_blocks); + let bcbs_with_counter_mappings = extracted_mappings.all_bcbs_with_counter_mappings(); if bcbs_with_counter_mappings.is_empty() { // No relevant spans were found in MIR, so skip instrumenting this function. return; @@ -109,7 +108,7 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir: inject_coverage_statements( mir_body, &basic_coverage_blocks, - bcb_has_counter_mappings, + &extracted_mappings, &coverage_counters, ); @@ -163,6 +162,7 @@ fn create_mappings<'tcx>( // Fully destructure the mappings struct to make sure we don't miss any kinds. let ExtractedMappings { + num_bcbs: _, code_mappings, branch_pairs, mcdc_bitmap_bytes: _, @@ -219,7 +219,7 @@ fn create_mappings<'tcx>( fn inject_coverage_statements<'tcx>( mir_body: &mut mir::Body<'tcx>, basic_coverage_blocks: &CoverageGraph, - bcb_has_coverage_spans: impl Fn(BasicCoverageBlock) -> bool, + extracted_mappings: &ExtractedMappings, coverage_counters: &CoverageCounters, ) { // Inject counter-increment statements into MIR. @@ -252,11 +252,16 @@ fn inject_coverage_statements<'tcx>( // can check whether the injected statement survived MIR optimization. // (BCB edges can't have spans, so we only need to process BCB nodes here.) // + // We only do this for ordinary `Code` mappings, because branch and MC/DC + // mappings might have expressions that don't correspond to any single + // point in the control-flow graph. + // // See the code in `rustc_codegen_llvm::coverageinfo::map_data` that deals // with "expressions seen" and "zero terms". + let eligible_bcbs = extracted_mappings.bcbs_with_ordinary_code_mappings(); for (bcb, expression_id) in coverage_counters .bcb_nodes_with_coverage_expressions() - .filter(|&(bcb, _)| bcb_has_coverage_spans(bcb)) + .filter(|&(bcb, _)| eligible_bcbs.contains(bcb)) { inject_statement( mir_body, diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index 8b965f4d18e..8303ef039d1 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -66,7 +66,7 @@ impl<'tcx> MirPass<'tcx> for DataflowConstProp { } struct ConstAnalysis<'a, 'tcx> { - map: Map, + map: Map<'tcx>, tcx: TyCtxt<'tcx>, local_decls: &'a LocalDecls<'tcx>, ecx: InterpCx<'tcx, DummyMachine>, @@ -78,7 +78,7 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> { const NAME: &'static str = "ConstAnalysis"; - fn map(&self) -> &Map { + fn map(&self) -> &Map<'tcx> { &self.map } @@ -330,7 +330,7 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> { } impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { - pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, map: Map) -> Self { + pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, map: Map<'tcx>) -> Self { let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); Self { map, @@ -560,12 +560,13 @@ impl<'tcx, 'locals> Collector<'tcx, 'locals> { Self { patch: Patch::new(tcx), local_decls } } + #[instrument(level = "trace", skip(self, ecx, map), ret)] fn try_make_constant( &self, ecx: &mut InterpCx<'tcx, DummyMachine>, place: Place<'tcx>, state: &State<FlatSet<Scalar>>, - map: &Map, + map: &Map<'tcx>, ) -> Option<Const<'tcx>> { let ty = place.ty(self.local_decls, self.patch.tcx).ty; let layout = ecx.layout_of(ty).ok()?; @@ -598,10 +599,11 @@ impl<'tcx, 'locals> Collector<'tcx, 'locals> { } } +#[instrument(level = "trace", skip(map), ret)] fn propagatable_scalar( place: PlaceIndex, state: &State<FlatSet<Scalar>>, - map: &Map, + map: &Map<'_>, ) -> Option<Scalar> { if let FlatSet::Elem(value) = state.get_idx(place, map) && value.try_to_scalar_int().is_ok() @@ -613,14 +615,14 @@ fn propagatable_scalar( } } -#[instrument(level = "trace", skip(ecx, state, map))] +#[instrument(level = "trace", skip(ecx, state, map), ret)] fn try_write_constant<'tcx>( ecx: &mut InterpCx<'tcx, DummyMachine>, dest: &PlaceTy<'tcx>, place: PlaceIndex, ty: Ty<'tcx>, state: &State<FlatSet<Scalar>>, - map: &Map, + map: &Map<'tcx>, ) -> InterpResult<'tcx> { let layout = ecx.layout_of(ty)?; @@ -719,6 +721,7 @@ impl<'mir, 'tcx> { type FlowState = State<FlatSet<Scalar>>; + #[instrument(level = "trace", skip(self, results, statement))] fn visit_statement_before_primary_effect( &mut self, results: &mut Results<'tcx, ValueAnalysisWrapper<ConstAnalysis<'_, 'tcx>>>, @@ -740,6 +743,7 @@ impl<'mir, 'tcx> } } + #[instrument(level = "trace", skip(self, results, statement))] fn visit_statement_after_primary_effect( &mut self, results: &mut Results<'tcx, ValueAnalysisWrapper<ConstAnalysis<'_, 'tcx>>>, @@ -834,7 +838,7 @@ struct OperandCollector<'tcx, 'map, 'locals, 'a> { state: &'a State<FlatSet<Scalar>>, visitor: &'a mut Collector<'tcx, 'locals>, ecx: &'map mut InterpCx<'tcx, DummyMachine>, - map: &'map Map, + map: &'map Map<'tcx>, } impl<'tcx> Visitor<'tcx> for OperandCollector<'tcx, '_, '_, '_> { diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index fe73715480f..fd9f0fec88d 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -41,6 +41,12 @@ struct CallSite<'tcx> { impl<'tcx> MirPass<'tcx> for Inline { fn is_enabled(&self, sess: &rustc_session::Session) -> bool { + // FIXME(#127234): Coverage instrumentation currently doesn't handle inlined + // MIR correctly when Modified Condition/Decision Coverage is enabled. + if sess.instrument_coverage_mcdc() { + return false; + } + if let Some(enabled) = sess.opts.unstable_opts.inline_mir { return enabled; } diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs index 97ec0cb39de..2100f4b4a1a 100644 --- a/compiler/rustc_mir_transform/src/jump_threading.rs +++ b/compiler/rustc_mir_transform/src/jump_threading.rs @@ -123,7 +123,7 @@ struct TOFinder<'tcx, 'a> { param_env: ty::ParamEnv<'tcx>, ecx: InterpCx<'tcx, DummyMachine>, body: &'a Body<'tcx>, - map: &'a Map, + map: &'a Map<'tcx>, loop_headers: &'a BitSet<BasicBlock>, /// We use an arena to avoid cloning the slices when cloning `state`. arena: &'a DroplessArena, |
