2009-09-13 22 views
10

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

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

私はLLVMから外部関数を呼び出そうとしていますが、私は運がありません。私が見た例では、 "puts"や "printf"のようなC標準関数だけが呼び出されていますが、>自家製関数を呼びたいと思います。私は立ち往生している。

+0

LLVM IRにコードを直接書き込もうとしていて、電話をかけることができないか、LLVMを使用してコードをコンパイルしているのに問題がありますか? –

答えて

5

LLVM-などで、通常はあなたのLLVMアセンブリファイルをコンパイルします。アセンブリ言語ファイルを.Sするビットコードファイルをコンパイルし

llvm-as *.ll 

:ランタイムライブラリと

llc *.bc 

GCCその中:

gcc *.s runtime.c -o executable 

必要に応じて、実際のメイクファイル、共有ライブラリなどで置き換えます。あなたはその考えを得る。

12

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

LLVMコードから外部関数を呼び出すには、その前に宣言を挿入する必要があります。たとえば、次のバイトのポインタ(文字列)、および2つの32ビット整数:

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

上記のコードは、ボイドを返し、3つの引数をとる関数log_funcを宣言する。 getOrInsertFunctionModuleの方法です。

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

+0

これはまさに私がllvmとやり取りしようとしていたものです。 – Dan

3

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

コンパイラの出力をLLVM IRからビットコードに変換してアセンブリーに変換し、バニラgccにランタイムソース(またはオブジェクトファイル)とアセンブリをリンクさせる方法があります。

llvm-gccを使用してランタイム自体をLLVMビットコードにコンパイルし、次にllvm-ldを使用して、コンパイラのビットコードとランタイムのビットコードをリンクする方法があります。このビットコードはoptで再最適化され、llvm-disでIRに変換され、lliで直接解釈されます(これは、LLVMがlibffiに対して構築されている場合のみ動作します)。またはllcでアセンブリにコンパイルされますバニラバイナリーgcc)。