Next: , Previous: Input Variables in Inline Assembler, Up: Inline Assembler


12.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 is 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.