inkwell
LLVM C API を安全にラップした Rust の LLVM バインディングクレート。トイ言語コンパイラ toy-llvm-compiler (ipulang) で LLVM IR 生成に使用 (LLVM 12 系)。生成した .ll を clang で実行ファイルへリンクする。
IR の階層と生成
- LLVM IR は
Module > Function > Block > Instructionの階層構造。Builderのメソッド呼び出しで手続き的に命令を組む。 - 変数:
build_allocaでスタック確保 →build_store/build_load。二項加算はbuild_int_add。 - 関数:
i32_type.fn_type(args, is_vararg)で型宣言し、entryブロックを作って引数を ptr に load。 - 制御フロー:
append_basic_blockでブロックを作り、build_unconditional_branch/build_conditional_branch(build_int_compareでcond != 0) で結線。各ブロック生成前にposition_at_endを呼ぶ必要がある。 - 組み込み関数 (
putchar/getchar) は IR 内で 宣言だけ しておけばリンク時に解決され呼べる。 - 最後に
module.print_to_string()で IR 文字列を得る。
コード生成の状態管理
コンパイラ側は Env 構造体に module / ctx / 関数ごとの変数マップ / 一時変数カウンタ / 関数テーブル / 現在の builder・関数 を保持し、各 AST ノードに gen_code(&mut env) を実装して Program から再帰的に呼ぶ (後に trait CodeGen へ整理)。
関連
- toy-llvm-compiler、llvm-mlir、rust-lang。
- 命令へ落とすバックエンド側は instruction-selection-register-allocation、対象 ISA は risc-v-isa。