我想知道是否有一种方法可以从 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
...< snip >
0000000000402a05 <main__caa.2187>:
402a05: 55 push %rbp
402a06: 48 89 e5 mov %rsp,%rbp
...< snip > 等等...
每个代码都非常相似,所以我怀疑正在发生的事情是 gnatmake 使用
Thing_Gen
作为模板并扩展每个实例化的代码,而不是通过某些参数重用代码。
所以问题是,如何让 gnatmake 重用泛型的代码,而不是为每个实例化复制/粘贴?
我希望实例化采用以下形式:
X
是有 This_Value
& 程序 Bob
位于 This_Address
)Thing_Gen
(然后使用设置的内容来生成
预期结果)导致
Thing_Gen
代码的重用。但事实似乎并非如此。也欢迎解释为什么我是汇编器和编译器问题上的菜鸟!
注意:Sparc 和 Intel 的结果相同! (英特尔 gnatmake 版本 4.4.3)
我认为你不能让 Gnat 来做共享泛型,因为泛型的代码生成是编译器实现者设计选择的问题,而 AdaCore 选择了复制。
根据 this thread,RR 或许 Irvine 支持共享泛型。