Skip to content

Remove support for SwitchInt edge effects in backward dataflow #143769

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 1 addition & 39 deletions compiler/rustc_middle/src/mir/basic_blocks.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand All @@ -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> {
Expand All @@ -21,15 +20,6 @@ pub struct BasicBlocks<'tcx> {
// Typically 95%+ of basic blocks have 4 or fewer predecessors.
type Predecessors = IndexVec<BasicBlock, SmallVec<[BasicBlock; 4]>>;

/// 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.
Expand All @@ -41,7 +31,6 @@ pub enum SwitchTargetValue {
#[derive(Clone, Default, Debug)]
struct Cache {
predecessors: OnceLock<Predecessors>,
switch_sources: OnceLock<SwitchSources>,
reverse_postorder: OnceLock<Vec<BasicBlock>>,
dominators: OnceLock<Dominators<BasicBlock>>,
}
Expand Down Expand Up @@ -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<BasicBlock, BasicBlockData<'tcx>> {
Expand Down
15 changes: 6 additions & 9 deletions compiler/rustc_mir_dataflow/src/framework/direction.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::ops::RangeInclusive;

use rustc_middle::bug;
use rustc_middle::mir::{
self, BasicBlock, CallReturnPlaces, Location, SwitchTargetValue, TerminatorEdges,
};
Expand Down Expand Up @@ -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(block, 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)
}
Expand Down
Loading