diff options
| author | David Wood <david.wood2@arm.com> | 2024-09-23 18:46:23 +0100 |
|---|---|---|
| committer | David Wood <david.wood2@arm.com> | 2025-01-10 18:37:54 +0000 |
| commit | f86169a58f212b174a01aa721545df009e96bfda (patch) | |
| tree | 8dcb0c44ab5c144297435b7f5cf279f1af979d7a /compiler/rustc_mir_transform/src/validate.rs | |
| parent | 336209eef13882bd1e211b24779584cb7ef911eb (diff) | |
| download | rust-f86169a58f212b174a01aa721545df009e96bfda.tar.gz rust-f86169a58f212b174a01aa721545df009e96bfda.zip | |
mir_transform: implement forced inlining
Adds `#[rustc_force_inline]` which is similar to always inlining but reports an error if the inlining was not possible, and which always attempts to inline annotated items, regardless of optimisation levels. It can only be applied to free functions to guarantee that the MIR inliner will be able to resolve calls.
Diffstat (limited to 'compiler/rustc_mir_transform/src/validate.rs')
| -rw-r--r-- | compiler/rustc_mir_transform/src/validate.rs | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index a670da94fcc..9444c5b61dd 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -1,6 +1,7 @@ //! Validates the MIR to ensure that invariants are upheld. use rustc_abi::{ExternAbi, FIRST_VARIANT, Size}; +use rustc_attr_parsing::InlineAttr; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir::LangItem; use rustc_index::IndexVec; @@ -79,7 +80,7 @@ impl<'tcx> crate::MirPass<'tcx> for Validator { cfg_checker.fail(location, msg); } - if let MirPhase::Runtime(_) = body.phase { + if let MirPhase::Runtime(phase) = body.phase { if let ty::InstanceKind::Item(_) = body.source.instance { if body.has_free_regions() { cfg_checker.fail( @@ -88,6 +89,27 @@ impl<'tcx> crate::MirPass<'tcx> for Validator { ); } } + + if phase >= RuntimePhase::Optimized + && body + .basic_blocks + .iter() + .filter_map(|bb| match &bb.terminator().kind { + TerminatorKind::Call { func, .. } + | TerminatorKind::TailCall { func, .. } => Some(func), + _ => None, + }) + .filter_map(|func| match func.ty(&body.local_decls, tcx).kind() { + ty::FnDef(did, ..) => Some(did), + _ => None, + }) + .any(|did| matches!(tcx.codegen_fn_attrs(did).inline, InlineAttr::Force { .. })) + { + cfg_checker.fail( + Location::START, + "`#[rustc_force_inline]`-annotated function not inlined", + ); + } } } } |
