LLVM-IR(LLVM中間コード)用コンパイラの作り方 その7

前回の続き

前回、GOTO文の分ができたので、条件分岐のIF文の実装について

IF B=1 THEN A=2
というTinyBasicのソースをコード生成の仕方を説明する。

まず、
比較演算子(=)について、左辺と右辺のコードを生成する。

	%1 = load i32* %_V1, align 4
	store i32 %11, i32* %acc
	%2 = load i32* %acc, align 4
	store i32 1 , i32* %acc, align 4
	%3 = load i32* %acc, align 4

として、変数Bの中身をレジスタ的な使い捨て変数の%2に取り出し、即値の1を%3に入れる。

そして、icmp命令で比較を行う。

	%4 = icmp eq i32 %2, %3

比較した結果はBool値で%4に入る。

Boolのままだと扱いに困るので、32bit整数値に変換し、作業用の変数accに入れる。

	%5 = sext i1 %4 to i32
	store i32 %5, i32* %acc

次に作業用変数から%6に取り出して、またBool値に戻し、%7に入れる。

	%6 = load i32* %acc, align 4
	%7 = trunc i32 %6 to i1

2度手間な感じだが、IF文の条件が比較演算子(=)を使ったBoolが来る場合以外もあるので仕方が無い。

そして、Bool値の入った%7を使って条件ジャンプ命令で分岐する。

	br i1 %7, label %_IL1_THEN, label %_IL1_ELSE

ラベルの%_IL1_THENと、%_IL_ELSEは、条件が真の場合のジャンプ先と偽の場合のジャンプ先だ。
それぞれの処理のコードの最後に、br label %_IL1_ENDIFというジャンプ命令を生成する。
ラベル名のついた処理の塊のブロックの最後にはジャンプ命令が必ず必要だからだ。
そして、最後に

_IL_ENDIF:

というラベル出力して、IF文についてのコード生成は終了。
このラベル%_IL_ENDIFに対するジャンプ命令は、前々回に書いたように行の処理の行末のジャンプ命令が来るので、特にIF文の処理でENDIF部分のジャンプ命令は不要だ。

変数と、計算と、GOTO文、IF文とできると、大体簡単な処理を作ることができる。
例えば、素数を調べるエラトステネスの篩の処理とか。




コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

Time limit is exhausted. Please reload CAPTCHA.