MIPSコード、GCC、またはLLVMに「最適な」フリー/ OSSコンパイラーとは何かを知りたいのですが、それよりも優れたものはありますか?
コードサイズよりも、高速でメモリに制約のある生成されたアセンブリコードについてもっと知りたいです。
言い換えれば、llvm-optはgcc -O3よりもうまく機能しますか?
MIPSコード、GCC、またはLLVMに「最適な」フリー/ OSSコンパイラーとは何かを知りたいのですが、それよりも優れたものはありますか?
コードサイズよりも、高速でメモリに制約のある生成されたアセンブリコードについてもっと知りたいです。
言い換えれば、llvm-optはgcc -O3よりもうまく機能しますか?
http://www.phoronix.com/scan.php?page=news_item&px=OTI1MA "LLVM 2.9 リリース候補 2 はこちら
Michael Larabel によって 2011 年 3 月 25 日に投稿されました。ハードウェアが不足しているため、LLVM ARM ベンチマークはありません..."
おそらく、高速なデュアル/クワッド アーム コーテックスと LLVM ARM などを備えた誰かが、月曜日までにhttp://openbenchmarking.org/ベンチを実行し、マイケルがこれらを他の結果に追加することができます。
mips については知りません。ARM を試してみたところ、llvm コードは現在の gcc よりも約 10 ~ 20% 遅くなりました。問題のテストは zlib ベースでした。それ自体で解凍し、圧縮してから解凍します。clang と llvm-gcc の両方を使用しました。-m32 は実際には 64 ビット ホストで動作するため、clang を好みました。問題のテストでは、-O2 (または -O3) を使用しないと最速のコードが生成されることがわかりました。バイトコード モジュールを 1 つの大きなモジュールにリンクし、標準の最適化で 1 つのオプションを実行して、最速のコードを取得しました。llc はデフォルトで -O2 であり、パフォーマンスに役立ちました。
編集:
mips の gcc と llvm/clang の間の興味深いテスト。
void dummy ( unsigned int );
void dowait ( void )
{
unsigned int ra;
for(ra=0x80000;ra;ra--) dummy(ra);
}
gcc が生成:
9d006034 <dowait>:
9d006034: 27bdffe8 addiu sp,sp,-24
9d006038: afb00010 sw s0,16(sp)
9d00603c: afbf0014 sw ra,20(sp)
9d006040: 3c100008 lui s0,0x8
9d006044: 02002021 move a0,s0
9d006048: 0f40180a jal 9d006028 <dummy>
9d00604c: 2610ffff addiu s0,s0,-1
9d006050: 1600fffd bnez s0,9d006048 <dowait+0x14>
9d006054: 02002021 move a0,s0
9d006058: 8fbf0014 lw ra,20(sp)
9d00605c: 8fb00010 lw s0,16(sp)
9d006060: 03e00008 jr ra
9d006064: 27bd0018 addiu sp,sp,24
そして組み立て後のllvm
9d006034 <dowait>:
9d006034: 27bdffe8 addiu sp,sp,-24
9d006038: afbf0014 sw ra,20(sp)
9d00603c: afb00010 sw s0,16(sp)
9d006040: 3c020008 lui v0,0x8
9d006044: 34440000 ori a0,v0,0x0
9d006048: 2490ffff addiu s0,a0,-1
9d00604c: 0f40180a jal 9d006028 <dummy>
9d006050: 00000000 nop
9d006054: 00102021 addu a0,zero,s0
9d006058: 1600fffb bnez s0,9d006048 <dowait+0x14>
9d00605c: 00000000 nop
9d006060: 8fb00010 lw s0,16(sp)
9d006064: 8fbf0014 lw ra,20(sp)
9d006068: 27bd0018 addiu sp,sp,24
9d00606c: 03e00008 jr ra
9d006070: 00000000 nop
gnu-asがこのようなことをしているのを見たので、組み立てた後に言います
.globl PUT32
PUT32:
sw $a1,0($a0)
jr $ra
nop
アセンブリを再配置します。
9d00601c <PUT32>:
9d00601c: 03e00008 jr ra
9d006020: ac850000 sw a1,0(a0)
9d006024: 00000000 nop
llvm と gcc で生成されたコードの違いは、分岐遅延スロットに配置されている命令です。clang と llc を使用してアセンブリ出力を生成し、binutils と gnu as を使用してバイナリを作成しました。だから、私の手で組み立てられたコードの好奇心です:
ori $sp,$sp,0x2000
jal notmain
nop
それは私のために最適化されました:
9d006004: 0f401820 jal 9d006080 <notmain>
9d006008: 37bd2000 ori sp,sp,0x2000
9d00600c: 00000000 nop
しかし、LLCが生成したコード
addiu $16, $4, -1
jal dummy
nop
ではなかった
9d006048: 2490ffff addiu s0,a0,-1
9d00604c: 0f40180a jal 9d006028 <dummy>
9d006050: 00000000 nop