web-dev-qa-db-ja.com

clangをllvm IRにコンパイルする方法

ClangでC/C++コードをバイナリ実行可能ファイルではなくLLVMバイトコードにコンパイルします。どうすればそれを達成できますか?また、LLVMバイトコードを取得した場合、それをどのようにしてバイナリ実行可能ファイルにさらにコンパイルできますか。

基本的に、バイナリ実行可能ファイルにコンパイルする前に、自分のコードをLLVMバイトコードに追加します。

129
pythonic

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つです。- ドキュメントがあります

177
Eli Bendersky

つかいます

clang -emit-llvm -o foo.bc -c foo.c
clang -o foo foo.bc
20
Christoph

複数のソースファイルがある場合は、実際にはリンク時間最適化を使用して、プログラム全体に対して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

上記のリンク手順へ。

18
Jeremy Salwen

複数のファイルがあり、各ファイルを入力する必要がない場合は、次の簡単な手順に従うことをお勧めします(clang-3.8を使用していますが、他のバージョンも使用できます)。

  1. すべての.llファイルを生成します

    clang-3.8 -S -emit-llvm *.c
    
  2. それらを単一のものにリンクする

    llvm-link-3.8 -S -v -o single.ll *.ll
    
  3. (オプション)コードを最適化します(エイリアス分析の可能性があります)

    opt-3.8 -S -O3 -aa -basicaaa -tbaa -licm single.ll -o optimised.ll
    
  4. アセンブリの生成(optimised.sファイルを生成)

    llc-3.8 optimised.ll
    
  5. 実行可能ファイルの作成(a.outという名前)

    clang-3.8 optimised.s
    
11
Kiko Fernandez

clang documentation を読みましたか?おそらく-emit-llvmを探しています。

11
rotoglup