園児ニア日記

LLVM-Cで最小(?)の実行形式ファイルを作る

LLVM (7.0.1) を利用して3を返すだけのプログラムをLLVM-Cで作る

将来的にセルフホスティング可能な自作言語を作りたいので、移植しやすいようにLLVM-Cを使って、とりあえず簡単なプログラムを作成してみる。
内容はmain関数で3を返すだけのもの。

minimum_llvm_c.c

#include <llvm-c/Core.h>
#include <llvm-c/ExecutionEngine.h>
#include <stdlib.h>

int main (int argc, char const *argv[]) {
  LLVMInitializeNativeTarget();
  LLVMModuleRef mod = LLVMModuleCreateWithName("minimum_llvm_c");
  LLVMValueRef function = LLVMAddFunction(mod, "main", LLVMFunctionType(LLVMInt32Type(), NULL, 0, 0));
  LLVMSetFunctionCallConv(function, LLVMCCallConv);
  LLVMBasicBlockRef block = LLVMAppendBasicBlock(function, "");
  LLVMBuilderRef builder = LLVMCreateBuilder();
  LLVMPositionBuilderAtEnd(builder, block);
  LLVMBuildRet(builder, LLVMConstInt(LLVMInt32Type(), 3, 0));

  char *errorMessage = NULL;
  LLVMPrintModuleToFile(mod, "minimum_llvm_c.ll", &errorMessage);
  LLVMDisposeBuilder(builder);
  return 0;
}

↑のコードに対して↓のコマンドを実行するとLLVM IR (minimum_llvm_c.ll) が作成される

clang `llvm-config --cflags` -c minimum_llvm_c.c
clang minimum_llvm_c.o `llvm-config --libs --cflags --ldflags core executionengine native` -o minimum_llvm_c
./minimum_llvm_c

minimum_llvm_c.ll

; ModuleID = 'minimum_llvm_c'
source_filename = "minimum_llvm_c"

define i32 @main() {
  ret i32 3
}

最後に↓のコマンドでminimum_llvm_c.llから実行ファイルを作成後、実行して終了ステータスで3が返っているか確認する。

llc minimum_llvm_c.ll
clang minimum_llvm_c.s
./a.out
echo $?
3