Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 18a3746

Browse filesBrowse files
authored
Unrolled build for rust-lang#136959
Rollup merge of rust-lang#136959 - nnethercote:simplify-SwitchSources, r=tmiasko Simplify switch sources `SwitchSources` and the code around it can be simplified. r? `@tmiasko`
2 parents ce36a96 + 3b81d9d commit 18a3746
Copy full SHA for 18a3746

File tree

Expand file treeCollapse file tree

6 files changed

+68
-46
lines changed
Filter options
Expand file treeCollapse file tree

6 files changed

+68
-46
lines changed

‎compiler/rustc_middle/src/mir/basic_blocks.rs

Copy file name to clipboardExpand all lines: compiler/rustc_middle/src/mir/basic_blocks.rs
+26-5Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,22 @@ pub struct BasicBlocks<'tcx> {
2020
// Typically 95%+ of basic blocks have 4 or fewer predecessors.
2121
type Predecessors = IndexVec<BasicBlock, SmallVec<[BasicBlock; 4]>>;
2222

23-
type SwitchSources = FxHashMap<(BasicBlock, BasicBlock), SmallVec<[Option<u128>; 1]>>;
23+
/// Each `(target, switch)` entry in the map contains a list of switch values
24+
/// that lead to a `target` block from a `switch` block.
25+
///
26+
/// Note: this type is currently never instantiated, because it's only used for
27+
/// `BasicBlocks::switch_sources`, which is only called by backwards analyses
28+
/// that do `SwitchInt` handling, and we don't have any of those, not even in
29+
/// tests. See #95120 and #94576.
30+
type SwitchSources = FxHashMap<(BasicBlock, BasicBlock), SmallVec<[SwitchTargetValue; 1]>>;
31+
32+
#[derive(Debug, Clone, Copy)]
33+
pub enum SwitchTargetValue {
34+
// A normal switch value.
35+
Normal(u128),
36+
// The final "otherwise" fallback value.
37+
Otherwise,
38+
}
2439

2540
#[derive(Clone, Default, Debug)]
2641
struct Cache {
@@ -70,8 +85,8 @@ impl<'tcx> BasicBlocks<'tcx> {
7085
})
7186
}
7287

73-
/// `switch_sources()[&(target, switch)]` returns a list of switch
74-
/// values that lead to a `target` block from a `switch` block.
88+
/// Returns info about switch values that lead from one block to another
89+
/// block. See `SwitchSources`.
7590
#[inline]
7691
pub fn switch_sources(&self) -> &SwitchSources {
7792
self.cache.switch_sources.get_or_init(|| {
@@ -82,9 +97,15 @@ impl<'tcx> BasicBlocks<'tcx> {
8297
}) = &data.terminator
8398
{
8499
for (value, target) in targets.iter() {
85-
switch_sources.entry((target, bb)).or_default().push(Some(value));
100+
switch_sources
101+
.entry((target, bb))
102+
.or_default()
103+
.push(SwitchTargetValue::Normal(value));
86104
}
87-
switch_sources.entry((targets.otherwise(), bb)).or_default().push(None);
105+
switch_sources
106+
.entry((targets.otherwise(), bb))
107+
.or_default()
108+
.push(SwitchTargetValue::Otherwise);
88109
}
89110
}
90111
switch_sources

‎compiler/rustc_middle/src/mir/mod.rs

Copy file name to clipboardExpand all lines: compiler/rustc_middle/src/mir/mod.rs
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::fmt::{self, Debug, Formatter};
77
use std::ops::{Index, IndexMut};
88
use std::{iter, mem};
99

10-
pub use basic_blocks::BasicBlocks;
10+
pub use basic_blocks::{BasicBlocks, SwitchTargetValue};
1111
use either::Either;
1212
use polonius_engine::Atom;
1313
use rustc_abi::{FieldIdx, VariantIdx};

‎compiler/rustc_middle/src/mir/syntax.rs

Copy file name to clipboardExpand all lines: compiler/rustc_middle/src/mir/syntax.rs
+19-11Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,22 +1015,30 @@ impl TerminatorKind<'_> {
10151015

10161016
#[derive(Debug, Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq)]
10171017
pub struct SwitchTargets {
1018-
/// Possible values. The locations to branch to in each case
1019-
/// are found in the corresponding indices from the `targets` vector.
1018+
/// Possible values. For each value, the location to branch to is found in
1019+
/// the corresponding element in the `targets` vector.
10201020
pub(super) values: SmallVec<[Pu128; 1]>,
10211021

1022-
/// Possible branch sites. The last element of this vector is used
1023-
/// for the otherwise branch, so targets.len() == values.len() + 1
1024-
/// should hold.
1022+
/// Possible branch targets. The last element of this vector is used for
1023+
/// the "otherwise" branch, so `targets.len() == values.len() + 1` always
1024+
/// holds.
10251025
//
1026-
// This invariant is quite non-obvious and also could be improved.
1027-
// One way to make this invariant is to have something like this instead:
1026+
// Note: This invariant is non-obvious and easy to violate. This would be a
1027+
// more rigorous representation:
10281028
//
1029-
// branches: Vec<(ConstInt, BasicBlock)>,
1030-
// otherwise: Option<BasicBlock> // exhaustive if None
1029+
// normal: SmallVec<[(Pu128, BasicBlock); 1]>,
1030+
// otherwise: BasicBlock,
10311031
//
1032-
// However we’ve decided to keep this as-is until we figure a case
1033-
// where some other approach seems to be strictly better than other.
1032+
// But it's important to have the targets in a sliceable type, because
1033+
// target slices show up elsewhere. E.g. `TerminatorKind::InlineAsm` has a
1034+
// boxed slice, and `TerminatorKind::FalseEdge` has a single target that
1035+
// can be converted to a slice with `slice::from_ref`.
1036+
//
1037+
// Why does this matter? In functions like `TerminatorKind::successors` we
1038+
// return `impl Iterator` and a non-slice-of-targets representation here
1039+
// causes problems because multiple different concrete iterator types would
1040+
// be involved and we would need a boxed trait object, which requires an
1041+
// allocation, which is expensive if done frequently.
10341042
pub(super) targets: SmallVec<[BasicBlock; 2]>,
10351043
}
10361044

‎compiler/rustc_mir_dataflow/src/framework/direction.rs

Copy file name to clipboardExpand all lines: compiler/rustc_mir_dataflow/src/framework/direction.rs
+11-16Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
use std::ops::RangeInclusive;
22

3-
use rustc_middle::mir::{self, BasicBlock, CallReturnPlaces, Location, TerminatorEdges};
3+
use rustc_middle::mir::{
4+
self, BasicBlock, CallReturnPlaces, Location, SwitchTargetValue, TerminatorEdges,
5+
};
46

57
use super::visitor::ResultsVisitor;
6-
use super::{Analysis, Effect, EffectIndex, Results, SwitchIntTarget};
8+
use super::{Analysis, Effect, EffectIndex, Results};
79

810
pub trait Direction {
911
const IS_FORWARD: bool;
@@ -112,14 +114,10 @@ impl Direction for Backward {
112114

113115
mir::TerminatorKind::SwitchInt { targets: _, ref discr } => {
114116
if let Some(mut data) = analysis.get_switch_int_data(block, discr) {
115-
let values = &body.basic_blocks.switch_sources()[&(block, pred)];
116-
let targets =
117-
values.iter().map(|&value| SwitchIntTarget { value, target: block });
118-
119117
let mut tmp = analysis.bottom_value(body);
120-
for target in targets {
121-
tmp.clone_from(&exit_state);
122-
analysis.apply_switch_int_edge_effect(&mut data, &mut tmp, target);
118+
for &value in &body.basic_blocks.switch_sources()[&(block, pred)] {
119+
tmp.clone_from(exit_state);
120+
analysis.apply_switch_int_edge_effect(&mut data, &mut tmp, value);
123121
propagate(pred, &tmp);
124122
}
125123
} else {
@@ -292,12 +290,9 @@ impl Direction for Forward {
292290
if let Some(mut data) = analysis.get_switch_int_data(block, discr) {
293291
let mut tmp = analysis.bottom_value(body);
294292
for (value, target) in targets.iter() {
295-
tmp.clone_from(&exit_state);
296-
analysis.apply_switch_int_edge_effect(
297-
&mut data,
298-
&mut tmp,
299-
SwitchIntTarget { value: Some(value), target },
300-
);
293+
tmp.clone_from(exit_state);
294+
let value = SwitchTargetValue::Normal(value);
295+
analysis.apply_switch_int_edge_effect(&mut data, &mut tmp, value);
301296
propagate(target, &tmp);
302297
}
303298

@@ -308,7 +303,7 @@ impl Direction for Forward {
308303
analysis.apply_switch_int_edge_effect(
309304
&mut data,
310305
exit_state,
311-
SwitchIntTarget { value: None, target: otherwise },
306+
SwitchTargetValue::Otherwise,
312307
);
313308
propagate(otherwise, exit_state);
314309
} else {

‎compiler/rustc_mir_dataflow/src/framework/mod.rs

Copy file name to clipboardExpand all lines: compiler/rustc_mir_dataflow/src/framework/mod.rs
+4-7Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ use rustc_data_structures::work_queue::WorkQueue;
3838
use rustc_index::bit_set::{DenseBitSet, MixedBitSet};
3939
use rustc_index::{Idx, IndexVec};
4040
use rustc_middle::bug;
41-
use rustc_middle::mir::{self, BasicBlock, CallReturnPlaces, Location, TerminatorEdges, traversal};
41+
use rustc_middle::mir::{
42+
self, BasicBlock, CallReturnPlaces, Location, SwitchTargetValue, TerminatorEdges, traversal,
43+
};
4244
use rustc_middle::ty::TyCtxt;
4345
use tracing::error;
4446

@@ -220,7 +222,7 @@ pub trait Analysis<'tcx> {
220222
&mut self,
221223
_data: &mut Self::SwitchIntData,
222224
_state: &mut Self::Domain,
223-
_edge: SwitchIntTarget,
225+
_value: SwitchTargetValue,
224226
) {
225227
unreachable!();
226228
}
@@ -430,10 +432,5 @@ impl EffectIndex {
430432
}
431433
}
432434

433-
pub struct SwitchIntTarget {
434-
pub value: Option<u128>,
435-
pub target: BasicBlock,
436-
}
437-
438435
#[cfg(test)]
439436
mod tests;

‎compiler/rustc_mir_dataflow/src/impls/initialized.rs

Copy file name to clipboardExpand all lines: compiler/rustc_mir_dataflow/src/impls/initialized.rs
+7-6Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@ use rustc_abi::VariantIdx;
44
use rustc_index::Idx;
55
use rustc_index::bit_set::{DenseBitSet, MixedBitSet};
66
use rustc_middle::bug;
7-
use rustc_middle::mir::{self, Body, CallReturnPlaces, Location, TerminatorEdges};
7+
use rustc_middle::mir::{
8+
self, Body, CallReturnPlaces, Location, SwitchTargetValue, TerminatorEdges,
9+
};
810
use rustc_middle::ty::util::Discr;
911
use rustc_middle::ty::{self, TyCtxt};
1012
use tracing::{debug, instrument};
1113

1214
use crate::drop_flag_effects::DropFlagState;
13-
use crate::framework::SwitchIntTarget;
1415
use crate::move_paths::{HasMoveData, InitIndex, InitKind, LookupResult, MoveData, MovePathIndex};
1516
use crate::{
1617
Analysis, GenKill, MaybeReachable, drop_flag_effects, drop_flag_effects_for_function_entry,
@@ -422,9 +423,9 @@ impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
422423
&mut self,
423424
data: &mut Self::SwitchIntData,
424425
state: &mut Self::Domain,
425-
edge: SwitchIntTarget,
426+
value: SwitchTargetValue,
426427
) {
427-
if let Some(value) = edge.value {
428+
if let SwitchTargetValue::Normal(value) = value {
428429
// Kill all move paths that correspond to variants we know to be inactive along this
429430
// particular outgoing edge of a `SwitchInt`.
430431
drop_flag_effects::on_all_inactive_variants(
@@ -535,9 +536,9 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
535536
&mut self,
536537
data: &mut Self::SwitchIntData,
537538
state: &mut Self::Domain,
538-
edge: SwitchIntTarget,
539+
value: SwitchTargetValue,
539540
) {
540-
if let Some(value) = edge.value {
541+
if let SwitchTargetValue::Normal(value) = value {
541542
// Mark all move paths that correspond to variants other than this one as maybe
542543
// uninitialized (in reality, they are *definitely* uninitialized).
543544
drop_flag_effects::on_all_inactive_variants(

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.