2010年04月06日

LLVM の JIT を使ってみる (4)

今回はローカル変数を作ってみました。

また、JIT 実行ではなく、bitcode をファイルに書き出してみました。

WriteBitcodeToFile() API の使い方などは、ModuleMaker.cpp というサンプルを参考にしました。そのままそのサンプルの main() 関数を、後述するものに置き換えて、関連しそうなプロジェクト全てに依存関係を設定すれば、ビルド & 実行できるはずです。

(なぜか HowToUseJIT サンプルでは、関連しそうなプロジェクト全てに依存関係を設定しても、BitcodeWriter.cpp の関数がリンクできませんでした。)



/* 以下のような main 関数を作る。
  
     int32_t main()
     {
         int32_t x;
         x = 123;
         return x;
     }

   実際は以下のようになる。

     int32_t main()
     {
         int32_t *x = alloca(sizeof(int32_t));
         *x = 123;
         return *x;
     }
*/
int main() {
  LLVMContext ctx;

  Module *m = new Module("test", ctx);
  Function *f = cast<Function>(m->getOrInsertFunction("main",
                                                      Type::getInt32Ty(ctx),
                                                      NULL));
  BasicBlock *block = BasicBlock::Create(ctx, "", f);
  IRBuilder<> builder(block);

  // 定数 123
  Value *c = ConstantInt::get(Type::getInt32Ty(ctx), 123);
  // 32 bit 自動変数へのポインタ
  Value *xp = builder.CreateAlloca(Type::getInt32Ty(ctx), 0, "x");
  builder.CreateStore(c, xp);
  Value *x = builder.CreateLoad(xp);
  builder.CreateRet(x);

  WriteBitcodeToFile(m, outs());

  delete m;
  return 0;
}

実行すると、以下のようになります。

C:\llvm\work> ModuleMaker > ModuleMaker.bc
C:\llvm\work>llvm-dis ModuleMaker.bc
C:\llvm\work>ls
modulemaker.bc  modulemaker.ll
C:\llvm\work>cat ModuleMaker.ll
; ModuleID = 'ModuleMaker.bc'

define i32 @main() {
  %x = alloca i32                                 ; <i32*> [#uses=2]
  store i32 123, i32* %x
  %1 = load i32* %x                               ; <i32> [#uses=1]
  ret i32 %1
}
:\llvm\work>llc ModuleMaker.ll
C:\llvm\work>cat ModuleMaker.s
        .def     _main; .scl    2;      .type   32;     .endef
        .text
        .globl  _main
        .align  16, 0x90
_main:                                  # @main
# BB#0:
        subl    $4, %esp
Llabel1:
        movl    $123, (%esp)
        movl    $123, %eax
        addl    $4, %esp
        ret
C:\llvm\work>path %path%;c:\MinGW\bin
C:\llvm\work>gcc ModuleMaker.s


トラックバックURL

コメント一覧

1. Posted by h_sakurai   2010年04月07日 13:19
テスト、チェスト、チェストー
っと。
結構簡単にできるんですね。
2. Posted by 若槻   2010年04月07日 17:05
そうですね、あっさり動いてくれて良かったです。

少しはまった点として、変な bitcode でも、API で作るときには何もチェックが入らないので、それを llc でネイティブアセンブラに変換するときに型が合わなくて怒られたというのがありました。

コメントする

名前
URL
 
  絵文字
 
 
記事検索
最新コメント
アクセスカウンター
  • 今日:
  • 昨日:
  • 累計:

QRコード
QRコード