]>
Commit | Line | Data |
---|---|---|
29967ef6 XL |
1 | //! SSA analysis |
2 | ||
3 | use crate::prelude::*; | |
4 | ||
5 | use rustc_index::vec::IndexVec; | |
6 | use rustc_middle::mir::StatementKind::*; | |
7 | ||
8 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] | |
9 | pub(crate) enum SsaKind { | |
10 | NotSsa, | |
11 | Ssa, | |
12 | } | |
13 | ||
14 | pub(crate) fn analyze(fx: &FunctionCx<'_, '_, impl Module>) -> IndexVec<Local, SsaKind> { | |
15 | let mut flag_map = fx | |
16 | .mir | |
17 | .local_decls | |
18 | .iter() | |
19 | .map(|local_decl| { | |
fc512014 | 20 | let ty = fx.monomorphize(local_decl.ty); |
29967ef6 XL |
21 | if fx.clif_type(ty).is_some() || fx.clif_pair_type(ty).is_some() { |
22 | SsaKind::Ssa | |
23 | } else { | |
24 | SsaKind::NotSsa | |
25 | } | |
26 | }) | |
27 | .collect::<IndexVec<Local, SsaKind>>(); | |
28 | ||
29 | for bb in fx.mir.basic_blocks().iter() { | |
30 | for stmt in bb.statements.iter() { | |
31 | match &stmt.kind { | |
32 | Assign(place_and_rval) => match &place_and_rval.1 { | |
33 | Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => { | |
34 | not_ssa(&mut flag_map, place.local) | |
35 | } | |
36 | _ => {} | |
37 | }, | |
38 | _ => {} | |
39 | } | |
40 | } | |
41 | ||
42 | match &bb.terminator().kind { | |
43 | TerminatorKind::Call { destination, .. } => { | |
44 | if let Some((dest_place, _dest_bb)) = destination { | |
45 | let dest_layout = fx | |
46 | .layout_of(fx.monomorphize(&dest_place.ty(&fx.mir.local_decls, fx.tcx).ty)); | |
47 | if !crate::abi::can_return_to_ssa_var(fx.tcx, dest_layout) { | |
48 | not_ssa(&mut flag_map, dest_place.local) | |
49 | } | |
50 | } | |
51 | } | |
52 | _ => {} | |
53 | } | |
54 | } | |
55 | ||
56 | flag_map | |
57 | } | |
58 | ||
59 | fn not_ssa(flag_map: &mut IndexVec<Local, SsaKind>, local: Local) { | |
60 | flag_map[local] = SsaKind::NotSsa; | |
61 | } |