てけもぐ Tech 忘備録

LLVM-C API を使った自作コンパイラでの LLVMBuildGEP2() の話

対象

LLVM-C API 初学者

内容

https://github.com/mzuhi5/tiny_c_compiler の話の続き。

前の投稿で GEP については記述済み。今回は LLVM-C API での構造体や配列、ポインタの GEP の話で、自分が使った ver 18.1.8 では LLVMBuildGEP2()を使う。使い方を防備録としてメモ。

関係ないかもだが、今回の自作コンパイラでは配列や構造体はローカル変数だけカバーしてる。

プロトタイプはこんな感じ。ver 15 みたいだけどここから

LLVMValueRef LLVMBuildGEP2(
    LLVMBuilderRef B,
    LLVMTypeRef Ty,
    LLVMValueRef Pointer,
    LLVMValueRef* Indices,
    unsigned int NumIndices,
    const char* Name)

注意するのは Indices 引数。IR の方の getelementptr() で言う所のインデックスを、配列に入れて引数に指定する。LLVMValueRef 型のこのインデックスは、先のブログで書いたとおりインデックスの数値に対する型を持っていればいい。ただし構造体の場合は i32 型のみ受け入れ可能。今回はデカイ値を使うことはないだろうと、構造体も含めて全て i32 型で決め打ち。

getelementptr() の計算は複数行に分割出来るので、インデックスを複数使ったケースは構造体に関するドット演算子処理のここだけ。パースの際に、矢印演算子 st->x は (*st).x に変換されてドット演算子に処理が集約されている。つまり複数インデックスを使うのは全体でもここだけで、後は単発処理の重ね合わせで済ませてる。

次の引数の NumIndices は Indices 配列の個数。今回はドット演算子での計算が 2 で後は全て 1。