mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-12 23:13:15 +00:00
Use sparse representation of switch sources
to avoid quadratic space overhead
This commit is contained in:
parent
fbc3cc18be
commit
2be012a0c6
@ -580,8 +580,8 @@ impl<'tcx> Body<'tcx> {
|
|||||||
self.predecessor_cache.compute(&self.basic_blocks)
|
self.predecessor_cache.compute(&self.basic_blocks)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `body.switch_sources()[target][switch]` returns a list of switch values
|
/// `body.switch_sources()[&(target, switch)]` returns a list of switch
|
||||||
/// that lead to a `target` block from a `switch` block.
|
/// values that lead to a `target` block from a `switch` block.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn switch_sources(&self) -> &SwitchSources {
|
pub fn switch_sources(&self) -> &SwitchSources {
|
||||||
self.switch_source_cache.compute(&self.basic_blocks)
|
self.switch_source_cache.compute(&self.basic_blocks)
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
//! `Predecessors`/`PredecessorCache`.
|
//! `Predecessors`/`PredecessorCache`.
|
||||||
|
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||||
|
use rustc_data_structures::stable_map::FxHashMap;
|
||||||
use rustc_data_structures::sync::OnceCell;
|
use rustc_data_structures::sync::OnceCell;
|
||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
use rustc_serialize as serialize;
|
use rustc_serialize as serialize;
|
||||||
@ -9,7 +10,7 @@ use smallvec::SmallVec;
|
|||||||
|
|
||||||
use crate::mir::{BasicBlock, BasicBlockData, Terminator, TerminatorKind};
|
use crate::mir::{BasicBlock, BasicBlockData, Terminator, TerminatorKind};
|
||||||
|
|
||||||
pub type SwitchSources = IndexVec<BasicBlock, IndexVec<BasicBlock, SmallVec<[Option<u128>; 1]>>>;
|
pub type SwitchSources = FxHashMap<(BasicBlock, BasicBlock), SmallVec<[Option<u128>; 1]>>;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub(super) struct SwitchSourceCache {
|
pub(super) struct SwitchSourceCache {
|
||||||
@ -35,19 +36,16 @@ impl SwitchSourceCache {
|
|||||||
basic_blocks: &IndexVec<BasicBlock, BasicBlockData<'_>>,
|
basic_blocks: &IndexVec<BasicBlock, BasicBlockData<'_>>,
|
||||||
) -> &SwitchSources {
|
) -> &SwitchSources {
|
||||||
self.cache.get_or_init(|| {
|
self.cache.get_or_init(|| {
|
||||||
let mut switch_sources = IndexVec::from_elem(
|
let mut switch_sources: SwitchSources = FxHashMap::default();
|
||||||
IndexVec::from_elem(SmallVec::new(), basic_blocks),
|
|
||||||
basic_blocks,
|
|
||||||
);
|
|
||||||
for (bb, data) in basic_blocks.iter_enumerated() {
|
for (bb, data) in basic_blocks.iter_enumerated() {
|
||||||
if let Some(Terminator {
|
if let Some(Terminator {
|
||||||
kind: TerminatorKind::SwitchInt { targets, .. }, ..
|
kind: TerminatorKind::SwitchInt { targets, .. }, ..
|
||||||
}) = &data.terminator
|
}) = &data.terminator
|
||||||
{
|
{
|
||||||
for (value, target) in targets.iter() {
|
for (value, target) in targets.iter() {
|
||||||
switch_sources[target][bb].push(Some(value));
|
switch_sources.entry((target, bb)).or_default().push(Some(value));
|
||||||
}
|
}
|
||||||
switch_sources[targets.otherwise()][bb].push(None);
|
switch_sources.entry((targets.otherwise(), bb)).or_default().push(None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,7 +322,7 @@ where
|
|||||||
fn apply(&mut self, mut apply_edge_effect: impl FnMut(&mut D, SwitchIntTarget)) {
|
fn apply(&mut self, mut apply_edge_effect: impl FnMut(&mut D, SwitchIntTarget)) {
|
||||||
assert!(!self.effects_applied);
|
assert!(!self.effects_applied);
|
||||||
|
|
||||||
let values = &self.body.switch_sources()[self.bb][self.pred];
|
let values = &self.body.switch_sources()[&(self.bb, self.pred)];
|
||||||
let targets = values.iter().map(|&value| SwitchIntTarget { value, target: self.bb });
|
let targets = values.iter().map(|&value| SwitchIntTarget { value, target: self.bb });
|
||||||
|
|
||||||
let mut tmp = None;
|
let mut tmp = None;
|
||||||
|
Loading…
Reference in New Issue
Block a user