]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_middle/src/mir/switch_sources.rs
New upstream version 1.63.0+dfsg1
[rustc.git] / compiler / rustc_middle / src / mir / switch_sources.rs
CommitLineData
5e7ed085
FG
1//! Lazily compute the inverse of each `SwitchInt`'s switch targets. Modeled after
2//! `Predecessors`/`PredecessorCache`.
3
4use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
04454e1e 5use rustc_data_structures::stable_map::FxHashMap;
5e7ed085
FG
6use rustc_data_structures::sync::OnceCell;
7use rustc_index::vec::IndexVec;
923072b8 8use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
5e7ed085
FG
9use smallvec::SmallVec;
10
11use crate::mir::{BasicBlock, BasicBlockData, Terminator, TerminatorKind};
12
04454e1e 13pub type SwitchSources = FxHashMap<(BasicBlock, BasicBlock), SmallVec<[Option<u128>; 1]>>;
5e7ed085
FG
14
15#[derive(Clone, Debug)]
16pub(super) struct SwitchSourceCache {
17 cache: OnceCell<SwitchSources>,
18}
19
20impl SwitchSourceCache {
21 #[inline]
22 pub(super) fn new() -> Self {
23 SwitchSourceCache { cache: OnceCell::new() }
24 }
25
26 /// Invalidates the switch source cache.
27 #[inline]
28 pub(super) fn invalidate(&mut self) {
29 self.cache = OnceCell::new();
30 }
31
32 /// Returns the switch sources for this MIR.
33 #[inline]
34 pub(super) fn compute(
35 &self,
36 basic_blocks: &IndexVec<BasicBlock, BasicBlockData<'_>>,
37 ) -> &SwitchSources {
38 self.cache.get_or_init(|| {
04454e1e 39 let mut switch_sources: SwitchSources = FxHashMap::default();
5e7ed085
FG
40 for (bb, data) in basic_blocks.iter_enumerated() {
41 if let Some(Terminator {
42 kind: TerminatorKind::SwitchInt { targets, .. }, ..
43 }) = &data.terminator
44 {
45 for (value, target) in targets.iter() {
04454e1e 46 switch_sources.entry((target, bb)).or_default().push(Some(value));
5e7ed085 47 }
04454e1e 48 switch_sources.entry((targets.otherwise(), bb)).or_default().push(None);
5e7ed085
FG
49 }
50 }
51
52 switch_sources
53 })
54 }
55}
56
923072b8 57impl<S: Encoder> Encodable<S> for SwitchSourceCache {
5e7ed085 58 #[inline]
923072b8 59 fn encode(&self, _s: &mut S) {}
5e7ed085
FG
60}
61
923072b8 62impl<D: Decoder> Decodable<D> for SwitchSourceCache {
5e7ed085
FG
63 #[inline]
64 fn decode(_: &mut D) -> Self {
65 Self::new()
66 }
67}
68
69impl<CTX> HashStable<CTX> for SwitchSourceCache {
70 #[inline]
71 fn hash_stable(&self, _: &mut CTX, _: &mut StableHasher) {
72 // do nothing
73 }
74}
75
76TrivialTypeFoldableAndLiftImpls! {
77 SwitchSourceCache,
78}