Inlining Inline Assembler Code (GNAT User’s Guide for Native Platforms)

### 10.5 Inlining Inline Assembler Code ¶

For a short subprogram such as the `Incr` function in the previous section, the overhead of the call and return (creating / deleting the stack frame) can be significant, compared to the amount of code in the subprogram body. A solution is to apply Ada’s `Inline` pragma to the subprogram, which directs the compiler to expand invocations of the subprogram at the point(s) of call, instead of setting up a stack frame for out-of-line calls. Here’s the resulting program:

>     with Interfaces; use Interfaces;
>     with Ada.Text_IO; use Ada.Text_IO;
>     with System.Machine_Code; use System.Machine_Code;
>     procedure Increment_2 is

>        function Incr (Value : Unsigned_32) return Unsigned_32 is
>           Result : Unsigned_32;
>        begin
>           Asm ("incl %0",
>                Outputs => Unsigned_32'Asm_Output ("=a", Result),
>                Inputs  => Unsigned_32'Asm_Input ("a", Value));
>           return Result;
>        end Incr;
>        pragma Inline (Increment);

>        Value : Unsigned_32;

>     begin
>        Value := 5;
>        Put_Line ("Value before is" & Value'Img);
>        Value := Increment (Value);
>        Put_Line ("Value after is" & Value'Img);
>     end Increment_2;

Compile the program with both optimization (`-O2`) and inlining (`-gnatn`) enabled.

The `Incr` function is still compiled as usual, but at the point in `Increment` where our function used to be called:

>     pushl %edi
>     call _increment__incr.1

the code for the function body directly appears:

>     movl %esi,%eax
>     #APP
>        incl %eax
>     #NO_APP
>        movl %eax,%edx

thus saving the overhead of stack frame setup and an out-of-line call.