diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 9911f20655c..fc860010813 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -10,7 +10,7 @@ use cranelift_codegen::ir::AbiParam; use self::pass_mode::*; use crate::prelude::*; -pub use self::returning::codegen_return; +pub use self::returning::{can_return_to_ssa_var, codegen_return}; // Copied from https://github.com/rust-lang/rust/blob/c2f4c57296f0d929618baed0b0d6eb594abf01eb/src/librustc/ty/layout.rs#L2349 pub fn fn_sig_for_fn_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> ty::PolyFnSig<'tcx> { diff --git a/src/abi/returning.rs b/src/abi/returning.rs index d566a517664..a503c6d795a 100644 --- a/src/abi/returning.rs +++ b/src/abi/returning.rs @@ -5,6 +5,14 @@ fn return_layout<'a, 'tcx>(fx: &mut FunctionCx<'a, 'tcx, impl Backend>) -> TyLay fx.layout_of(fx.monomorphize(&fx.mir.local_decls[RETURN_PLACE].ty)) } +pub fn can_return_to_ssa_var<'tcx>(tcx: TyCtxt<'tcx>, dest_layout: TyLayout<'tcx>) -> bool { + match get_pass_mode(tcx, dest_layout) { + PassMode::NoPass | PassMode::ByVal(_) => true, + // FIXME Make it possible to return ByValPair and ByRef to an ssa var. + PassMode::ByValPair(_, _) | PassMode::ByRef => false + } +} + pub fn codegen_return_param( fx: &mut FunctionCx, ssa_analyzed: &rustc_index::vec::IndexVec, diff --git a/src/analyze.rs b/src/analyze.rs index d118665b92b..3bebf0ed777 100644 --- a/src/analyze.rs +++ b/src/analyze.rs @@ -30,6 +30,18 @@ pub fn analyze(fx: &FunctionCx<'_, '_, impl Backend>) -> IndexVec {} } } + + match &bb.terminator().kind { + 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) { + analyze_non_ssa_place(&mut flag_map, dest_place); + } + } + } + _ => {} + } } flag_map