From 011d4aa81f1d20b4923a01c7162caa5f0042b8ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Fri, 11 Jul 2025 08:10:16 +0200 Subject: [PATCH 1/2] Call `get_switch_int_data` on a block with SwitchInt terminator Fix a mix-up of a block with its predecessors in handling of SwitchInt edge effects for backward analysis. Note that this functionality is currently unused, so change has no practical impact. --- compiler/rustc_mir_dataflow/src/framework/direction.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs index cb647476db8f3..bba652656dd2f 100644 --- a/compiler/rustc_mir_dataflow/src/framework/direction.rs +++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs @@ -113,7 +113,7 @@ impl Direction for Backward { } mir::TerminatorKind::SwitchInt { ref targets, ref discr } => { - if let Some(mut data) = analysis.get_switch_int_data(block, discr) { + if let Some(mut data) = analysis.get_switch_int_data(pred, discr) { let mut tmp = analysis.bottom_value(body); for &value in &body.basic_blocks.switch_sources()[&(block, pred)] { tmp.clone_from(exit_state); From 5b6d661039116ea573652393938061a9a2a2c586 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Fri, 11 Jul 2025 08:43:16 +0200 Subject: [PATCH 2/2] Remove support for SwitchInt edge effects in backward dataflow analyses Those effects are untested and unused. Remove them along with the implementation of `BasicBlocks::switch_sources`. --- compiler/rustc_middle/src/mir/basic_blocks.rs | 40 +------------------ .../src/framework/direction.rs | 15 +++---- 2 files changed, 7 insertions(+), 48 deletions(-) diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs index d0dbf64dc5959..0d2e23609ce35 100644 --- a/compiler/rustc_middle/src/mir/basic_blocks.rs +++ b/compiler/rustc_middle/src/mir/basic_blocks.rs @@ -1,6 +1,5 @@ use std::sync::OnceLock; -use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::graph; use rustc_data_structures::graph::dominators::{Dominators, dominators}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -10,7 +9,7 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use smallvec::SmallVec; use crate::mir::traversal::Postorder; -use crate::mir::{BasicBlock, BasicBlockData, START_BLOCK, Terminator, TerminatorKind}; +use crate::mir::{BasicBlock, BasicBlockData, START_BLOCK}; #[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable, TypeVisitable)] pub struct BasicBlocks<'tcx> { @@ -21,15 +20,6 @@ pub struct BasicBlocks<'tcx> { // Typically 95%+ of basic blocks have 4 or fewer predecessors. type Predecessors = IndexVec>; -/// Each `(target, switch)` entry in the map contains a list of switch values -/// that lead to a `target` block from a `switch` block. -/// -/// Note: this type is currently never instantiated, because it's only used for -/// `BasicBlocks::switch_sources`, which is only called by backwards analyses -/// that do `SwitchInt` handling, and we don't have any of those, not even in -/// tests. See #95120 and #94576. -type SwitchSources = FxHashMap<(BasicBlock, BasicBlock), SmallVec<[SwitchTargetValue; 1]>>; - #[derive(Debug, Clone, Copy)] pub enum SwitchTargetValue { // A normal switch value. @@ -41,7 +31,6 @@ pub enum SwitchTargetValue { #[derive(Clone, Default, Debug)] struct Cache { predecessors: OnceLock, - switch_sources: OnceLock, reverse_postorder: OnceLock>, dominators: OnceLock>, } @@ -86,33 +75,6 @@ impl<'tcx> BasicBlocks<'tcx> { }) } - /// Returns info about switch values that lead from one block to another - /// block. See `SwitchSources`. - #[inline] - pub fn switch_sources(&self) -> &SwitchSources { - self.cache.switch_sources.get_or_init(|| { - let mut switch_sources: SwitchSources = FxHashMap::default(); - for (bb, data) in self.basic_blocks.iter_enumerated() { - if let Some(Terminator { - kind: TerminatorKind::SwitchInt { targets, .. }, .. - }) = &data.terminator - { - for (value, target) in targets.iter() { - switch_sources - .entry((target, bb)) - .or_default() - .push(SwitchTargetValue::Normal(value)); - } - switch_sources - .entry((targets.otherwise(), bb)) - .or_default() - .push(SwitchTargetValue::Otherwise); - } - } - switch_sources - }) - } - /// Returns mutable reference to basic blocks. Invalidates CFG cache. #[inline] pub fn as_mut(&mut self) -> &mut IndexVec> { diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs index bba652656dd2f..79c0db7d72831 100644 --- a/compiler/rustc_mir_dataflow/src/framework/direction.rs +++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs @@ -1,5 +1,6 @@ use std::ops::RangeInclusive; +use rustc_middle::bug; use rustc_middle::mir::{ self, BasicBlock, CallReturnPlaces, Location, SwitchTargetValue, TerminatorEdges, }; @@ -112,15 +113,11 @@ impl Direction for Backward { propagate(pred, &tmp); } - mir::TerminatorKind::SwitchInt { ref targets, ref discr } => { - if let Some(mut data) = analysis.get_switch_int_data(pred, discr) { - let mut tmp = analysis.bottom_value(body); - for &value in &body.basic_blocks.switch_sources()[&(block, pred)] { - tmp.clone_from(exit_state); - analysis - .apply_switch_int_edge_effect(&mut data, &mut tmp, value, targets); - propagate(pred, &tmp); - } + mir::TerminatorKind::SwitchInt { ref discr, .. } => { + if let Some(_data) = analysis.get_switch_int_data(pred, discr) { + bug!( + "SwitchInt edge effects are unsupported in backward dataflow analyses" + ); } else { propagate(pred, exit_state) }