@@ -327,6 +327,27 @@ fn create_alloc_family_attr(llcx: &llvm::Context) -> &llvm::Attribute {
327
327
llvm:: CreateAttrStringValue ( llcx, "alloc-family" , "__rust_alloc" )
328
328
}
329
329
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
+
330
351
/// Helper for `FnAbi::apply_attrs_llfn`:
331
352
/// Composite function which sets LLVM attributes for function depending on its AST (`#[attribute]`)
332
353
/// attributes.
@@ -356,7 +377,17 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
356
377
} else {
357
378
codegen_fn_attrs. inline
358
379
} ;
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
+ }
360
391
361
392
// The `uwtable` attribute according to LLVM is:
362
393
//
0 commit comments