LLVM for Grad Students 大学院生のためのLLVM を訳す6

Understanding LLVM IR

LLVM IRへの理解を深める.
LLVMでプログラムを動作させるには, IRがどのような構成なのか知っておく必要があるでしょう.
http://adriansampson.net/media/llvm/llvm-containers.svg

Containers: 構成

ここではLLVMプログラムにおいて重要なコンポーネントの外観を示します.

  • モジュールはソースがいるもしくは変換ユニットを表現する. すべてはモジュールに含まれています.
  • 最もわかりやすいのはFuntionはモジュールに含まれています. 実行可能コードのまとめとして名付けられた( C++で, functionとmethodはLLVM functionに対応している.)
  • 名前と引数を宣言したfunctionは主にBasicBlocksコンテナを含みます.

BasicBlockはコンパイラでお馴染みですが, イメージとしては命令の塊のようなものです.

  • Instructionは, ひとつのコード命令である. 抽象化レベルはRISC機械語とほとんどおなじである. 例えば命令は, 整数加算, 浮動小数点除算, メモリへの格納などがあります.

LLVMのほとんど -- instruction, BasicBlock, Functionを含んだ -- それらは多くの基底クラスと呼ばれる値受け渡しのC++クラスがある. 値は計算に使用できる任意の値である. 例えば, 数値であれば, アドレスであったり, グローバル変数, 定数などが含まれる.


An Instruction:

ここでは人が読めるLLVM IRの命令を示します.

%5 = add i32 %4, 2

この命令は2つの32bitの整数値を加算するものです. つまりレジスタ4の数値と定数 2 を加算し, レジスタ5にその結果を格納します.
RISC機械語を理想とするとき, どんな意味があるでしょう. 私達はレジスタを同じようにつかうが, レジスタは無限のように存在する.

つまり同じ命令は, C++命令のクラスのインスタンスとして, コンパイラ内部を表現する.
オブジェクトは(型, 他のオブジェクトの値を指すポインタのオペランドのリストへ)追加命令するオペコードを持つ.
我々の場合には、 定数2と他の命令に相当するレジスタ5を示す定数オブジェクトを指します。(LLVM IRは性的単一代入形式(SSA形式)のため, レジスタと命令は1つと変わりない. レジスタ番号はtext表現のものである.)
ところで, あなたのプログラムのLLVM IRを見たい場合, clangに次のコマンドを与えます.

$ clang -emit-llvm -S -o - something.c

Inspecting IR in Our Pass PassによるIRの検査(解析)

私達の裏で働いていたLLVM Passを取得してみよう. 私達は便利な共通のdump()と呼ばれるメソッドを使用して,重要なIRすべてのオブジェクトを解析することができる. それはIRを人間が読める程度の表現にしてくれます.
PassがFunctionを渡して, 命令の各BasicBlockのセットの上に各FunctionのBasicBlocksを反復処理するために利用してみましょう。

ここでは次のコードを示す. llvm-passskeletonのgitレポジトリのcontainersをcheck outすることで手に入れられる.

errs() << "Function body:\n";
F.dump();

for (auto& B : F) { 
  errs() << "Basic block:\n";
  B.dump();
  for (auto& I : B) {
     errs() << "Instruction: ";
     I.dump();
  }
}

C++11のautoタイプとforeach構文を使用すると、簡単にLLVM IRの階層を移動することができます。
もし, 再びビルドするなら, IRの様々な部分が分割して表示されるはずです.