Skip to content

Commit 3f4afce

Browse files
committed
Use optimized_mir_summary.
1 parent d41a04d commit 3f4afce

File tree

2 files changed

+56
-14
lines changed

2 files changed

+56
-14
lines changed

compiler/rustc_middle/src/ty/mod.rs

+33-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub use self::IntVarValue::*;
1717
pub use self::Variance::*;
1818
use crate::metadata::ModChild;
1919
use crate::middle::privacy::AccessLevels;
20-
use crate::mir::{Body, GeneratorLayout};
20+
use crate::mir::{self, Body, GeneratorLayout};
2121
use crate::traits::{self, Reveal};
2222
use crate::ty;
2323
use crate::ty::fast_reject::SimplifiedType;
@@ -2160,6 +2160,38 @@ impl<'tcx> TyCtxt<'tcx> {
21602160
}
21612161
}
21622162

2163+
/// Returns the possibly-auto-generated MIR of a `(DefId, Subst)` pair.
2164+
pub fn instance_mir_summary(self, instance: ty::InstanceDef<'tcx>) -> mir::Summary {
2165+
match instance {
2166+
ty::InstanceDef::Item(def) => match self.def_kind(def.did) {
2167+
DefKind::Const
2168+
| DefKind::Static(..)
2169+
| DefKind::AssocConst
2170+
| DefKind::Ctor(..)
2171+
| DefKind::AnonConst
2172+
| DefKind::InlineConst => {
2173+
mir::Summary { inlining_cost: 0, bbcount: 0, diverges: false }
2174+
}
2175+
// If the caller wants `mir_for_ctfe` of a function they should not be using
2176+
// `instance_mir`, so we'll assume const fn also wants the optimized version.
2177+
_ => {
2178+
assert_eq!(def.const_param_did, None);
2179+
self.optimized_mir_summary(def.did)
2180+
}
2181+
},
2182+
ty::InstanceDef::VTableShim(..)
2183+
| ty::InstanceDef::ReifyShim(..)
2184+
| ty::InstanceDef::Intrinsic(..)
2185+
| ty::InstanceDef::FnPtrShim(..)
2186+
| ty::InstanceDef::Virtual(..)
2187+
| ty::InstanceDef::ClosureOnceShim { .. }
2188+
| ty::InstanceDef::DropGlue(..)
2189+
| ty::InstanceDef::CloneShim(..) => {
2190+
mir::Summary { inlining_cost: 0, bbcount: 0, diverges: false }
2191+
}
2192+
}
2193+
}
2194+
21632195
// FIXME(@lcnr): Remove this function.
21642196
pub fn get_attrs_unchecked(self, did: DefId) -> &'tcx [ast::Attribute] {
21652197
if let Some(did) = did.as_local() {

compiler/rustc_mir_transform/src/inline.rs

+23-13
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,7 @@ impl<'tcx> Inliner<'tcx> {
151151
let callee_attrs = self.tcx.codegen_fn_attrs(callsite.callee.def_id());
152152
self.check_codegen_attributes(callsite, callee_attrs)?;
153153
self.check_mir_is_available(caller_body, &callsite.callee)?;
154-
let callee_body = self.tcx.instance_mir(callsite.callee.def);
155-
self.check_mir_body(callsite, callee_body, callee_attrs)?;
154+
let callee_body = self.check_mir_body(callsite, callee_attrs)?;
156155

157156
if !self.tcx.consider_optimizing(|| {
158157
format!("Inline {:?} into {:?}", callsite.callee, caller_body.source)
@@ -385,43 +384,54 @@ impl<'tcx> Inliner<'tcx> {
385384

386385
/// Returns inlining decision that is based on the examination of callee MIR body.
387386
/// Assumes that codegen attributes have been checked for compatibility already.
388-
#[instrument(level = "debug", skip(self, callee_body))]
387+
#[instrument(level = "debug", skip(self))]
389388
fn check_mir_body(
390389
&self,
391390
callsite: &CallSite<'tcx>,
392-
callee_body: &Body<'tcx>,
393391
callee_attrs: &CodegenFnAttrs,
394-
) -> Result<(), &'static str> {
395-
let cost_info = body_cost(self.tcx, self.param_env, callee_body, |ty| {
396-
callsite.callee.subst_mir(self.tcx, &ty)
397-
});
392+
) -> Result<&'tcx Body<'tcx>, &'static str> {
393+
if let InlineAttr::Always = callee_attrs.inline {
394+
debug!("INLINING {:?} because inline(always)", callsite,);
395+
let callee_body = self.tcx.instance_mir(callsite.callee.def);
396+
return Ok(callee_body);
397+
}
398398

399399
let mut threshold = if callee_attrs.requests_inline() {
400400
self.tcx.sess.opts.unstable_opts.inline_mir_hint_threshold.unwrap_or(100)
401401
} else {
402402
self.tcx.sess.opts.unstable_opts.inline_mir_threshold.unwrap_or(50)
403403
};
404404

405+
let callee_summary = self.tcx.instance_mir_summary(callsite.callee.def);
405406
// Give a bonus functions with a small number of blocks,
406407
// We normally have two or three blocks for even
407408
// very small functions.
408-
if cost_info.bbcount <= 3 {
409+
if callee_summary.bbcount <= 3 {
409410
threshold += threshold / 4;
410411
}
412+
if callee_summary.diverges {
413+
threshold = 0;
414+
}
411415
debug!(" final inline threshold = {}", threshold);
412416

413-
if cost_info.diverges {
414-
threshold = 0;
417+
// Fast reject based on unsubstituted MIR.
418+
if callee_summary.inlining_cost >= 2 * threshold {
419+
return Err("summary cost above threshold");
415420
}
416421

422+
let callee_body = self.tcx.instance_mir(callsite.callee.def);
423+
let cost_info = body_cost(self.tcx, self.param_env, callee_body, |ty| {
424+
callsite.callee.subst_mir(self.tcx, &ty)
425+
});
426+
417427
let cost = cost_info.cost;
418428

419429
if let InlineAttr::Always = callee_attrs.inline {
420430
debug!("INLINING {:?} because inline(always) [cost={}]", callsite, cost);
421-
Ok(())
431+
Ok(callee_body)
422432
} else if cost <= threshold {
423433
debug!("INLINING {:?} [cost={} <= threshold={}]", callsite, cost, threshold);
424-
Ok(())
434+
Ok(callee_body)
425435
} else {
426436
debug!("NOT inlining {:?} [cost={} > threshold={}]", callsite, cost, threshold);
427437
Err("cost above threshold")

0 commit comments

Comments
 (0)