LLVM で stderr に出力

デバッグするのに stderr に出力したいと思ったが、これが面倒だった。何か楽な方法がありそうなものだけど、、

例によって、C で書いてみて LLVM IR にしてみる。c->llvm-ir は自作。-O3 で最適化している。

gosh> (c->llvm-ir "#include <stdlib.h>\n#include <stdio.h>\nint main() { frintf(stderr, \"%d\", 10); return 1;}" 3)
; ModuleID = 'c-cheat.c'
target datalayout = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f128:64:128"
target triple = "powerpc-apple-darwin8"
	%struct.__sFILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, %struct.__sFILEX*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 }
	%struct.__sFILEX = type opaque
	%struct.__sbuf = type { i8*, i32 }
@__sF = external global [0 x %struct.__sFILE]		; <[0 x %struct.__sFILE]*> [#uses=1]
@.str = internal constant [3 x i8] c"%d\00"		; <[3 x i8]*> [#uses=1]

define i32 @main() nounwind  {
entry:
	%tmp1 = tail call i32 (...)* @frintf( %struct.__sFILE* getelementptr ([0 x %struct.__sFILE]* @__sF, i32 0, i32 2), i8* getelementptr ([3 x i8]* @.str, i32 0, i32 0), i32 10 ) nounwind 		; <i32> [#uses=0]
	ret i32 1
}

declare i32 @frintf(...)
#<undef>

うーん。ファイルのための構造体情報がどかどかと定義され、謎の getelementptr が使われている。これポータブルな LLVMコードになってるんだろうか?
また自作の LLVM 生成ライブラリはこんなややこしい call のよびだしとか構造体に対応していないので、 しょうがないので文字列として無理矢理出力した。そもそも getelementptr よく分かっていない。

これを真似してとりあえずstderrへの出力はできた。

これでようやく、プログラム実行後にコンパイラが自分で確保したメモリ領域をstderrに出力できる。