11

私は言語Timber用のLLVMコードジェネレーターを書いています。現在のコンパイラーはCコードを出力します。私の問題は、生成されたLLVMファイルからC関数を呼び出す必要があることです。たとえば、コンパイラにはリアルタイムのガベージコレクタがあり、新しいオブジェクトがヒープに割り当てられたときに通知する関数を呼び出す必要があります。これらの関数を生成されたLLVMファイルとリンクする方法がわかりません。

コード生成は、.llファイルを生成し、これらを手動でコンパイルすることによって行われます。

LLVMから外部関数を呼び出そうとしていますが、うまくいきません。例では、「puts」や「printf」などのC標準関数のみが呼び出されていることがわかりましたが、自家製の関数を呼び出したいと思います。私は立ち往生しています。

4

3 に答える 3

12

あなたは LLVM 変換を書いていて、変換されたコードに外部関数の呼び出しを追加したいと思っていると思います。そうでない場合は、質問を編集して詳細情報を含めてください。

LLVM コードから外部関数を呼び出す前に、その宣言を挿入する必要があります。例えば:

virtual bool runOnModule(Module &m) {
    Constant *log_func = m.getOrInsertFunction("log_func",
                                               Type::VoidTy,
                                               PointerType::getUnqual(Type::Int8Ty),
                                               Type::Int32Ty,
                                               Type::Int32Ty,
                                               NULL);
    ...
}

上記のコードは、 log_funcvoid を返し、バイト ポインター (文字列) と 2 つの 32 ビット整数の 3 つの引数を取る関数を宣言しています。getOrInsertFunctionの方法ですModule

実際に関数を呼び出すには、CallInst. これにはいくつかの静的Createメソッドがあります。

于 2009-10-23T04:49:25.680 に答える
5

llvm-asを使用してLLVMアセンブリファイルを通常どおりにコンパイルします。

llvm-as *.ll

ビットコードファイルを.sアセンブリ言語ファイルにコンパイルします。

llc *.bc

ランタイムライブラリを使用してそれらをGCCします。

gcc *.s runtime.c -o executable

必要に応じて、実際のmakefile、共有ライブラリなどに置き換えてください。あなたはその考えを理解します。

于 2010-01-01T18:54:55.613 に答える
3

私はあなたの質問を「LLVM にコンパイルされる自分の言語用に C または C++ でランタイム ライブラリを実装するにはどうすればよいですか?」と解釈しています。

1 つのアプローチは、Jonathan Tang によって詳述されているように、コンパイラの出力を LLVM IR からビットコード、アセンブリに変換しgcc、ランタイム ソース (またはオブジェクト ファイル) に対してアセンブリをバニラ リンクさせることです。

別のより柔軟な方法として、 を使用llvm-gccしてランタイム自体を LLVM ビットコードにコンパイルし、 を使用llvm-ldしてコンパイラのビットコードをランタイムのビットコードにリンクする方法があります。このビットコードは、 で再最適化されopt、 で IR に変換され、llvm-disで直接解釈されlli(これは、LLVM が に対してビルドされた場合にのみ機能しますlibffi)、または でアセンブリにコンパイルされますllc(そして、vanilla でネイティブ バイナリにコンパイルされgccます)。

于 2010-01-27T03:20:00.593 に答える