2

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 に再利用させる方法です。

インスタンス化が次の形式をとると予想していました。

  1. Baa の設定 / 一般的なXパラメータThis_ValueBob適用This_Address
  2. 呼び出しThing_Gen(次に、セットアップされたものを使用して期待される結果を生成します)

コードの再利用につながりThing_Genます。しかし、そうではないようです。私がアセンブラーとコンパイラーの問題の初心者である理由の説明も歓迎します!

注: Sparc と Intel でも同じ結果になります。(Intel gnatmake バージョン 4.4.3)

4

1 に答える 1

3

ジェネリックのコード生成はコンパイラ実装者の設計上の選択の問題であり、AdaCore は複製を選択したため、Gnat に共有ジェネリックを実行させることはできないと思います。

このスレッドによると、RR とおそらく Irvine は共有ジェネリックをサポートしています。

于 2012-08-15T11:06:43.550 に答える