Procedure Inlining in the Intel Fortran Compiler

Inline expansion, or “inlining”, is a kind of optimization that replaces a function call site with the body of the called function. In the compiler, inline function expansion typically favors relatively small user functions over functions that are relatively large. Function inlining can improve execution time by removing the runtime overhead of function calls, however, function inlining can increase code size, code complexity, and compile times.

There are several ways to enable/disable inlining during compilation. Inlining is enabled with the default optimization setting for the Intel compiler.

Here is a simple example showing how it works:

subroutine test_inlining
integer k
k =10
print *, k
end subroutine test_inlining

program Console1
call test_inlining
print *, 'Hello World'

end program Console1

Compile this code using default optimization options (put S option to get the ASM code):

Linux & Mac OS:  ifort -S test.f90
Windows:            ifort /S test.f90

In this case the default level of optimization is enabled and inlining of the function TEST_INLINING is performed. Checking the assembly listing produced from the above example, you will see that there is no call of the test_inlining subroutine in the generated ASM code (test.s) - the body of this small subroutine was inlined. Here is the example of the assembly listing produced on Windows:

        mov       DWORD PTR [8+esp], 0                          ;8.6
        lea       edx, DWORD PTR [8+esp]                        ;8.6
        lea       eax, DWORD PTR [80+esp]                       ;8.6
        mov       DWORD PTR [80+esp], 10                        ;8.6
        push      32                                            ;8.6
        push      eax                                           ;8.6
        push      OFFSET FLAT: STRLITPACK_0.0.1                 ;8.6
        push      -2088435968                                   ;8.6
        push      -1                                            ;8.6
        push      edx                                           ;8.6
        call      _for_write_seq_lis                            ;8.6

Set the code optimization level to disable inlining:

Linux & Mac OS:  ifort –O0 -S test.f90
Windows:            ifort /Od /S test.f90

Examining the assembly language listing produced by the above example, you will see that there is the explicit call of test_inlining subroutine:

 call      _TEST_INLINING                                ;8.6

It is also possible to control the inlining of the specific subroutines using directives. Adding a simple directive before the subroutine will avoid the inlining:

!DEC$ ATTRIBUTES NOINLINE :: test_inlining
subroutine test_inlining
integer k
...

The explicit call of test_inlining subroutine could be found in the ASM code again. The NOINLINE option disables inlining of a function.

There is also the INLINE option which could be used to specify that a function or subroutine can be inlined. However, the inlining can be ignored in this case by the compiler if inline heuristics determine it may have a negative impact on performance or will cause too much of an increase in code size.

The FORCEINLINE option could be used to specify that a function or subroutine must be inlined unless it will cause errors.

There is also a way to control the inline expansion using -inline-level (Linux) or /Ob (Windows) option. It specifies the level of inline function expansion. Depending on the value specified, the option can disable or enable inlining.

-inline-level=0 option disables inlining of user-defined functions (note that statement functions are always inlined) on Linux, /Ob0 is the corresponding option on Windows.

For more complete information about compiler optimizations, see our Optimization Notice.