-foptimize-sibling-callsは別名定義ができる言語には必須ですよねえ

本当は末尾再帰の最適化をするためのものであろうこの最適化オプション、-O3でも含まれていないのですが、Adaのような言語には必須です。昨日気付いたばっかですが。
たとえば、次のような状態を考えてみてください。

package A is
   procedure P;
end A;
with A;
package B is
   procedure R renames A.P;
end B;

B.Rへの呼び出しは、直接A.Pへの呼び出しとなります。
しかし、上記の書き方では、with B;したソースをコンパイルする時は、必然的にA.adsも読まれることになってしまい、まあCのヘッダじゃあるまいし名前空間の汚染なんて起きないんですが、コンパイル時間が若干かかるようになるのは事実です。
それで次のようにします。

package A is
   procedure P;
end A;
package B is
   procedure R;
end B;
with A;
package body B is
   procedure R renames A.P;
end B;

すると、B.Rの名前でコールする側は、B.Rの実体がわからないので、B.Rをシンボルとして使うしかありません。ということでB.Rというシンボルが必要になります。
B.Rの実体としては単にjmp A.Pでいいんですが、何しろバックエンドはgccですから、真面目に引数をコピーしてはcallしてespを戻してくれます。A.Pが大量の引数を取る関数だったら、そのオーバーヘッドたるや莫大です。
で、-foptimize-sibling-callsを付けておけば、jmp A.Pになります。まあそれだけの話です。
それでも何しろバックエンドはgccですから、-fomit-frame-pointerも一緒に付けない限り、push ebpして即座にpop ebpという無意味なスタックフレームの生成が残ります。