LLVM IRファイルを読み込む
はじめに
ファイルに出力されたLLVM IRをC++で読み込んで遊んでみます。
環境
$ clang++ --version clang version 8.0.1-svn360950-1~exp1~20190517004233.70 (branches/release_80) Target: x86_64-pc-linux-gnu Thread model: posix InstalledDir: /usr/bin
$ llvm-config --cxxflags --ldflags --system-libs --libs core -I/usr/lib/llvm-8/include -std=c++11 -fno-exceptions -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -L/usr/lib/llvm-8/lib -lLLVM-8
LLVM IRファイルの読み込み
アプリケーションの引数にLLVM IRファイルパスを指定する想定です。
#include <llvm/IR/LLVMContext.h> #include <llvm/IR/Module.h> #include <llvm/IRReader/IRReader.h> #include <llvm/Support/SourceMgr.h> int main(int argc, char** argv) { if (argc < 2) { llvm::errs() << "Expected an argument - IR file name\n"; exit(1); } llvm::LLVMContext Context; llvm::SMDiagnostic Err; auto module = llvm::parseIRFile(argv[1], Err, Context); if (!module) { Err.print(argv[0], llvm::errs()); return 1; } return 0; }
llvm::parseIRFile
に、ファイルパスを与えるだけで、llvm::Module
(のunique_ptr) を得ることができます。
下のコマンドでLLVM IRファイルが読み込めます。
clang++ main.cpp `llvm-config --cxxflags --ldflags --system-libs --libs core` -o ir_reader ./ir_reader main.ll
少し内部を覗く
main.ll
にはmain
関数があり、いくつか命令があります。
そのオペコードを表示してみます。
次のようなコードで実現できました。
auto func = module->getFunction("main"); std::cout << "function name: " << func->getName().data() << std::endl; for (auto &bb: *func) { auto i = 0; for (auto &instr: bb) { std::cout << "%" << i << ": " << instr.getOpcodeName() << std::endl; i++; } }
$ ./ir_reader main.ll function name: main %0: alloca %1: bitcast %2: call %3: getelementptr %4: load %5: call %6: ret
お手軽ですね!