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.


rakkota's picture


I have two questions.

Is there a way to see a message during the compilation that a subroutine call was actually inlined? Something like: remark: LOOP WAS VECTORIZED.

If a subroutine has an explicit interface, should we put the pragma "!DEC$ ATTRIBUTES FORCEINLINE" there as well?

Thanks, Rak   

Ahmed A.'s picture

Many Thanks for your Interesting article
in the case that I have two definitions of the same subroutine, How can I ask the program to use the subroutine that is included in the project rather than the same subroutine in the library. This was very easy using power station but using intel fortran this becomes difficult One possible difference is that the Intel compiler does automatic inlining of procedures in the same source file - this would probably explain the difference.

As this problem come from the Intel fortran automatic inlining , there is any way to disable or enable this automatic inlining or any other options that we can control the inlining while we are creating the static library to avoid this automatic inlining and get the project use the user subroutine instead of the library subroutine.
Many Thanks
Ahmed Khalil

Add a Comment

Have a technical question? Visit our forums. Have site or software product issues? Contact support.