3.2 Inlining functions

ARM Compiler automatically inlines functions if it decides that inlining the function gives better performance. This inlining does not significantly increase the code size. However, you can use compiler hints and options to influence or control whether a function is inlined or not.

Table 3-6 Function inlining

Inlining options, keywords, or attributes Description
__inline__ Specify this keyword on a function definition or declaration as a hint to the compiler to favor inlining of the function. However, for each function call, the compiler still decides whether to inline the function. This is equivalent to __inline.
__attribute__((always_inline)) Specify this function attribute on a function definition or declaration to tell the compiler to always inline this function, with certain exceptions such as for recursive functions. This overrides the -fno-inline-functions option.
__attribute__((noinline)) Specify this function attribute on a function definition or declaration to tell the compiler to not inline the function. This is equivalent to __declspec(noinline).
-fno-inline-functions This is a compiler command-line option. Specify this option to the compiler to disable inlining. This option overrides the __inline__ hint.

Note:

  • ARM Compiler only inlines functions within the same compilation unit, unless you use Link Time Optimization. For more information, see Optimizing across modules with link time optimization in the Software Development Guide.
  • C++ and C99 provide the inline language keyword. The effect of this inline language keyword is identical to the effect of using the __inline__ compiler keyword. However, the effect in C99 mode is different from the effect in C++ or other C that does not adhere to the C99 standard. For more information, see Inline functions in the armclang Reference Guide.
  • Function inlining normally happens at higher optimization levels, such as -O2, except when you specify __attribute__((always_inline)).

Examples of function inlining

This example shows the effect of __attribute__((always_inline)) and -fno-inline-functions in C99 mode, which is the default behavior for C files. Copy the following code to file.c.

int bar(int a)
{
    a=a*(a+1);
    return a;
}

__attribute__((always_inline)) static int row(int a)
{
    a=a*(a+1);
    return a;
}

int foo (int i)
{
    i=bar(i);
    i=i-2;
    i=bar(i);
    i++;
    i=row(i);
    i++;
    return i;
}

In the example code, functions bar and row are identical but function row is always inlined. Use the following compiler commands to compile for -O2 with -fno-inline-functions and without -fno-inline-functions:

armclang --target=arm-arm-none-eabi -march=armv8-a -c -S file.c -O2 -o file_no_inline.s -fno-inline-functions
armclang --target=arm-arm-none-eabi -march=armv8-a -c -S file.c -O2 -o file_with_inline.s

The generated code shows inlining:

Table 3-7 Effect of -fno-inline-functions

Compiling with -fno-inline-functions Compiling without -fno-inline-functions
foo:                                    @ @foo
        .fnstart
@ BB#0:
        .save   {r11, lr}
        push    {r11, lr}        
        bl	 bar
        sub     r0, r0, #2
        bl	 bar
        add     r1, r0, #1
        add     r0, r0, #2
        mul     r0, r0, r1
        add     r0, r0, #1
        pop     {r11, pc}
.Lfunc_end0:
	   .size   foo, .Lfunc_end0-foo
        .cantunwind
        .fnend
foo:                                    @ @foo
        .fnstart
@ BB#0:
        add     r1, r0, #1
        mul     r0, r1, r0
        sub     r1, r0, #2
        sub     r0, r0, #1
        mul     r0, r0, r1
        add     r1, r0, #1
        add     r0, r0, #2
        mul     r0, r0, r1
        add     r0, r0, #1
        bx	lr
.Lfunc_end0:
	   .size   foo, .Lfunc_end0-foo
        .cantunwind
        .fnend

When compiling with -fno-inline-functions, the compiler does not inline the function bar. When compiling without -fno-inline-functions, the compiler inlines the function bar. However, the compiler always inlines the function row even though it is identical to function bar.

Non-ConfidentialPDF file icon PDF versionARM 100748_0607_00_en
Copyright © 2016, 2017 ARM Limited or its affiliates. All rights reserved.