バイナリ実行可能ファイルではなく、C/C++ コードを LLVM ビットコードにコンパイルするには、clang を使用します。どうすればそれを達成できますか?
また、LLVM ビットコードを持っている場合、それをバイナリ実行可能ファイルにさらにコンパイルするにはどうすればよいですか?
バイナリ実行可能ファイルにコンパイルする前に、独自のコードを LLVM ビットコードに追加したいと考えています。
いくつかのC/C ++ファイルがある場合foo.c
:
> clang -S -emit-llvm foo.c
LLVMIRfoo.ll
ファイルを生成します。
この-emit-llvm
オプションは、ドライバーではなく、コンパイラーのフロントエンドに直接渡すこともできます-cc1
。
> clang -cc1 foo.c -emit-llvm
IRfoo.ll
で生成します。-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
複数のソース ファイルがある場合、実際にはリンク時の最適化を使用して、プログラム全体に対して 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
それらを1つにリンクします
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