回答:
いくつかのC / C ++ファイルを考えますfoo.c
:
> clang -S -emit-llvm foo.c
生成しfoo.ll
LLVM IRファイルです。
-emit-llvm
オプションもによってドライバを直接コンパイラのフロントエンドに渡され、そしてませんすることができます-cc1
。
> clang -cc1 foo.c -emit-llvm
foo.ll
IRで制作。-cc1
のようないくつかのクールなオプションを追加します-ast-print
。チェックアウト-cc1 --help
詳細については。
LLVM IRをさらにアセンブリにコンパイルするには、次のllc
ツールを使用します:
> llc foo.ll
生成しfoo.s
(あなたがそれを実行するマシンのアーキテクチャをデフォルト)のアセンブリで。llc
はLLVMツールの1つです。ここにそのドキュメントがあります。
使用する
clang -emit-llvm -o foo.bc -c foo.c
clang -o foo foo.bc
.o
バイナリオブジェクトファイル、.s
アセンブリファイル、および.ll
LLVM IRファイルの他の(慣例により)を参照する必要があります。そうでなければ、混乱するのは簡単です。Clang / LLVMには、バイナリオブジェクト用の独自のリンカーはありません(1つは開発中です)。LLVMリンカーllvm-ld
は、複数のIRファイルを1つに結合するだけです
.bc
が使用されている場合、実際には正しいことを行います。心の中でも、キープllvm-ld
システムツールチェーンのためのフロントエンドとして機能することができ、すなわち私の前の回答使用してllvm-ld -native
期待通りに動作するはずです....
foo.bc
LLVMのビットコードファイルである
clang -emit-llvm -o test.bc -c test.c && file test.bc: test.bc: LLVM IR bitcode
。
複数のソースファイルがある場合、実際にはリンク時最適化を使用して、プログラム全体の1つのビットコードファイルを出力する必要があります。与えられた他の答えは、すべてのソースファイルのビットコードファイルで終わることになります。
代わりに、リンク時の最適化でコンパイルしたい
clang -flto -c program1.c -o program1.o
clang -flto -c program2.c -o program2.o
最後のリンク手順では、引数-Wl、-plugin-opt = also-emit-llvmを追加します
clang -flto -Wl,-plugin-opt=also-emit-llvm program1.o program2.o -o program
これにより、コンパイルされたプログラムとそれに対応するビットコード(program.bc)の両方が提供されます。次に、program.bcを好きなように変更し、変更したプログラムをいつでも再コンパイルできます。
clang program.bc -o program
ただし、このステップでは、必要なリンカーフラグ(外部ライブラリなど)を再度含める必要があることに注意してください。
これを機能させるには、ゴールドリンカーを使用する必要があることに注意してください。clangで特定のリンカーを使用するように強制するには、コンピューターのどこかにある「fakebin」という特別なディレクトリに「ld」という名前のリンカーへのシンボリックリンクを作成し、オプションを追加します。
-B/home/jeremy/fakebin
上記のリンク手順に。
複数のファイルがあり、各ファイルを入力する必要がない場合は、次の簡単な手順に従うことをお勧めします(私は使用してclang-3.8
いますが、他のバージョンも使用できます)。
すべての.ll
ファイルを生成する
clang-3.8 -S -emit-llvm *.c
それらを単一のものにリンクする
llvm-link-3.8 -S -v -o single.ll *.ll
(オプション)コードを最適化します(おそらくエイリアス分析)
opt-3.8 -S -O3 -aa -basicaaa -tbaa -licm single.ll -o optimised.ll
アセンブリを生成(optimised.s
ファイルを生成)
llc-3.8 optimised.ll
実行可能ファイルを作成(名前はa.out
)
clang-3.8 optimised.s
-S
(ステップ2で)オプションを使用して、LLVM IRで出力を生成することを指定します。基本的に、すべての* .llファイルを1つにまとめます。これを実行して、最適化によってコードが実際に変更されていることを確認します。つまりsingle.ll
、optimised.ll
今度は異なる(コードごとに)見えるはずです。また、レポートを表示して、違いがあるかどうかを確認することもできます。
-basicaaa
間違ったフラグ-basicaa
です。代わりに使用する必要があります。
clang
ドキュメンテーションを読みましたか?あなたはおそらく探してい-emit-llvm
ます。