Adaジェネリックからより小さく/より効率的なアセンブラコードを取得する方法があるかどうか疑問に思っています.
たとえば、一般的な手順を示すために少しダミーの Ada プログラム (main.adb) を作成し、それを 6 回インスタンス化しました。
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;
コンパイルするためにgnatmake main.adb
、結果objdump -d -S main > main.dump
を見ると、一般的なインスタンス化ごとに 6 つのセクションがあることがわかります。
000000000040275f <main__baa.2182>:
40275f: 55 push %rbp
402760: 48 89 e5 mov %rsp,%rbp
... <中略>
0000000000402a05 <main__caa.2187>:
402a05: 55 push %rbp
402a06: 48 89 e5 mov %rsp,%rbp
... <中略> など...
それぞれ非常によく似たコードを持っているので、gnatmake がThing_Gen
いくつかのパラメーターでコードを再利用するのではなく、テンプレートとして使用し、インスタンス化ごとにコードを展開していると思われます。
問題は、インスタンス化ごとにコピー/貼り付けするのではなく、ジェネリックのコードを gnatmake に再利用させる方法です。
インスタンス化が次の形式をとると予想していました。
- Baa の設定 / 一般的な
X
パラメータThis_Value
のBob
適用This_Address
- 呼び出し
Thing_Gen
(次に、セットアップされたものを使用して期待される結果を生成します)
コードの再利用につながりThing_Gen
ます。しかし、そうではないようです。私がアセンブラーとコンパイラーの問題の初心者である理由の説明も歓迎します!
注: Sparc と Intel でも同じ結果になります。(Intel gnatmake バージョン 4.4.3)