llvmruby との比較

細かく修正。3/12

http://d.hatena.ne.jp/miura1729/20090311 経由で http://llvmruby.org/wordpress-llvmruby/ compiling a standalone binary の例をなんとなく真似してみました。

  • llvm ruby は言ってみれば DOM で HTML 作るみたいなイメージでしょうか。"LLVMRuby is a pretty straighforward wrapper around the C++ API" と書いてありました。http://llvm.org/docs/tutorial/index.html LLVM Tutorial もそうなのですが、API を使ってプログラムを組み立てていくのは何かまどろっこしさを感じます。
  • S-式版は主観的にはとても直接的。SXML で HTML 作るみたいなイメージです(ところどころ私の実装がどんくさくかっこわるいですが)。代償として、ちゃんとしたAPIを使っていないために不完全です。
  • わたしの家内の感想は「(わたしのscheme版は)アスキーアートみたいで嫌」だそうです。このエレガントさが分からないとは何と度し難い‥!
;; llvmgen version

(define-module grape
  (use llvmgen))

(select-module grape)

(define (string-constant-type str)
  (format #f "[~a x i8]" (+ 1 (string-length str))))

(define (string-constant-type* str)
  (format #f "[~a x i8]*" (+ 1 (string-length str))))

(define (define-string-constant var str)
  (let1 type (string-constant-type str)
  `(assign ,var ,(format #f "internal constant ~a" type)
           ,(format #f "c\"~a\\00\"" str))))

(define (grape-build)
  (let1 m (make-llvm-module)
    (add-global! m '(declare i32 @printf ("i8* noalias" "...")))
    (let* ((grapes-str "I LIKE GRAPES!\n")
           (type* (string-constant-type* grapes-str)))
      (add-global! m (define-string-constant '@str grapes-str))
      (let1 main
          `(define-function () i32 @main ()
             (assign %fmt (getelementptr (,type* @str) ((i32 0) (i32 0))))
             (call () i32 |(i8*, ...)*| @printf ((i8* %fmt)))
             (ret (i32 0)))
        (add-function! m main)
        (let1 p (open-output-file "grape.ll" :if-exists :supersede)
          (parameterize ([llvm-port p])
            (compile-llvm-module m)
            (close-output-port p)))))))

で、ここからが本題で、 id:miura1729 さんの場合、LLVM の最適化が不十分なので llvm-dis の結果の LLVM IR を文字列操作で?さらに最適化しようとしている、ようです。高度。確認していないのですが、 LLVMRUBY -> .bc -> optimize -> disassemble した結果(人間が読める形式)をさらに ruby のオブジェクトに読み込みなおす、という操作は llvmruby ではできないのでしょうか。
私はまだまだそこまで行っていませんが LLVM IR のバイナリ(.bc) をいつか scheme で直接読み込めるといいなあと思っています。そうすると S-式- LLVM で最適化 - S-式と戻って来れるので。ちゃんと仕様はある(http://www.llvm.org/docs/BitCodeFormat.html)ようです。

追記。

  • 書いているうちに思いついた方法。S-式で書くけど変換時には LLVMAPI を使うと間違いが無いかも。scheme からC++が呼べればいいのか。SWIG?
  • llvmruby はいろいろ簡潔に書くための仕組みを持っていそう。