diff options
Diffstat (limited to 'src/librustc_mir/transform/inline.rs')
| -rw-r--r-- | src/librustc_mir/transform/inline.rs | 51 |
1 files changed, 28 insertions, 23 deletions
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index b6802505df7..157dada831a 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -1,30 +1,29 @@ //! Inlining pass for MIR functions +use rustc_attr as attr; use rustc_hir::def_id::DefId; - use rustc_index::bit_set::BitSet; use rustc_index::vec::{Idx, IndexVec}; - -use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags; -use rustc::mir::visit::*; -use rustc::mir::*; -use rustc::session::config::Sanitizer; -use rustc::ty::subst::{InternalSubsts, Subst, SubstsRef}; -use rustc::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; +use rustc_middle::mir::visit::*; +use rustc_middle::mir::*; +use rustc_middle::ty::subst::{Subst, SubstsRef}; +use rustc_middle::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt}; +use rustc_session::config::Sanitizer; +use rustc_target::spec::abi::Abi; use super::simplify::{remove_dead_blocks, CfgSimplifier}; use crate::transform::{MirPass, MirSource}; use std::collections::VecDeque; use std::iter; -use rustc_attr as attr; -use rustc_target::spec::abi::Abi; - const DEFAULT_THRESHOLD: usize = 50; const HINT_THRESHOLD: usize = 100; const INSTR_COST: usize = 5; const CALL_PENALTY: usize = 25; +const LANDINGPAD_PENALTY: usize = 50; +const RESUME_PENALTY: usize = 45; const UNKNOWN_SIZE_COST: usize = 10; @@ -67,14 +66,7 @@ impl Inliner<'tcx> { let mut callsites = VecDeque::new(); - let mut param_env = self.tcx.param_env(self.source.def_id()); - - let substs = &InternalSubsts::identity_for_item(self.tcx, self.source.def_id()); - - // For monomorphic functions, we can use `Reveal::All` to resolve specialized instances. - if !substs.needs_subst() { - param_env = param_env.with_reveal_all(); - } + let param_env = self.tcx.param_env(self.source.def_id()).with_reveal_all(); // Only do inlining into fn bodies. let id = self.tcx.hir().as_local_hir_id(self.source.def_id()).unwrap(); @@ -328,6 +320,7 @@ impl Inliner<'tcx> { if ty.needs_drop(tcx, param_env) { cost += CALL_PENALTY; if let Some(unwind) = unwind { + cost += LANDINGPAD_PENALTY; work_list.push(unwind); } } else { @@ -343,7 +336,7 @@ impl Inliner<'tcx> { threshold = 0; } - TerminatorKind::Call { func: Operand::Constant(ref f), .. } => { + TerminatorKind::Call { func: Operand::Constant(ref f), cleanup, .. } => { if let ty::FnDef(def_id, _) = f.literal.ty.kind { // Don't give intrinsics the extra penalty for calls let f = tcx.fn_sig(def_id); @@ -352,9 +345,21 @@ impl Inliner<'tcx> { } else { cost += CALL_PENALTY; } + } else { + cost += CALL_PENALTY; + } + if cleanup.is_some() { + cost += LANDINGPAD_PENALTY; + } + } + TerminatorKind::Assert { cleanup, .. } => { + cost += CALL_PENALTY; + + if cleanup.is_some() { + cost += LANDINGPAD_PENALTY; } } - TerminatorKind::Assert { .. } => cost += CALL_PENALTY, + TerminatorKind::Resume => cost += RESUME_PENALTY, _ => cost += INSTR_COST, } @@ -445,7 +450,7 @@ impl Inliner<'tcx> { // Place could result in two different locations if `f` // writes to `i`. To prevent this we need to create a temporary // borrow of the place and pass the destination as `*temp` instead. - fn dest_needs_borrow(place: &Place<'_>) -> bool { + fn dest_needs_borrow(place: Place<'_>) -> bool { for elem in place.projection.iter() { match elem { ProjectionElem::Deref | ProjectionElem::Index(_) => return true, @@ -456,7 +461,7 @@ impl Inliner<'tcx> { false } - let dest = if dest_needs_borrow(&destination.0) { + let dest = if dest_needs_borrow(destination.0) { debug!("creating temp for return destination"); let dest = Rvalue::Ref( self.tcx.lifetimes.re_erased, |
