web-dev-qa-db-ja.com

なぜLLVMはツリーのようなIRではなくアセンブリのようなIRを持っているのですか?または:プロジェクトがclangのASTではなくLLVM IRをターゲットにするのはなぜですか?

なぜLLVMの中間表現(LLVM IR)は、ツリーではなくアセンブリに似ているのですか?

あるいは、言語実装がclangのASTではなくLLVM IRをターゲットにしているのはなぜですか?

そのように思われる場合、私は一度に2つの異なる質問をするつもりはありません。私にとっては、クライアントプログラマーとライブラリプログラマーの両方が、LLVMのAPIは多かれ少なかれ、明らかに優れたソフトウェア設計であり、私の質問は「なぜなのか?」.

私が尋ねる理由は、IRがASTに似ていれば、LLVMがフロントエンドにより多くの機能を提供できるように思われるからです。それは、clangのASTベースのツールを任意のフロントエンドに使用できるためです。または、LLVM IRを対象とする言語は、clangのASTを対象とすると、より多くの機能を利用できます。

Clangには、ASTを作成して操作するためのクラスと関数があり、LLVMプロジェクトに強く結びついているのはonlyフロントエンドプロジェクトなので、clangのAST機能はLLVMの外部にあるのはなぜですか?

私の頭の上では、Rust(rustc)、D(ldc)、およびHaskell(GHC)はすべてLLVMをバックエンドとして使用できますが、Clang = AST(私が知る限り、私は間違っている可能性があります。)これらのコンパイラのすべての内部の詳細はわかりませんが、少なくともRustおよびDは確かにそれらはclangのASTにコンパイルできるように思えますが、Haskellも可能かもしれませんが、私はそれについてはるかに確信が持てません。

これは歴史的な理由によるものですか(LLVMはもともと「低レベルの仮想マシン」であり、後でclangが登場するため)?これは、他のフロントエンドがLLVMに供給するものを可能な限り制御したいためですか? clangのASTが「Cに似ていない」言語には不適切であるという根本的な理由はありますか?

この質問をマインドリーディングの練習にするつもりはありません。コンパイラ設計に興味はあるが、まだ流暢ではない私たちにとって、それが役立つことを望んでいます。 LLVMとclangのプロジェクトは公開で開発されているため、これらのプロジェクトの開発に精通している誰かが回答できるか、回答が一部のコンパイルオタクにとって十分に明白であり、回答に十分自信があると思います。


明らかであるが不十分な回答を先取りするには:

はい、アセンブリのようなIRを使用すると、IRを作成する人をより詳細に制御できます(おそらく、X langのコードベースとAST形式はclangよりも優れています)。それが唯一の答えである場合、質問は「なぜLLVM onlyは、高レベルのツリー状IRと低レベルのアセンブリ状IRではなく、アセンブリ状のIRを持っているのですか?」.

はい、プログラミング言語をASTに(少なくとも他のコンパイル手順と比較して)解析するのはそれほど難しくありません。それでも、なぜ個別のASTを使用するのですか?他に何もない場合、同じASTを使用すると、ASTを操作するツールを使用できます(ASTプリンタのような単純なものでも)。

はい、私は強くよりモジュール化することは良いことだと同意しますが、それが唯一の理由であるなら、なぜ他の言語実装はclangのASTではなくLLVM IRをターゲットにする傾向があるのですか?

これらの横取りは誤っているか、詳細を見落としている可能性があるため、詳細があるか、私の仮定が間違っている場合は、これらの回答を自由に提供してください。


より明確に答えられる質問に答えたい人のために:アセンブリのようなIRとツリーのようなIRの長所と短所は何ですか?

14
Praxeolitic

ここには相互に関連する質問がいくつかあります。できる限りそれらを分離するようにします。

他の言語がclang ASTではなくLLVM IRに基づいているのはなぜですか?

これは単に、clangがC/C++フロントエンドであり、それが生成するASTがC/C++に緊密に結合されているためです。別の言語でClangを使用できますが、一部のサブセットとほぼ同じセマンティクスが必要です。 C/C++は非常に制限があります。ご指摘のとおり、ASTへの解析はかなり簡単なので、セマンティックの選択を制限しても、わずかな節約に値する可能性はほとんどありません。

ただし、C/C++用のツールを作成している場合は、 ASTを再利用することは、AST C/C++での作業。

なぜLLVM IRは現在の形式なのですか?

LLVM IRは、コンパイラの最適化を記述する適切な形式として選択されました。このように、それは [〜#〜] ssa [〜#〜] 形式であることが主な特徴です。これは非常に低レベルのIRなので、幅広い言語に適用できます。これは言語によって大きく異なるため、メモリを入力しません。

さて、コンパイラの最適化を書くことはかなり専門的な仕事であり、言語機能の設計に直角であることがよくあります。ただし、コンパイルされた言語を高速に実行することは、かなり一般的な要件です。また、LLVM IRからASMへの変換はかなり機械的であり、一般に言語設計者にとっても興味深いものではありません。

したがって、言語をLLVM IRに下げると、言語設計者は多くの「無料のもの」を使用できるようになり、実際には言語自体に集中することを余儀なくされます。

別のIRが役に立ちますか(大丈夫、質問されていませんが、暗示的なものです)?

絶対に! ASTは、プログラム構造の特定の変換に非常に適していますが、プログラムフローを変換する場合は非常に使いにくいです。 SSAフォームの方が一般に優れています。ただし、LLVM IRは非常に低レベルであるため、高レベルの構造の多くが失われています(故意に、より一般的に適用されます)。 ASTと低レベルIRの間にIRを置くことは、ここでは有益です。両方のRustおよびSwiftこのアプローチをとります2つの間に高レベルのIRがあります。

13
Alex