10

LLVMの使い方を学びたいと思って、 LLVMで遊んでいます。

しかし、インターフェースの複雑さのレベルに頭がおかしくなりました。

たとえば、フィボナッチ関数を考えてみましょう

int fib(int x) {
    if(x<=2) 
        return 1;
    return fib(x-1) + fib(x-2);
   }

これを LLVM IR に出力するには、61 行のコードが必要です!!!

また、最小のコンパイラ (200 バイト) で知られる BrainFuck も含まれています。残念ながら、LLVM では600 行(18 kb) を超えています。

これはコンパイラ バックエンドの標準ですか? これまでのところ、アセンブリまたは C バックエンドを実行する方がはるかに簡単であるように思われます。

4

4 に答える 4

18

問題は C++ にあり、LLVM にはありません。

OCamlのようなメタプログラミング用に設計された言語を使用すると、コンパイラは非常に小さくなります。たとえば、この OCaml Journal の記事では、87 行の LLVM ベースの Brainfuck コンパイラについて説明しています。このメーリング リストの投稿では、フィボナッチ関数を (他のプログラムの中でも) コンパイルできるパーサーを含む完全なプログラミング言語の実装について説明しており、コンパイラ全体は OCaml の 100 行未満です。 LLVM を使用したコードであり、HLVM は LLVM を使用した 2,000 行未満の OCaml コードでマルチコア対応のガベージ コレクションを備えた高レベルの仮想マシンです。

于 2009-05-12T18:54:33.983 に答える
1

LLVM にはいくつかのボイラープレート コードが必要ですが、理解すれば非常に簡単です。シンプルな GCC フロント エンドを探してみると、LLVM がいかにクリーンであるかがわかります。C または ASM よりも LLVM を強くお勧めします。ASM は移植性がまったくありません。また、ソース コードの生成は、コンパイルが遅くなるため、通常は悪いことです。

于 2009-04-09T14:46:36.073 に答える
1

LLVM は、バックエンドに実装された特定のアーキテクチャに応じて IR を最適化しませんか? IR コードは 1:1 で最終的なバイナリに直接変換されません。私が理解している限り、それがどのように機能するかです。ただし、バックエンドをいじり始めたばかりです (カスタム プロセッサに移植しています)。

于 2009-04-09T07:58:09.020 に答える
1

中間表現は、非仮想アセンブラーと比較して、少し冗長になる可能性があります。私は .NET IL を見ていることを学びましたが、見るより先に進んだことはありませんでした。私はLLVMにあまり詳しくありませんが、同じ問題だと思います。

とはいえ、考えてみれば当然のことです。大きな違いの 1 つは、IR が多くのメタデータを処理する必要があることです。アセンブラーにはほとんどありません。プロセッサは暗黙のうちに多くのことを定義し、関数呼び出しなどの規則はプログラマー/コンパイラーに定義を任せます。これは便利ですが、移植性と相互運用性に大きな問題が生じます。

.NET や LLVM などの中間表現は、別々にコンパイルされたコンポーネントが連携できるようにすることに注意を払います。異なる言語で記述され、異なるコンパイラ フロント エンドでコンパイルされたコンポーネントであっても同様です。つまり、メタデータは、任意のプッシュ、ポップ、パラメータ処理などよりも高いレベルで何が起こっているかを説明する必要がありますが、ほとんど何でも可能です。見返りはかなり大きいですが、支払うべき代償があります。

他にも問題があります。中間表現は人間が書くことを意図したものではありませんが、読みやすいことを意図しています。また、完全に互換性のないゼロからの再設計なしで、多くのバージョンに耐えられるように十分に一般的であることを意図しています。

基本的に、このコンテキストでは、ほとんどの場合、暗黙的よりも明示的の方が優れているため、冗長性を避けるのは困難です。

于 2009-10-09T01:48:07.853 に答える