Skip to content

Commit 4507939

Browse files
committed
inline: force inlining shims
1 parent 02d423c commit 4507939

File tree

3 files changed

+27
-12
lines changed

3 files changed

+27
-12
lines changed

compiler/rustc_mir_transform/src/inline.rs

Lines changed: 15 additions & 11 deletions
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_parsing::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() {
@@ -723,7 +723,11 @@ fn check_mir_is_available<'tcx, I: Inliner<'tcx>>(
723723
return Ok(());
724724
}
725725

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

compiler/rustc_mir_transform/src/shim.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use rustc_span::{DUMMY_SP, Span};
2020
use tracing::{debug, instrument};
2121

2222
use crate::{
23-
abort_unwinding_calls, add_call_guards, add_moves_for_packed_drops, deref_separator,
23+
abort_unwinding_calls, add_call_guards, add_moves_for_packed_drops, deref_separator, inline,
2424
instsimplify, mentioned_items, pass_manager as pm, remove_noop_landing_pads, simplify,
2525
};
2626

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

tests/ui/force-inlining/shims.rs

Lines changed: 9 additions & 0 deletions
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)