memo
LLVM IR を S 式で表現するモジュールを試作中。これの機能はただ単純に、S 式で表現した LLVM IR を LLVM IR の文字列に変換すること。これはどこかで誰かがやってるに違いないと思うが、見つけられなかった。読み飛ばしている可能性も高いけど。
- LLVM IR はほとんど1行1命令。例外的にラベル、関数定義のブロックあり。
- '=' による単純な形式の代入文あり。
- 作り直しになってもたかがしれているので「構文を完全に調査して網羅」などということは目指さず、自分の知っている範囲の LLVM IR 構文でまず動くようにする。困ったら困ったときに考える。
以下のように、S式を変換するところまでできた。
gosh> (trans-ir '(define-function i32 scheme_entry () (assign %ret (alloca i32)) (store (i32 4) (i32* %ret)) (assign %var1 (load (i32* %ret))) (assign %var2 (add (i32 4 %var1))) (store (i32 %var2) (i32* %ret)) (assign %retval (load (i32* %ret))) (ret (i32 %retval)))) define i32 @scheme_entry() nounwind { entry: %ret = alloca i32 store i32 4, i32* %ret %var1 = load i32* %ret %var2 = add i32 4, %var1 store i32 %var2, i32* %ret %retval = load i32* %ret ret i32 %retval } #<undef>
変換部分では match を使用。以下はまだ未完成だけど、 match を使うのが楽しくて仕方が無い。
(define (trans-ir form) (match form (('define-function type name ((ty arg) ...) body ...) (emit "define ~a @~a(~a) nounwind {" type name (string-join (map (cut format #f "~a ~a" <> <>) ty arg) ", ")) (emit "entry:") (map emit (map trans-seq body)) (emit "}")) (_ (errorf "mulformed define: ~a" form)))) ;; *** store Instruction ;; (store (ty value) (ty* pointer)) => store <ty> <value>, <ty>* <pointer> ;; (store (ty value) (ty* pointer) align) => store <ty> <value>, <ty>* <pointer>, align alignment (define-inst (store . args) (match args (((ty value) (ty* pointer)) (format #f "store ~a ~a, ~a ~a" ty value ty* pointer)) (((ty value) (ty* pointer) align) (format #f "store ~a ~a, ~a ~a, align ~a" ty value ty* pointer align)) (_ (errorf "mulformed: ~a" args))))