2008-09-05

透過的なLLVM (2)

四行詩を諳んじるにはまだ遠い。

./configure
make
make check
make install

前回、ラッパーとなるシェルスクリプトを介してllvm-ldを呼び出すことで、llvm-gccをほとんどgccとして扱えることを示した。こうして、いつでもllvm-gccに-emit-llvmを与えられるようになった。もちろん、gccをllvm-gccへのシンボリックリンクに設定するべきではない。コンパイラドライバとしてのllvm-gccは、アセンブラとしてのgccを必要とする。llvm-gccを呼び出す前に、自分自身が存在するディレクトリを$PATHから削除すれば問題はほとんど解決する。

そもそもの目的に照らせば、いつでもllvm-gccに-emit-llvmを与えることは必然だ。llvm-ldを呼び出す際にどのようなオプションを与えるかは考慮に値する。考慮するべきオプションは、-disable-optと-nativeだ。なにも指定しなければ、llvm-ldは可能な限りの最適化を試みる。ひとつの問題がある。

char function();
char (*f)() = function;

int main() {
    return f != function;
}

関数の存在を調べるためにconfigureが(つまりAutoconfのAC_CHECK_FUNCSマクロが)生成したコードだ。リンクに成功すればfunctionが外部に存在していると認識される。なにも指定しなければ、llvm-ldは可能な限りの最適化を試みる。ffunctionが等しいことを見抜き、f != functionは偽であることを見抜く。

int main() {
    return 0;
}

リンクは常に成功する。畢竟、functionは存在する。ひとつの教訓は、configureの実行中、llvm-ldに-disable-optを与えることだ。

-nativeまたは-native-cbeを指定しなければ、llvm-ldはbitcodeとそれを実行するためのシェルスクリプトを生成する。ひとつの問題は動的リンクライブラリのリンクが動的に行われることで、最適化と同様の問題が発生する。さらに、make installがぼくたちの望んだように働かない(シェルスクリプトだけをインストールしてくれちゃう)。

目的に立ち返ろう。ぼくたちのC++のコードがリンクする全ての静的ライブラリをbitcodeで表現すること、最後の最後に最適化をかけることが目的だ。最後の最後が永遠に続くとしても、それはぼくたちのC++のコードの話だ。欲しいのはbitcodeで表現された図書館であって、bitcodeで表現された実行可能バイナリではない。

ふたつめの教訓は、四行詩を諳んじている間、常にllvm-ldに-nativeを与えることだ(ただし副作用はある。-g付きでコンパイルした場合、dsymutilがオブジェクトファイルからDWARFデバッグ情報を抽出しようとするかもしれない)。

0 件のコメント: