]> git.lizzy.rs Git - rust.git/blobdiff - src/analyze.rs
Rollup merge of #81618 - bjorn3:sync_cg_clif-2021-02-01, r=bjorn3
[rust.git] / src / analyze.rs
index d118665b92bb30edc8867bf40788a696b15211b1..62fbcfe3f7a5df6bda3f4c7b4093b6aa4ba875e7 100644 (file)
@@ -1,47 +1,64 @@
+//! SSA analysis
+
 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>) -> IndexVec<Local, SsaKind> {
-    let mut flag_map = fx.mir.local_decls.iter().map(|local_decl| {
-        if fx.clif_type(local_decl.ty).is_some() {
-            SsaKind::Ssa
-        } else {
-            SsaKind::NotSsa
-        }
-    }).collect::<IndexVec<Local, SsaKind>>();
+pub(crate) fn analyze(fx: &FunctionCx<'_, '_, impl Module>) -> 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)
                     }
                     _ => {}
                 },
                 _ => {}
             }
         }
+
+        match &bb.terminator().kind {
+            TerminatorKind::Call {
+                destination,
+                func,
+                args,
+                ..
+            } => {
+                if let Some((dest_place, _dest_bb)) = destination {
+                    if !crate::abi::can_return_to_ssa_var(fx, func, args) {
+                        not_ssa(&mut flag_map, dest_place.local)
+                    }
+                }
+            }
+            _ => {}
+        }
     }
 
     flag_map
 }
 
-fn analyze_non_ssa_place(flag_map: &mut IndexVec<Local, SsaKind>, place: &Place) {
-    match place.base {
-        PlaceBase::Local(local) => not_ssa(flag_map, local),
-        _ => {}
-    }
-}
-
 fn not_ssa(flag_map: &mut IndexVec<Local, SsaKind>, local: Local) {
     flag_map[local] = SsaKind::NotSsa;
 }