genericsassemblyadagnat

Ada Generics & Assembly Code generation


I am wondering if there is a way of getting smaller / more efficient assembler code from Ada generics.

For example, I have written a little dummy Ada program (main.adb) to show a generic procedure & instantiated it 6 times:

with Ada.Text_Io;
procedure Main is

   generic
      X : Natural;
      with procedure Bob (S : in String);
   procedure Thing_Gen (S : in String);

   procedure Thing_Gen (S : in String) is
   begin
      for I in 0 .. X loop
         Bob (Natural'Image (I) & " " & S);
      end loop;
   end Thing_Gen;

   procedure Alice (S : in String) is
   begin
      Ada.Text_Io.Put_Line ("Alice:" & S);
   end Alice;

   procedure Aaa is new Thing_Gen (X => 1, Bob => Alice);
   procedure Baa is new Thing_Gen (X => 2, Bob => Alice);
   procedure Caa is new Thing_Gen (X => 3, Bob => Alice);
   procedure Daa is new Thing_Gen (X => 4, Bob => Alice);
   procedure Eaa is new Thing_Gen (X => 5, Bob => Alice);
   procedure Faa is new Thing_Gen (X => 6, Bob => Alice);

begin

   Aaa("A");
   Baa("B");
   Caa("C");
   Daa("D");
   Eaa("E");
   Faa("F");

end Main;

To compile, I am using gnatmake main.adb when I look at the resulting objdump -d -S main > main.dump I see that there are 6 sections for each of the generic instantiations:

000000000040275f <main__baa.2182>:
  40275f:   55                      push   %rbp
  402760:   48 89 e5                mov    %rsp,%rbp

... < snip >

0000000000402a05 <main__caa.2187>:
  402a05:   55                      push   %rbp
  402a06:   48 89 e5                mov    %rsp,%rbp

... < snip > etc...

each with very similar code, so what I suspect is happening is that gnatmake is using Thing_Gen as a template and expanding the code for each instantiation, rather than reusing the code with some parametetrs.

So the question is, how to get gnatmake to reuse the code of the generic, rather than copy/pasting for each instantiation ?

I would have expected the instantiations to have taken a form of :

  1. Setup Baa / apply generic parameters (I know X is to have This_Value & procedure Bob is at This_Address)
  2. Call Thing_Gen (which then uses what was setup to produce the expected result)

Resulting in reuse of Thing_Gen code. But this appears not to be the case. Explanations of why I am a noob in Assembler & Compiler issues also welcome!

NOTE: same results in Sparc & Intel ! (Intel gnatmake version 4.4.3)


Solution

  • I don't think you can get Gnat to do shared generics, as code generation for generics is a matter of compiler implementor's design choice, and AdaCore chose to replicate.

    According to this thread, RR and perhaps Irvine support shared generics.