ClangでC/C++
コードをバイナリ実行可能ファイルではなくLLVM
バイトコードにコンパイルします。どうすればそれを達成できますか?また、LLVM
バイトコードを取得した場合、それをどのようにしてバイナリ実行可能ファイルにさらにコンパイルできますか。
基本的に、バイナリ実行可能ファイルにコンパイルする前に、自分のコードをLLVM
バイトコードに追加します。
C/C++ファイルfoo.c
がある場合:
> clang -S -emit-llvm foo.c
LLVM IRファイルであるfoo.ll
を生成します。
-emit-llvm
オプションは、-cc1
を使用してドライバーではなく、コンパイラーのフロントエンドに直接渡すこともできます。
> clang -cc1 foo.c -emit-llvm
IRでfoo.ll
を生成します。 -cc1
は、-ast-print
などのクールなオプションを追加します。詳細については、-cc1 --help
をご覧ください。
LLVM IRをさらにAssemblyにコンパイルするには、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
これにより、bothコンパイル済みプログラムとそれに対応するビットコード(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
clang
documentation を読みましたか?おそらく-emit-llvm
を探しています。