Next: Other Asm Functionality, Previous: Input Variables in Inline Assembler, Up: Inline Assembler
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",
Inputs => Unsigned_32'Asm_Input ("a", Value),
Outputs => Unsigned_32'Asm_Output ("=a", Result));
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 enabled (-gnatpn instead of -gnatp).
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.