Skip to content

Commit 2be012a

Browse files
committed
Use sparse representation of switch sources
to avoid quadratic space overhead
1 parent fbc3cc1 commit 2be012a

File tree

3 files changed

+8
-10
lines changed

3 files changed

+8
-10
lines changed

compiler/rustc_middle/src/mir/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -580,8 +580,8 @@ impl<'tcx> Body<'tcx> {
580580
self.predecessor_cache.compute(&self.basic_blocks)
581581
}
582582

583-
/// `body.switch_sources()[target][switch]` returns a list of switch values
584-
/// that lead to a `target` block from a `switch` block.
583+
/// `body.switch_sources()[&(target, switch)]` returns a list of switch
584+
/// values that lead to a `target` block from a `switch` block.
585585
#[inline]
586586
pub fn switch_sources(&self) -> &SwitchSources {
587587
self.switch_source_cache.compute(&self.basic_blocks)

compiler/rustc_middle/src/mir/switch_sources.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
//! `Predecessors`/`PredecessorCache`.
33
44
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
5+
use rustc_data_structures::stable_map::FxHashMap;
56
use rustc_data_structures::sync::OnceCell;
67
use rustc_index::vec::IndexVec;
78
use rustc_serialize as serialize;
89
use smallvec::SmallVec;
910

1011
use crate::mir::{BasicBlock, BasicBlockData, Terminator, TerminatorKind};
1112

12-
pub type SwitchSources = IndexVec<BasicBlock, IndexVec<BasicBlock, SmallVec<[Option<u128>; 1]>>>;
13+
pub type SwitchSources = FxHashMap<(BasicBlock, BasicBlock), SmallVec<[Option<u128>; 1]>>;
1314

1415
#[derive(Clone, Debug)]
1516
pub(super) struct SwitchSourceCache {
@@ -35,19 +36,16 @@ impl SwitchSourceCache {
3536
basic_blocks: &IndexVec<BasicBlock, BasicBlockData<'_>>,
3637
) -> &SwitchSources {
3738
self.cache.get_or_init(|| {
38-
let mut switch_sources = IndexVec::from_elem(
39-
IndexVec::from_elem(SmallVec::new(), basic_blocks),
40-
basic_blocks,
41-
);
39+
let mut switch_sources: SwitchSources = FxHashMap::default();
4240
for (bb, data) in basic_blocks.iter_enumerated() {
4341
if let Some(Terminator {
4442
kind: TerminatorKind::SwitchInt { targets, .. }, ..
4543
}) = &data.terminator
4644
{
4745
for (value, target) in targets.iter() {
48-
switch_sources[target][bb].push(Some(value));
46+
switch_sources.entry((target, bb)).or_default().push(Some(value));
4947
}
50-
switch_sources[targets.otherwise()][bb].push(None);
48+
switch_sources.entry((targets.otherwise(), bb)).or_default().push(None);
5149
}
5250
}
5351

compiler/rustc_mir_dataflow/src/framework/direction.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ where
322322
fn apply(&mut self, mut apply_edge_effect: impl FnMut(&mut D, SwitchIntTarget)) {
323323
assert!(!self.effects_applied);
324324

325-
let values = &self.body.switch_sources()[self.bb][self.pred];
325+
let values = &self.body.switch_sources()[&(self.bb, self.pred)];
326326
let targets = values.iter().map(|&value| SwitchIntTarget { value, target: self.bb });
327327

328328
let mut tmp = None;

0 commit comments

Comments
 (0)