Fuzix-Compiler-Kitの6800用コンパイラ(8) peep hole optimizer(1)

2024/12/16BASICMASTER, 昔のパソコン

EtchedPixels/Fuzix-Compiler-Kit: Fuzix C Compiler ProjectのCコンパイラには、peephole optimizer (のぞき穴的最適化プログラム)が付属している。

このoptimizerはZ80用のz88dkや、6809用のacwjでも使われている汎用的なツールである。アセンブラプログラムを簡単なパターンマッチで操作できる。


fcc付属オプティマイザーの使い方

オプティマイズ用のルールは rules.CPU名 というファイル名で置かれている。6800用は rules.6800 である。

rules.6800の中には最低限のルールが書かれている。peephole optimizerで頑張りすぎると全体の見通しが悪くなるので、ルールを減らしている。バグがでたときに解析不能になるし。

簡単な例

次の例は、直後のラベルへの無条件ジャンプを消し去るルール。

ルールは、 = を挟んで前後に記述する。ルール間の区切りは空行。# がコメント。%0-%9がパターンマッチに使える。タブと空白は区別される。

ルール間の区切りが空行なのは少しわかりにくい。acwjのcopt(acwj/64_6809_Target/lib/6809/rules.6809 at master · DoctorWkt/acwj)は、====を区切りにするように改良されている。


# Branches
	jmp %1
%1:
=
%1:


%0-%9によるマッチング

%0-%9があると、置き換え前のパターンに入れて、置き換え後に使える。

探すパターンに正規表現が使えないし、場合分けもできないのが面倒。6800のアドレッシング別に処理をしたい場合は、 ,x や # などを書いて区別する必要がある。


	ldx #%1
	stb %2,x
=
	stb %1+%2


%L,%M,%N

ラベル生成用の特殊変数。書き換え後にラベルが必要となったときに使える。使うたびに +1 される。

%L,%M,%N の3種類使えて、通常の用途では足りるはず。


        pshb
        psha
        clra
        ldab %1
        jsr __cclteq
;
        jeq %2_%3
=
        subb %1
        sbca #0
        jgt %2_%3
        jlt M%M_cc      ; jsr __cclteq
        tstb
        jne %2_%3
M%M_cc:


%activate

書き換えたい箇所と、書き換えのきっかけになる箇所が離れているときに使う。

下記の例では %1: jeq %2 というコードを見つけたら、jeq %1命令をjeq %2に書きかえる条件を生成(activate)する。

最初の%activateで、%activate %jeq %1 = … が起動され、それを元に書き換えが行われる。すごくわかりにくい。

activateを一度だけ行う場合は %once。


%1:
        jeq %2
=
%activate
%2:
=
%%activate
        jeq %1
=
        jeq %2
;       jmp destination change from %1 to %2


%check

パターンマッチで使った変数 %0-%9 が特定の範囲内のときだけ、書き換えを行う。

比較の <= は、変更できない。< などに置き換えるとエラーになる。 z88dk/lib/z80rules.1 at master · z88dk/z88dkが参考になる。


%check min <= %n <= max


%check 0 <= %1 <= 65535
	ld	l,(hl)
	ld	h,0
	ld	de,%1
	ex	de,hl
=
	ld	e,(hl)
	ld	d,0
	ld	hl,%1	;const


%eval

逆ポーランド記法(RPN)で書かれた式を評価する。


数値、+ * | & > < / %
> <  はシフト(2項演算)
% はパラメータ変数
%% は 剰余演算

	ld	(hl),%eval(%1 256 %%)
	inc	hl
	ld	(hl),%eval(%1 256 /)
	ld	hl,%2


acwjのcoptは改良されている

続く