]> git.lizzy.rs Git - rust.git/blobdiff - src/analyze.rs
fmt: Run cargo fmt since it is available
[rust.git] / src / analyze.rs
index fe58eaa18bb87f819e98b9e5b2522ff691dd389d..055b371f43c3c064dd97bf0edac92f4db7bb84e1 100644 (file)
@@ -1,30 +1,35 @@
 use crate::prelude::*;
 
-use rustc::mir::StatementKind::*;
+use rustc_index::vec::IndexVec;
+use rustc_middle::mir::StatementKind::*;
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
-pub enum SsaKind {
+pub(crate) enum SsaKind {
     NotSsa,
     Ssa,
 }
 
-pub fn analyze(fx: &FunctionCx<'_, '_, impl Backend>) -> HashMap<Local, SsaKind> {
-    let mut flag_map = HashMap::new();
-
-    for (local, local_decl) in fx.mir.local_decls.iter_enumerated() {
-        if fx.clif_type(local_decl.ty).is_some() {
-            flag_map.insert(local, SsaKind::Ssa);
-        } else {
-            flag_map.insert(local, SsaKind::NotSsa);
-        }
-    }
+pub(crate) fn analyze(fx: &FunctionCx<'_, '_, impl Backend>) -> IndexVec<Local, SsaKind> {
+    let mut flag_map = fx
+        .mir
+        .local_decls
+        .iter()
+        .map(|local_decl| {
+            let ty = fx.monomorphize(&local_decl.ty);
+            if fx.clif_type(ty).is_some() || fx.clif_pair_type(ty).is_some() {
+                SsaKind::Ssa
+            } else {
+                SsaKind::NotSsa
+            }
+        })
+        .collect::<IndexVec<Local, SsaKind>>();
 
     for bb in fx.mir.basic_blocks().iter() {
         for stmt in bb.statements.iter() {
             match &stmt.kind {
                 Assign(place_and_rval) => match &place_and_rval.1 {
-                    Rvalue::Ref(_, _, place) => {
-                        analyze_non_ssa_place(&mut flag_map, place);
+                    Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => {
+                        not_ssa(&mut flag_map, place.local)
                     }
                     _ => {}
                 },
@@ -33,10 +38,15 @@ pub fn analyze(fx: &FunctionCx<'_, '_, impl Backend>) -> HashMap<Local, SsaKind>
         }
 
         match &bb.terminator().kind {
-            TerminatorKind::Call {
-                destination: Some((place, _)),
-                ..
-            } => analyze_non_ssa_place(&mut flag_map, place),
+            TerminatorKind::Call { destination, .. } => {
+                if let Some((dest_place, _dest_bb)) = destination {
+                    let dest_layout = fx
+                        .layout_of(fx.monomorphize(&dest_place.ty(&fx.mir.local_decls, fx.tcx).ty));
+                    if !crate::abi::can_return_to_ssa_var(fx.tcx, dest_layout) {
+                        not_ssa(&mut flag_map, dest_place.local)
+                    }
+                }
+            }
             _ => {}
         }
     }
@@ -44,13 +54,6 @@ pub fn analyze(fx: &FunctionCx<'_, '_, impl Backend>) -> HashMap<Local, SsaKind>
     flag_map
 }
 
-fn analyze_non_ssa_place(flag_map: &mut HashMap<Local, SsaKind>, place: &Place) {
-    match place.base {
-        PlaceBase::Local(local) => not_ssa(flag_map, local),
-        _ => {}
-    }
-}
-
-fn not_ssa<L: ::std::borrow::Borrow<Local>>(flag_map: &mut HashMap<Local, SsaKind>, local: L) {
-    *flag_map.get_mut(local.borrow()).unwrap() = SsaKind::NotSsa;
+fn not_ssa(flag_map: &mut IndexVec<Local, SsaKind>, local: Local) {
+    flag_map[local] = SsaKind::NotSsa;
 }