@@ -327,6 +327,27 @@ fn create_alloc_family_attr(llcx: &llvm::Context) -> &llvm::Attribute {
327327 llvm:: CreateAttrStringValue ( llcx, "alloc-family" , "__rust_alloc" )
328328}
329329
330+ fn should_always_inline ( body : & rustc_middle:: mir:: Body < ' _ > ) -> bool {
331+ use rustc_middle:: mir:: * ;
332+ match body. basic_blocks . len ( ) {
333+ 0 => return true ,
334+ 1 => { }
335+ 2 .. => return false ,
336+ }
337+ let block = & body. basic_blocks [ START_BLOCK ] ;
338+ match block. statements . len ( ) {
339+ 0 => {
340+ matches ! ( block. terminator( ) . kind, TerminatorKind :: Return )
341+ }
342+ 1 => {
343+ let statement = & block. statements [ 0 ] ;
344+ matches ! ( statement. kind, StatementKind :: Assign ( _) )
345+ && matches ! ( block. terminator( ) . kind, TerminatorKind :: Return )
346+ }
347+ 2 .. => return false ,
348+ }
349+ }
350+
330351/// Helper for `FnAbi::apply_attrs_llfn`:
331352/// Composite function which sets LLVM attributes for function depending on its AST (`#[attribute]`)
332353/// attributes.
@@ -356,7 +377,17 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
356377 } else {
357378 codegen_fn_attrs. inline
358379 } ;
359- to_add. extend ( inline_attr ( cx, inline) ) ;
380+
381+ if cx. tcx . is_mir_available ( instance. def_id ( ) ) {
382+ let body = cx. tcx . instance_mir ( instance. def ) ;
383+ if should_always_inline ( body) {
384+ to_add. push ( AttributeKind :: AlwaysInline . create_attr ( cx. llcx ) ) ;
385+ } else {
386+ to_add. extend ( inline_attr ( cx, inline) ) ;
387+ }
388+ } else {
389+ to_add. extend ( inline_attr ( cx, inline) ) ;
390+ }
360391
361392 // The `uwtable` attribute according to LLVM is:
362393 //
0 commit comments