ComProcの代入式に対する最適化
code:サンプルコード.c
int main() {
int i;
i = 2;
return 0;
}
code:最適化前の出力.asm
main:
cpush fp
add fp,2
push 2
push cstack+0 ; 最適化したい行
std ; 最適化したい行
push 0
cpop fp
ret
push cstack+0とstdをst cstack+0にまとめたい
現状の代入式の処理コードはこうなっている
code:main.c
case kNodeAssign:
Generate(ctx, node->rhs, 0); // 代入の右辺(2)を右辺値(lval=0)として評価 ⇒ push 2
Generate(ctx, node->lhs, 1); // 代入の左辺(i)を左辺値(lval=1)として評価 ⇒ push cstack+0
if (SizeofType(node->lhs->type) == 1) {
Insn(ctx, lval ? "sta.1" : "std.1");
} else {
Insn(ctx, lval ? "sta" : "std"); // i のバイト数は 2 なので、こちら
}
node->type = node->lhs->type;
break;
愚直な最適化は可能か
push cstack+0; stdの代わりにst cstack+0を出力すれば良いと思うかもしれない
ただ、代入式は(j = 2) != 0のように、式の中に書くことが可能
代入式は「式」なので当然だ
この場合、j = 2の結果(右辺値「2」)をスタック上に残しておかねばならない
単にst cstack+0に変えると、代入値がスタックから消えてしまう
現状の代入式処理は、stdが値をスタックに残す特徴を上手く利用している
dupで代入値を複製してからst cstack+0を実行する必要があるが、最適化前と命令数が変わらないので意味がない
可能な最適化
代入式の値がそれ以上使われない場合(つまり、statementの直下にある代入式の場合)に限り、st cstack+0に置き換えることができる
Generate関数の中で、この式の結果は利用されませんよ、というのが分かるようになっていれば良さそう