質問

llvm のチュートリアルと例では、コンパイラは次のような呼び出しを行うことで LLVM IR を出力します。

return Builder.CreateAdd(L, R, "addtmp");

しかし、多くのインタプリタは次のように書かれています。

switch (opcode) {
     case ADD:
             result = L + R;
             break;
     ...

LLVM IR で各オペコードを再実装せずに、これらの各コード スニペットを抽出して LLVM で JIT を作成するにはどうすればよいでしょうか?

役に立ちましたか?

解決

まず、すべてのコード スニペットを取得し、それらを独自の関数にリファクタリングします。したがって、コードは次のようになります。

void addOpcode(uint32_t *result, uint32_t L, uint32_t R) {
    *result = L + R;
}

switch (opcode) {
    case ADD:
            addOpcode(&result, L, R);
            break;
     ....

さて、これを実行した後もインタープリタは実行されるはずです。次に、すべての新しい関数を取得して、独自のファイルに配置します。次に、llvm-gcc または Clang を使用してそのファイルをコンパイルし、ネイティブ コードを生成する代わりに、 「cpp」バックエンド (-march -cpp)。これにより、コンパイル単位のバイト コードをインスタンス化する C++ コードが生成されます。オプションを指定して特定の機能に限定することも可能です。おそらく「-cppgen module」を使用するとよいでしょう。

ここで、インタープリタ ループに戻り、元のコードを直接実行するのではなく、生成された C++ コードへの呼び出しを結合し、それをいくつかのオプティマイザとネイティブ コードジェネレータに渡します。JIT については感謝します ;-) この例は、次の vm_ops など、いくつかの LLVM プロジェクトで見ることができます。 llvm-lua.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top