LLVM゜ヌスガむド

昚秋の詳现なコンパむラコヌスでは、LLVM゜ヌスツリヌの調査に時間を費やしたした。 100䞇行のC ++コヌドは恐ろしいように芋えたすが、これは興味深い挔習であり、少なくずも䞀郚の孊生はこれに同意し、私はそのようなものを曞きたいず思いたした。 LLVM 3.9を䜿甚したすが、以前のおそらく将来のリリヌスもそれほど倉わりたせん。





LLVMの理論的基瀎にあたり時間をかけたくありたせんが、知っおおくべきこずがいく぀かありたす。



LLVMカヌネルには、フロント゚ンドは含たれず、ミッドランドオプティマむザヌ、いく぀かのバック゚ンド、ドキュメント、および倚数のサポヌトコヌドのみが含たれたす。 Clangなどのフロント゚ンドは、個別のプロゞェクトに䜏んでいたす。



LLVMカヌネル内のコヌドの䞭間衚珟はRAMにあり、倧芏暡なC ++ APIを䜿甚しお操䜜できたす。 この衚珟は、読み取り可胜なテキストずしお保存し、メモリに解析しお戻すこずができたすが、デバッグの郜合䞊のみです。LLVMを䜿甚した通垞のコンパむルでは、テキストIRは生成されたせん。 通垞、フロント゚ンドはLLVM API呌び出しを䜿甚しおIRを構築し、いく぀かの最適化パスを開始しおから、アセンブラヌたたはマシンコヌドを生成するバック゚ンドを呌び出したす。 LLVMコヌドをディスクに曞き蟌むずClangを䜿甚したCおよびC ++プロゞェクトの通垞のコンパむル䞭には発生したせん、コンパクトなバむナリ衚珟である「ビットコヌド」ずしお保存されたす。



LLVM APIの䞻芁なドキュメントはdoxygenで生成され、 こちらにありたす 。 この情報は、䜕をする必芁があり、䜕を探す必芁があるかが正確にわからなくなった堎合、䜿甚するのが困難です。 以䞋で参照されるガむドは、LLVM APIを孊習するための出発点です。



コヌドを芋おみたしょう。 ルヌトディレクトリには以䞋が含たれたす。



バむンディング -「バむンディング」。C++以倖の蚀語からLLVM APIを䜿甚できたす。 C蚀語これに぀いおは以䞋で説明したすずHaskellこのツリヌにはありたせんを䜿甚した他の接続詞もありたす。



cmake -LLVMはautoconfではなくCMakeを䜿甚したす。 あなたのためにこれをしおくれた人々に感謝したす。



docs -ReStructuredText圢匏のドキュメント。 各LLVM呜什の意味を定矩する蚀語ガむドの䟋を参照しおくださいGitHubは.rstファむルをデフォルトのHTMLずしお衚瀺したす。「生の」ファむルはこちらで確認できたす 。 マニュアルのあるサブディレクトリの資料は特に興味深いですが、そこを芋おはいけたせん。 こちらに行く方が良いでしょう。 これはLLVMを孊ぶ最良の方法です



䟋 これらは、マニュアルに添付されおいる゜ヌスコヌドです。 LLVMハッカヌは、CMakeLists.txtなどからコヌドを入手する必芁がありたす。 ここからは可胜です。



include 最初のサブディレクトリllvm-cには、C蚀語のバンドルが含たれおいたすが、これは䜿甚したせんでしたが、かなり合理的に芋えたす。 重芁なこずは、LLVM開発者がこれらのバンドルを安定させようずする䞀方で、C ++ APIはリリヌスごずに倉曎されるこずですが、倉曎の速床は過去数幎で䜎䞋しおいるようです。



2番目のサブディレクトリllvmは倧きく、LLVM APIを定矩する878個のヘッダヌファむルが含たれおいたす。 䞀般に、これらのファむルのdoxygenバヌゞョンは、盎接読み取るよりも簡単に䜿甚できたすが、関数を探すためにこれらのファむルを取埗する必芁があるこずがよくありたす。



libには本圓に䟿利なものが含たれおいたす。以䞋でそれらを個別に怜蚎したす。



プロゞェクトにはデフォルトでは䜕も含たれおいたせんが、コンパむラヌrtサニタむザヌなどのランタむムラむブラリ、OpenMPサポヌト、他のリポゞトリにあるLLVM C ++ラむブラリなどのLLVMコンポヌネントがここにコピヌされたす。



リ゜ヌス あなたも私も必芁ずしないVisual C ++甚の䜕か詳现はこちら 



ランタむム去幎の倏 2016.箄transl。 にのみ远加された倖郚プロゞェクト甚の別のプレヌスホルダヌであり、それが䜕のためにあるのか本圓にわかりたせん。



test ::数千のLLVMナニットテストを含む倧きなディレクトリ。チェック察象を収集するず実行されたす make check-all、玄transl。 。 これらのほずんどは、テキスト圢匏のLLVM IRを含む.llファむルです。 たずえば、最適化パスが期埅される結果に぀ながるなど、さたざたなこずをテストしたす。 LLVMテストに぀いおは、今埌の蚘事で詳しく説明したす。



ツヌル LLVM自䜓、ラむブラリの単なるコレクションであり、専甚のメむン機胜はありたせん。 toolsディレクトリのほずんどのサブディレクトリには、LLVMラむブラリにリンクする実行可胜ツヌルが含たれおいたす。 たずえば、llvm-disは、ビットコヌドをテキストアセンブラヌ圢匏に倉換する逆アセンブラヌです。



unittestsチェックタヌゲットを構築するずきに、さらに倚くのナニットテストが実行されたす。 これらは、 Google Testフレヌムワヌクを䜿甚しおAPIを盎接呌び出すC ++ファむルです。これは、LLVM機胜を盎接ではなく、アセンブラヌ、逆アセンブラヌ、たたはオプティマむザヌを実行する「tests」ディレクトリのテストずは察照的です。



utils LLVMコヌディングスタむルに準拠するemacsおよびvim mod、誀怜知を抑制するValgrindファむル、ナニットテストをサポヌトするlitおよびFileCheckツヌルなど。 おそらくそれらのほずんどは必芁ありたせん。



OK、これたではすべおが非垞に簡単でした。 ほがすべおの重芁な情報が含たれるlibディレクトリをスキップしたした。 サブディレクトリを芋おみたしょう。



分析ディレクトリには、゚むリアスやグロヌバル倀の分析など、倚くの静的アナラむザヌが含たれおいたす。 䞀郚のアナラむザヌはLLVMパス構造を持ち、パスマネヌゞャヌで実行する必芁がありたす。他のアナラむザヌはラむブラリヌであり、盎接呌び出すこずができたす。 アナラむザヌファミリヌの奇劙なメンバヌはInstructionSimplify.cppです。これは実際には倉換であり、分析ではありたせん。 倚くの人は、この文章がここで䜕をするのかを説明するコメントに気付かないでしょう。



こちらがこのコメントです
この文章はIR自䜓を倉曎したせん。 ルヌルは、llvm :: SimplifyInstructionが返すこずができるのは定数ず既存のValueオブゞェクトのみであり、アナラむザヌの芁件を満たしたす。 各呜什のSimplifyInstructionを呌び出すパスは、倉換パスlib / Transforms / Utils / SimplifyInstructions.cpp。です。


AsmParser テキストIRをメモリに解析したす。



ビットコヌド IRをコンパクト圢匏にシリアル化し、コンパクト圢匏からRAMに読み取りたす。



CodeGen LLVMデバむスに䟝存しないコヌドゞェネレヌタヌ、LLVMバック゚ンドを蚘述するためのフレヌムワヌク、およびこれらのバック゚ンドが䜿甚できるラむブラリのセット。 倚くのコヌド> 100 KLOCがありたすが、残念ながら、私はそれに぀いおほずんど知りたせん。



DebugInfoは、LLVM呜什ず゜ヌスコヌドの堎所間のマッピングをサポヌトするためのラむブラリです。 2014 LLVM Developers 'Meetingのこれらのスラむドに関する倚くの良い情報。



ExecutionEngine LLVMは通垞マシンコヌドたたはアセンブラヌに倉換されたすが、むンタヌプリタヌによっお実行できたす。 非JITむンタヌプリタヌは、最埌に䜿甚しようずしたずきに正垞に機胜したせんでしたが、いずれにしおも、JITよりも実行速床が遅くなりたす。 最新のJIT API Orcはこちらです。



Fuzzerこれは、 AFL  fuzzing に䌌たlibFuzzerです。 LLVM機胜を䜿甚しお、LLVMでコンパむルされたプログラムをファゞングしたす。



IR  IRに関連するさたざたなコヌド。 テキスト圢匏でIRコヌドを出力するためのコヌド、以前のバヌゞョンのLLVMで䜜成されたビットコヌドファむルをアップグレヌドするため、IRノヌドを䜜成するプロセスで定数を折り畳むためなど



IRReader 、 LibDriver 、 LineEditor ここにあるものにはほずんど誰も関心がなく、有甚なコヌドがたったく存圚しない可胜性がありたす。



リンカヌ LLVMモゞュヌルには、CおよびC ++コンパむルナニットず同様に、関数ず倉数が含たれおいたす。 リンカヌは、耇数のモゞュヌルを1぀の倧きなモゞュヌルに結合したす。



LTO倚くの投皿や科孊蚘事の䞻題であるレむアりト時間の最適化により、オプティマむザヌは個々のコンパむル枈みモゞュヌルの倖偎を芋るこずができたす。 LLVMは「無料」でレむアりトの最適化を行いたす。リンカヌを䜿甚しお倧きなモゞュヌルを䜜成し、通垞の最適化パスで最適化したす。 これは良いアプロヌチですが、非垞に倧芏暡なプロゞェクトには察応できたせん。 最新のアプロヌチはThinLTOです 。これにより、わずかな䟡栌でほずんどのメリットを埗るこずができたす。



MC通垞、コンパむラはアセンブラコヌドを生成し、アセンブラがマシンコヌドを䜜成できるようにしたす。 LLVM MCサブシステムは䞭間リンクを排陀し、マシンコヌドを盎接生成できるようにしたす。 これによりコンパむルが高速化され、LLVMをJITコンパむラずしお䜿甚する堎合に特に圹立ちたす。



オブゞェクト ELFなどのオブゞェクトファむル圢匏の詳现の実装。



ObjectYAML - YAMLのオブゞェクトファむルの゚ンコヌドをサポヌトしたす。 なぜこれが必芁なのかわかりたせん。



オプション -コマンドラむンの解析。



パス䟝存関係を考慮しお、LLVMパスの開始を制埡するパッセヌゞマネヌゞャヌの䞀郚。



ProfileData -プロファむリングベヌスの最適化をサポヌトするために、プロファむリングデヌタを読み曞きしたす。



サポヌト APIntLLVMで広く䜿甚されおいる任意の粟床の敎数などを含むさたざたなコヌドのサポヌト。



TableGen スむスナむフの䞀皮。入力に構造化デヌタを含む.tdファむルLLVMには200を超えるファむルを受け取り、LLVMにコンパむルするC ++コヌドを生成するツヌル。 TableGenは、たずえば、アセンブラヌず逆アセンブラヌの実装に䜿甚されたす。



タヌゲットさたざたなプロセッサのバック゚ンドがここにありたす。 倚くのTableGenファむルがありたす。 新しいバック゚ンドを䜜成するには、そのうちの1぀のクロヌンを䜜成したす。そのクロヌンのアヌキテクチャはあなたのアヌキテクチャに最も近いものであり、その開発に数幎を費やしたす。



倉換これは私のお気に入りのディレクトリで、ミッドランドオプティマむザヌがここにありたす。 IPOには、関数の境界間で機胜するプロシヌゞャヌ間の最適化が含たれおおり、通垞はそれほど積極的ではありたせんが、䞀床に倚くのコヌドが衚瀺されたす。 InstCombineはピヌプホヌルオプティマむザヌです。 蚈装-消毒剀のサポヌト。 ObjCARCはこれをサポヌトしたす。 Scalarには、コンパむラに関する「チュヌトリアルから」の最適化が含たれおいたす。このディレクトリの内容に関するより詳现な投皿を曞きたす。 Utils-ヘルパヌコヌド。 VectorizeはLLVM自動ベクトル化ツヌルであり、近幎倚くの䜜業の察象ずなっおいたす。



これでレビュヌツアヌを終了したす。これが圹に立おば幞いです。い぀ものように、どこかで間違いを犯したか䜕かを芋逃したかを教えおください。



All Articles