a21_txt02_6a
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
* 「10日くらいでできる!プログラミング言語自作入門」の続...
-(by [[K]], 2021.04.29)
** (1) HL-16a
-HL-16までで、「簡単にできる」かつ「そこそこ効果がある」...
-機械語の中で%mを使ってメモリアクセスしている回数を変数別...
-これがわかれば、出現頻度が高いものからregVarに指定すれば...
----
-[1]optimizerX86()関数の宣言の直前に、以下の一行を追加
int vc[MAX_TC + 1];
-[2]optimizerX86()関数に3行追加
if (icq0[0] == 0x8b && isConstM(&icq0[1])) {
int reg = (icq0[1] >> 3) & 7, i = getConstM(...
+ vc[((AInt *) get32(&icq0[2])) - var]--;
icq = icq0;
if (i == 0) { putIcX86("31_%0c", (IntP) (reg...
else { putIcX86("%0c_%1i", (IntP) (re...
}
if (icq0[0] <= 0x3f && (icq0[0] & 7) == 3 && isC...
int reg = (icq0[1] >> 3) & 7, i = getConstM(...
+ vc[((AInt *) get32(&icq0[2])) - var]--;
icq = icq0;
if (-0x80 <= i && i <= 0x7f) { putIcX86("83_...
else { putIcX86("81_...
}
if (icq0[0] == 0x0f && icq0[1] == 0xaf && isCons...
int reg = (icq0[2] >> 3) & 7, i = getConstM(...
+ vc[((AInt *) get32(&icq0[3])) - var]--;
icq = icq0;
if (-0x80 <= i && i <= 0x7f) { putIcX86("6b_...
else { putIcX86("69_...
}
-[3]optimizerX86()関数に2行追加
if (icq0[0] == 0x8b && icq1 != 0 && icq1[0] == 0...
icq = icq0; // 8b命令は削除.
i = (IntP) get32(icq1 + 2) - var;
+ vc[i]--;
if (TcTmp0 <= i && i <= TcTmp9) {
+ vc[i]--;
icq = icq1; // 89命令も削除.
}
}
-[4]putIcX86_sub()関数に1行追加
if (s[i + 2] == 'm') { // mod r/m.
k = s[i + 3] - '0';
i += 4;
subcmd_m:
if (regVar(a[j]) < 0) {
*icq = 0x05 + k * 8 + addVal;
put32(icq + 1, (int) a[j]);
+ vc[a[j] - var]++;
icq += 5;
} else {
*icq = 0xc0 + regVarNo[regVar(a[j])]...
icq++;
}
addVal = 0;
continue;
}
-[5]compile()関数に3行追加
int compile(String s)
{
(中略)
for (i = 0; i < 10; i++) {
tmp_flag[i] = 0;
}
tmpLabelNo = 0;
+ for (i = 0; i < MAX_TC + 1; i++) {
+ vc[i] = 0;
+ }
bd = lbd = 0;
toExit = tmpLabelAlloc();
for (pc = 0; pc < pc1; ) { // コンパイル開始.
(中略)
}
-[6]run()関数に5行追加
int run(String s)
{
if (compile(s) < 0)
return 1;
if (codedump == 0) {
void (*func)() = (void (*)()) ic;
t0 = clock();
func();
if (win != 0) {
aFlushAll(win);
}
} else {
int i, i1 = dump1 - dump0;
for (i = 0; i < i1; i++) {
printf("%02x ", dump0[i]);
}
printf("\n(len=%d)\n", i1);
+ for (i = 0; i < MAX_TC + 1; i++) {
+ if (vc[i] != 0) {
+ printf("#%04d(%08x): %06d: %s\n", i, (int...
+ }
+ }
}
return 0;
}
----
-以上すべての改造を終えると、プログラムは1081行になります。
-それでは早速動かしてみます。
>codedump 1
(len=0)
>run maze.c
b8 f0 02 00 ...
(len=1533)
#0036(00421aa0): 000024: _t0
#0037(00421aa4): 000010: _t1
#0038(00421aa8): 000008: _t2
#0071(00421b2c): 000001: w
#0072(00421b30): 000003: i
#0073(00421b34): 000009: x
#0074(00421b38): 000009: y
#0075(00421b3c): 000014: xx
#0076(00421b40): 000014: yy
#0077(00421b44): 000004: d0
#0078(00421b48): 000004: d1
#0079(00421b4c): 000004: d2
#0080(00421b50): 000004: d3
#0081(00421b54): 000002: d
#0082(00421b58): 000013: dd
#0093(00421b84): 000001: 23
#0094(00421b88): 000001: 15
-これを見ると、変数xx, yy, ddの出現頻度が高そうです。あと...
>regVar(0 xx yy dd x)
8b 1d 3c 1b ...
(len=96)
>run maze.c
b8 f0 02 00 ...
(len=1265)
#0036(00421aa0): 000024: _t0
#0037(00421aa4): 000010: _t1
#0038(00421aa8): 000008: _t2
#0071(00421b2c): 000001: w
#0072(00421b30): 000003: i
#0074(00421b38): 000009: y
#0077(00421b44): 000004: d0
#0078(00421b48): 000004: d1
#0079(00421b4c): 000004: d2
#0080(00421b50): 000004: d3
#0081(00421b54): 000002: d
#0093(00421b84): 000001: 23
#0094(00421b88): 000001: 15
-ということで、このregVarの設定ではプログラムの大きさが15...
** (2) プログラムの説明
-まず変数vc[]を追加します。
-そしてputIcX86_sub()関数で、%mで参照されるたびにvc[]を加...
-あとはoptimizerX86()関数で最適化の結果、メモリ変数へのア...
-最後にcodedumpで機械語を出力するついでにvc[]の値を表示し...
** (3) 成果の比較
-上記みたいなのはすごく特別でレアケースなのか、それともよ...
-サイズが小さくなったからいいとか悪いとかではなく、「サイ...
||HL-13a|HL-14|HL-14a|HL-15|HL-15a|HL-16|HL-16a|備考|
|mandel.c|RIGHT:1087|RIGHT:1007|RIGHT:942|RIGHT:768|RIGHT...
|maze.c|RIGHT:2192|RIGHT:2192|RIGHT:2192|RIGHT:1770|RIGHT...
|kcube.c|RIGHT:4623|RIGHT:4623|RIGHT:4623|RIGHT:3695|RIGH...
|invader.c|RIGHT:3260|RIGHT:3260|RIGHT:3260|RIGHT:2750|RI...
-x86(32bit)のJITコンパイラの話はこれでいったんおしまいで...
-次からはx64(64bit)のJITコンパイラの話を書きます。
** 次回に続く
-次回: [[a21_txt02_6b]]
*こめんと欄
#comment
終了行:
* 「10日くらいでできる!プログラミング言語自作入門」の続...
-(by [[K]], 2021.04.29)
** (1) HL-16a
-HL-16までで、「簡単にできる」かつ「そこそこ効果がある」...
-機械語の中で%mを使ってメモリアクセスしている回数を変数別...
-これがわかれば、出現頻度が高いものからregVarに指定すれば...
----
-[1]optimizerX86()関数の宣言の直前に、以下の一行を追加
int vc[MAX_TC + 1];
-[2]optimizerX86()関数に3行追加
if (icq0[0] == 0x8b && isConstM(&icq0[1])) {
int reg = (icq0[1] >> 3) & 7, i = getConstM(...
+ vc[((AInt *) get32(&icq0[2])) - var]--;
icq = icq0;
if (i == 0) { putIcX86("31_%0c", (IntP) (reg...
else { putIcX86("%0c_%1i", (IntP) (re...
}
if (icq0[0] <= 0x3f && (icq0[0] & 7) == 3 && isC...
int reg = (icq0[1] >> 3) & 7, i = getConstM(...
+ vc[((AInt *) get32(&icq0[2])) - var]--;
icq = icq0;
if (-0x80 <= i && i <= 0x7f) { putIcX86("83_...
else { putIcX86("81_...
}
if (icq0[0] == 0x0f && icq0[1] == 0xaf && isCons...
int reg = (icq0[2] >> 3) & 7, i = getConstM(...
+ vc[((AInt *) get32(&icq0[3])) - var]--;
icq = icq0;
if (-0x80 <= i && i <= 0x7f) { putIcX86("6b_...
else { putIcX86("69_...
}
-[3]optimizerX86()関数に2行追加
if (icq0[0] == 0x8b && icq1 != 0 && icq1[0] == 0...
icq = icq0; // 8b命令は削除.
i = (IntP) get32(icq1 + 2) - var;
+ vc[i]--;
if (TcTmp0 <= i && i <= TcTmp9) {
+ vc[i]--;
icq = icq1; // 89命令も削除.
}
}
-[4]putIcX86_sub()関数に1行追加
if (s[i + 2] == 'm') { // mod r/m.
k = s[i + 3] - '0';
i += 4;
subcmd_m:
if (regVar(a[j]) < 0) {
*icq = 0x05 + k * 8 + addVal;
put32(icq + 1, (int) a[j]);
+ vc[a[j] - var]++;
icq += 5;
} else {
*icq = 0xc0 + regVarNo[regVar(a[j])]...
icq++;
}
addVal = 0;
continue;
}
-[5]compile()関数に3行追加
int compile(String s)
{
(中略)
for (i = 0; i < 10; i++) {
tmp_flag[i] = 0;
}
tmpLabelNo = 0;
+ for (i = 0; i < MAX_TC + 1; i++) {
+ vc[i] = 0;
+ }
bd = lbd = 0;
toExit = tmpLabelAlloc();
for (pc = 0; pc < pc1; ) { // コンパイル開始.
(中略)
}
-[6]run()関数に5行追加
int run(String s)
{
if (compile(s) < 0)
return 1;
if (codedump == 0) {
void (*func)() = (void (*)()) ic;
t0 = clock();
func();
if (win != 0) {
aFlushAll(win);
}
} else {
int i, i1 = dump1 - dump0;
for (i = 0; i < i1; i++) {
printf("%02x ", dump0[i]);
}
printf("\n(len=%d)\n", i1);
+ for (i = 0; i < MAX_TC + 1; i++) {
+ if (vc[i] != 0) {
+ printf("#%04d(%08x): %06d: %s\n", i, (int...
+ }
+ }
}
return 0;
}
----
-以上すべての改造を終えると、プログラムは1081行になります。
-それでは早速動かしてみます。
>codedump 1
(len=0)
>run maze.c
b8 f0 02 00 ...
(len=1533)
#0036(00421aa0): 000024: _t0
#0037(00421aa4): 000010: _t1
#0038(00421aa8): 000008: _t2
#0071(00421b2c): 000001: w
#0072(00421b30): 000003: i
#0073(00421b34): 000009: x
#0074(00421b38): 000009: y
#0075(00421b3c): 000014: xx
#0076(00421b40): 000014: yy
#0077(00421b44): 000004: d0
#0078(00421b48): 000004: d1
#0079(00421b4c): 000004: d2
#0080(00421b50): 000004: d3
#0081(00421b54): 000002: d
#0082(00421b58): 000013: dd
#0093(00421b84): 000001: 23
#0094(00421b88): 000001: 15
-これを見ると、変数xx, yy, ddの出現頻度が高そうです。あと...
>regVar(0 xx yy dd x)
8b 1d 3c 1b ...
(len=96)
>run maze.c
b8 f0 02 00 ...
(len=1265)
#0036(00421aa0): 000024: _t0
#0037(00421aa4): 000010: _t1
#0038(00421aa8): 000008: _t2
#0071(00421b2c): 000001: w
#0072(00421b30): 000003: i
#0074(00421b38): 000009: y
#0077(00421b44): 000004: d0
#0078(00421b48): 000004: d1
#0079(00421b4c): 000004: d2
#0080(00421b50): 000004: d3
#0081(00421b54): 000002: d
#0093(00421b84): 000001: 23
#0094(00421b88): 000001: 15
-ということで、このregVarの設定ではプログラムの大きさが15...
** (2) プログラムの説明
-まず変数vc[]を追加します。
-そしてputIcX86_sub()関数で、%mで参照されるたびにvc[]を加...
-あとはoptimizerX86()関数で最適化の結果、メモリ変数へのア...
-最後にcodedumpで機械語を出力するついでにvc[]の値を表示し...
** (3) 成果の比較
-上記みたいなのはすごく特別でレアケースなのか、それともよ...
-サイズが小さくなったからいいとか悪いとかではなく、「サイ...
||HL-13a|HL-14|HL-14a|HL-15|HL-15a|HL-16|HL-16a|備考|
|mandel.c|RIGHT:1087|RIGHT:1007|RIGHT:942|RIGHT:768|RIGHT...
|maze.c|RIGHT:2192|RIGHT:2192|RIGHT:2192|RIGHT:1770|RIGHT...
|kcube.c|RIGHT:4623|RIGHT:4623|RIGHT:4623|RIGHT:3695|RIGH...
|invader.c|RIGHT:3260|RIGHT:3260|RIGHT:3260|RIGHT:2750|RI...
-x86(32bit)のJITコンパイラの話はこれでいったんおしまいで...
-次からはx64(64bit)のJITコンパイラの話を書きます。
** 次回に続く
-次回: [[a21_txt02_6b]]
*こめんと欄
#comment
ページ名: