最適化の範囲: p0 ~ p1
for (p = p0; p < p1; p = 次の命令) {
if (pの命令がAEs_OpCmpEq~AEs_OpCmpRnz) { r = p; (この命令の場所を覚えておく) }
if (pの命令がAEs_OpSetCc && 次の命令がAEs_OpCmpEqかAEs_OpCmpNeで定数0との比較 && OpSetCcの結果をその先で一切使わない) {
if (次の命令がAEs_OpCmpEq) { rに書いてある命令の比較条件を反転させる }
pのSetCc命令をNopにしてしまう
pの次のAEs_OpCmpEq/AEs_OpCmpNe命令もNopにしてしまう
}
}if ((a > 1) != 0) goto label; // HLX-001が内部的に生成してしまう共通中間コードをC言語風に書いたもの 1: OpCmpGt(a, 1); // (最適前)上記を共通中間コードにしたもの 2: OpSetCc(tmp); // この2行目と3行目は最適化によって消される 3: OpCmpNe(tmp, 0); 4: Op0Jcc(label); 1: OpCmpGt(a, 1); // (最適化後)このようにうまくいく 2: Op0Jcc(label);
最適化の範囲: p0 ~ p1
変数の値を記憶するテーブルを初期化
for (p = p0; p < p1; p = 次の命令) {
定数代入命令があったら、テーブルに変数の値を登録
その他、結果が定数になるような演算があれば、それも結果をテーブルに登録
もし定数のみの演算ではなく結果が定数じゃないかもしれないと思われるときは、テーブルから変数に関する行を削除
命令の中で変数が使われていたら、その変数がテーブルに登録されていないかを確認し、登録されていれば定数値に置換する。
ラベル宣言文に当たったら、テーブルをいったん全クリアする(もうどの変数に定数値がはいっているか分からないので)
}最適化の範囲: p0 ~ p1
for (p = p0; p < p1; p = 次の命令) {
if (pの命令がOp0JmpかOp0Jcc) {
分岐先の命令を見る
もしOp0Jmpだったら、分岐先を修正
}
}最適化範囲: p0 ~ p1 範囲内のプログラムの、Op0JmpやOp0Jcc命令を探してラベルの参照回数をカウントする そして参照回数が0回のラベル宣言文は削除してしまう