Skip to content

Commit 26659c6

Browse files
committed
inline: force inlining shims
1 parent d370964 commit 26659c6

File tree

3 files changed

+27
-12
lines changed

3 files changed

+27
-12
lines changed

compiler/rustc_mir_transform/src/inline.rs

+15-11
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::ops::{Range, RangeFrom};
66
use rustc_abi::{ExternAbi, FieldIdx};
77
use rustc_attr::InlineAttr;
88
use rustc_hir::def::DefKind;
9-
use rustc_hir::def_id::{DefId, LocalDefId};
9+
use rustc_hir::def_id::DefId;
1010
use rustc_index::Idx;
1111
use rustc_index::bit_set::BitSet;
1212
use rustc_middle::bug;
@@ -98,12 +98,12 @@ impl<'tcx> crate::MirPass<'tcx> for ForceInline {
9898
}
9999

100100
trait Inliner<'tcx> {
101-
fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body<'tcx>) -> Self;
101+
fn new(tcx: TyCtxt<'tcx>, def_id: DefId, body: &Body<'tcx>) -> Self;
102102

103103
fn tcx(&self) -> TyCtxt<'tcx>;
104104
fn typing_env(&self) -> ty::TypingEnv<'tcx>;
105105
fn history(&self) -> &[DefId];
106-
fn caller_def_id(&self) -> LocalDefId;
106+
fn caller_def_id(&self) -> DefId;
107107

108108
/// Has the caller body been changed?
109109
fn changed(self) -> bool;
@@ -146,7 +146,7 @@ struct ForceInliner<'tcx> {
146146
tcx: TyCtxt<'tcx>,
147147
typing_env: ty::TypingEnv<'tcx>,
148148
/// `DefId` of caller.
149-
def_id: LocalDefId,
149+
def_id: DefId,
150150
/// Stack of inlined instances.
151151
/// We only check the `DefId` and not the args because we want to
152152
/// avoid inlining cases of polymorphic recursion.
@@ -158,7 +158,7 @@ struct ForceInliner<'tcx> {
158158
}
159159

160160
impl<'tcx> Inliner<'tcx> for ForceInliner<'tcx> {
161-
fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body<'tcx>) -> Self {
161+
fn new(tcx: TyCtxt<'tcx>, def_id: DefId, body: &Body<'tcx>) -> Self {
162162
Self { tcx, typing_env: body.typing_env(tcx), def_id, history: Vec::new(), changed: false }
163163
}
164164

@@ -174,7 +174,7 @@ impl<'tcx> Inliner<'tcx> for ForceInliner<'tcx> {
174174
&self.history
175175
}
176176

177-
fn caller_def_id(&self) -> LocalDefId {
177+
fn caller_def_id(&self) -> DefId {
178178
self.def_id
179179
}
180180

@@ -248,7 +248,7 @@ struct NormalInliner<'tcx> {
248248
tcx: TyCtxt<'tcx>,
249249
typing_env: ty::TypingEnv<'tcx>,
250250
/// `DefId` of caller.
251-
def_id: LocalDefId,
251+
def_id: DefId,
252252
/// Stack of inlined instances.
253253
/// We only check the `DefId` and not the args because we want to
254254
/// avoid inlining cases of polymorphic recursion.
@@ -263,7 +263,7 @@ struct NormalInliner<'tcx> {
263263
}
264264

265265
impl<'tcx> Inliner<'tcx> for NormalInliner<'tcx> {
266-
fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body<'tcx>) -> Self {
266+
fn new(tcx: TyCtxt<'tcx>, def_id: DefId, body: &Body<'tcx>) -> Self {
267267
let typing_env = body.typing_env(tcx);
268268
let codegen_fn_attrs = tcx.codegen_fn_attrs(def_id);
269269

@@ -284,7 +284,7 @@ impl<'tcx> Inliner<'tcx> for NormalInliner<'tcx> {
284284
self.tcx
285285
}
286286

287-
fn caller_def_id(&self) -> LocalDefId {
287+
fn caller_def_id(&self) -> DefId {
288288
self.def_id
289289
}
290290

@@ -442,7 +442,7 @@ impl<'tcx> Inliner<'tcx> for NormalInliner<'tcx> {
442442
}
443443

444444
fn inline<'tcx, T: Inliner<'tcx>>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool {
445-
let def_id = body.source.def_id().expect_local();
445+
let def_id = body.source.def_id();
446446

447447
// Only do inlining into fn bodies.
448448
if !tcx.hir().body_owner_kind(def_id).is_fn_or_closure() {
@@ -722,7 +722,11 @@ fn check_mir_is_available<'tcx, I: Inliner<'tcx>>(
722722
return Ok(());
723723
}
724724

725-
if callee_def_id.is_local() {
725+
if callee_def_id.is_local()
726+
&& !inliner
727+
.tcx()
728+
.is_lang_item(inliner.tcx().parent(caller_def_id), rustc_hir::LangItem::FnOnce)
729+
{
726730
// If we know for sure that the function we're calling will itself try to
727731
// call us, then we avoid inlining that function.
728732
if inliner.tcx().mir_callgraph_reachable((callee, caller_def_id.expect_local())) {

compiler/rustc_mir_transform/src/shim.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use rustc_span::{DUMMY_SP, Span};
1919
use tracing::{debug, instrument};
2020

2121
use crate::{
22-
abort_unwinding_calls, add_call_guards, add_moves_for_packed_drops, deref_separator,
22+
abort_unwinding_calls, add_call_guards, add_moves_for_packed_drops, deref_separator, inline,
2323
instsimplify, mentioned_items, pass_manager as pm, remove_noop_landing_pads, simplify,
2424
};
2525

@@ -154,6 +154,8 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body<
154154
&remove_noop_landing_pads::RemoveNoopLandingPads,
155155
&simplify::SimplifyCfg::MakeShim,
156156
&instsimplify::InstSimplify::BeforeInline,
157+
// Perform inlining of `#[rustc_force_inline]`-annotated callees.
158+
&inline::ForceInline,
157159
&abort_unwinding_calls::AbortUnwindingCalls,
158160
&add_call_guards::CriticalCallEdges,
159161
],

tests/ui/force-inlining/shims.rs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//@ build-pass
2+
#![allow(internal_features)]
3+
#![feature(rustc_attrs)]
4+
5+
#[rustc_force_inline]
6+
fn f() {}
7+
fn g<T: FnOnce()>(t: T) { t(); }
8+
9+
fn main() { g(f); }

0 commit comments

Comments
 (0)