a21_txt02_12a
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
* 「10日くらいでできる!プログラミング言語自作入門」の続...
-(by [[K]], 2021.05.18)
** (1) HL-22a
-HL-22までで、「簡単にできる」かつ「そこそこ効果がある」...
-機械語の中で%mを使ってメモリアクセスしている回数を変数別...
-これがわかれば、出現頻度が高いものからregVarに指定すれば...
----
-[1]optimizerX64()関数の宣言の直前に、以下の一行を追加
int vc[MAX_TC + 1];
-[2]optimizerX64()関数に6行追加
if (icq0[0] == 0x48 && icq0[1] == 0x8b && isCons...
AInt reg = (icq0[2] >> 3) & 7, i = getConstM...
+ vc[get32(&icq0[3]) / 8]--;
icq = icq0;
if (i == 0) { putIcX64("31_%0c", ...
else if (i >> 32 == 0) { putIcX64("%0c_%1i",...
else if (is32bit(i)) { putIcX64("48_c7_%0c...
else { putIcX64("48_%0c_%1...
}
if (icq0[0] == 0x4c && icq0[1] == 0x8b && isCons...
AInt reg = (icq0[2] >> 3) & 7, i = getConstM...
+ vc[get32(&icq0[3]) / 8]--;
icq = icq0;
if (i == 0) { putIcX64("4d_31_%0c...
else if (i >> 32 == 0) { putIcX64("41_%0c_%1...
else if (is32bit(i)) { putIcX64("49_c7_%0c...
else { putIcX64("49_%0c_%1...
}
if (icq0[0] == 0x48 && icq0[1] <= 0x3f && (icq0[...
AInt reg = (icq0[2] >> 3) & 7, i = getConstM...
+ vc[get32(&icq0[3]) / 8]--;
icq = icq0;
if (-0x80 <= i && i <= 0x7f) { putIcX64("48_...
else { putIcX64("48_...
}
if (icq0[0] == 0x4c && icq0[1] <= 0x3f && (icq0[...
AInt reg = (icq0[2] >> 3) & 7, i = getConstM...
+ vc[get32(&icq0[3]) / 8]--;
icq = icq0;
if (-0x80 <= i && i <= 0x7f) { putIcX64("49_...
else { putIcX64("49_...
}
if (icq0[0] == 0x48 && icq0[1] == 0x0f && icq0[2...
AInt reg = (icq0[3] >> 3) & 7, i = getConstM...
+ vc[get32(&icq0[4]) / 8]--;
icq = icq0;
if (-0x80 <= i && i <= 0x7f) { putIcX64("48_...
else { putIcX64("48_...
}
if (icq0[0] == 0x4c && icq0[1] == 0x0f && icq0[2...
AInt reg = (icq0[3] >> 3) & 7, i = getConstM...
+ vc[get32(&icq0[4]) / 8]--;
icq = icq0;
if (-0x80 <= i && i <= 0x7f) { putIcX64("4d_...
else { putIcX64("4d_...
}
-[3]optimizerX64()関数に2行追加
if (icq1 != 0 && memcmp(icq0, "\x48\x8b\x85", 3)...
icq = icq0; // 8b命令は削除.
i = get32(icq1 + 3) / 8;
+ vc[i]--;
if (TcTmp0 <= i && i <= TcTmp9) {
icq = icq1; // 89命令も削除.
+ vc[i]--;
}
}
-[4]putIcX64_sub()関数に1行追加
if (s[i + 2] == 'm') { // mod r/m.
k = s[i + 3] - '0';
if (s[i + 3] >= 'a') { // もしかしたらこ...
k = s[i + 3] - 'a' + 10;
}
i += 4;
subcmd_m: ;
int rv = regVar(a[j]);
if (k >= 8) {
*putIcX64_rex += 4;
k -= 8;
}
if (rv < 0) {
*icq = 0x85 + k * 8 + addVal;
put32(icq + 1, (a[j] - var) * 8);
+ vc[a[j] - var]++;
icq += 5;
} else {
rv = regVarNo[rv];
if (rv >= 8) {
*putIcX64_rex += 1;
rv -= 8;
}
*icq = 0xc0 + rv + k * 8 + addVal;
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: %06d: %s\n", i, vc[i], ts[...
+ }
+ }
}
return 0;
}
----
-以上すべての改造を終えると、プログラムは1223行になります。
-それでは早速動かしてみます。
>codedump 1
(len=0)
>run maze.c
b9 f0 02 00 ...
(len=1638)
#0036: 000032: _t0
#0037: 000010: _t1
#0038: 000008: _t2
#0049: 000003: sub_xorShift
#0050: 000009: sub_aGetPix
#0056: 000007: sub_aFilRct0
#0059: 000001: sub_opnWin
#0060: 000001: sub_aWait
#0089: 000001: w
#0090: 000003: i
#0091: 000009: x
#0092: 000009: y
#0093: 000014: xx
#0094: 000014: yy
#0095: 000004: d0
#0096: 000004: d1
#0097: 000004: d2
#0098: 000004: d3
#0099: 000002: d
#0100: 000013: dd
#0111: 000001: 23
#0112: 000001: 15
-これを見ると、変数xx, yy, ddの出現頻度が高そうです。あと...
>regVar(0, xx, yy, dd, x, y, d0, d1)
48 8b 9d e8 ...
(len=49)
>run maze.c
b8 f0 02 00 ...
(len=1289)
#0036: 000032: _t0
#0037: 000010: _t1
#0038: 000008: _t2
#0049: 000003: sub_xorShift
#0050: 000009: sub_aGetPix
#0056: 000007: sub_aFilRct0
#0059: 000001: sub_opnWin
#0060: 000001: sub_aWait
#0089: 000001: w
#0090: 000003: i
#0097: 000004: d2
#0098: 000004: d3
#0099: 000002: d
#0111: 000001: 23
#0112: 000001: 15
-ということで、このregVarの設定ではプログラムの大きさが16...
** (2) プログラムの説明
-まず変数vc[]を追加します。
-そしてputIcX64_sub()関数で、%mで参照されるたびにvc[]を加...
-あとはoptimizerX64()関数で最適化の結果、メモリ変数へのア...
-最後にcodedumpで機械語を出力するついでにvc[]の値を表示し...
** (3) 成果の比較
-上記みたいなのはすごく特別でレアケースなのか、それともよ...
-サイズが小さくなったからいいとか悪いとかではなく、「サイ...
||HL-19a|HL-20|HL-20a|HL-20b|HL-21|HL-21a|HL-22|HL-22a|備...
|mandel.c|RIGHT:1200|RIGHT:1088|RIGHT:989|RIGHT:989|RIGHT...
|maze.c|RIGHT:2331|RIGHT:2331|RIGHT:2331|RIGHT:2331|RIGHT...
|kcube.c|RIGHT:5207|RIGHT:5207|RIGHT:5207|RIGHT:5207|RIGH...
|invader.c|RIGHT:3567|RIGHT:3567|RIGHT:3567|RIGHT:3567|RI...
** 次回に続く
-次回: ''a21_txt02_13''
*こめんと欄
#comment
終了行:
* 「10日くらいでできる!プログラミング言語自作入門」の続...
-(by [[K]], 2021.05.18)
** (1) HL-22a
-HL-22までで、「簡単にできる」かつ「そこそこ効果がある」...
-機械語の中で%mを使ってメモリアクセスしている回数を変数別...
-これがわかれば、出現頻度が高いものからregVarに指定すれば...
----
-[1]optimizerX64()関数の宣言の直前に、以下の一行を追加
int vc[MAX_TC + 1];
-[2]optimizerX64()関数に6行追加
if (icq0[0] == 0x48 && icq0[1] == 0x8b && isCons...
AInt reg = (icq0[2] >> 3) & 7, i = getConstM...
+ vc[get32(&icq0[3]) / 8]--;
icq = icq0;
if (i == 0) { putIcX64("31_%0c", ...
else if (i >> 32 == 0) { putIcX64("%0c_%1i",...
else if (is32bit(i)) { putIcX64("48_c7_%0c...
else { putIcX64("48_%0c_%1...
}
if (icq0[0] == 0x4c && icq0[1] == 0x8b && isCons...
AInt reg = (icq0[2] >> 3) & 7, i = getConstM...
+ vc[get32(&icq0[3]) / 8]--;
icq = icq0;
if (i == 0) { putIcX64("4d_31_%0c...
else if (i >> 32 == 0) { putIcX64("41_%0c_%1...
else if (is32bit(i)) { putIcX64("49_c7_%0c...
else { putIcX64("49_%0c_%1...
}
if (icq0[0] == 0x48 && icq0[1] <= 0x3f && (icq0[...
AInt reg = (icq0[2] >> 3) & 7, i = getConstM...
+ vc[get32(&icq0[3]) / 8]--;
icq = icq0;
if (-0x80 <= i && i <= 0x7f) { putIcX64("48_...
else { putIcX64("48_...
}
if (icq0[0] == 0x4c && icq0[1] <= 0x3f && (icq0[...
AInt reg = (icq0[2] >> 3) & 7, i = getConstM...
+ vc[get32(&icq0[3]) / 8]--;
icq = icq0;
if (-0x80 <= i && i <= 0x7f) { putIcX64("49_...
else { putIcX64("49_...
}
if (icq0[0] == 0x48 && icq0[1] == 0x0f && icq0[2...
AInt reg = (icq0[3] >> 3) & 7, i = getConstM...
+ vc[get32(&icq0[4]) / 8]--;
icq = icq0;
if (-0x80 <= i && i <= 0x7f) { putIcX64("48_...
else { putIcX64("48_...
}
if (icq0[0] == 0x4c && icq0[1] == 0x0f && icq0[2...
AInt reg = (icq0[3] >> 3) & 7, i = getConstM...
+ vc[get32(&icq0[4]) / 8]--;
icq = icq0;
if (-0x80 <= i && i <= 0x7f) { putIcX64("4d_...
else { putIcX64("4d_...
}
-[3]optimizerX64()関数に2行追加
if (icq1 != 0 && memcmp(icq0, "\x48\x8b\x85", 3)...
icq = icq0; // 8b命令は削除.
i = get32(icq1 + 3) / 8;
+ vc[i]--;
if (TcTmp0 <= i && i <= TcTmp9) {
icq = icq1; // 89命令も削除.
+ vc[i]--;
}
}
-[4]putIcX64_sub()関数に1行追加
if (s[i + 2] == 'm') { // mod r/m.
k = s[i + 3] - '0';
if (s[i + 3] >= 'a') { // もしかしたらこ...
k = s[i + 3] - 'a' + 10;
}
i += 4;
subcmd_m: ;
int rv = regVar(a[j]);
if (k >= 8) {
*putIcX64_rex += 4;
k -= 8;
}
if (rv < 0) {
*icq = 0x85 + k * 8 + addVal;
put32(icq + 1, (a[j] - var) * 8);
+ vc[a[j] - var]++;
icq += 5;
} else {
rv = regVarNo[rv];
if (rv >= 8) {
*putIcX64_rex += 1;
rv -= 8;
}
*icq = 0xc0 + rv + k * 8 + addVal;
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: %06d: %s\n", i, vc[i], ts[...
+ }
+ }
}
return 0;
}
----
-以上すべての改造を終えると、プログラムは1223行になります。
-それでは早速動かしてみます。
>codedump 1
(len=0)
>run maze.c
b9 f0 02 00 ...
(len=1638)
#0036: 000032: _t0
#0037: 000010: _t1
#0038: 000008: _t2
#0049: 000003: sub_xorShift
#0050: 000009: sub_aGetPix
#0056: 000007: sub_aFilRct0
#0059: 000001: sub_opnWin
#0060: 000001: sub_aWait
#0089: 000001: w
#0090: 000003: i
#0091: 000009: x
#0092: 000009: y
#0093: 000014: xx
#0094: 000014: yy
#0095: 000004: d0
#0096: 000004: d1
#0097: 000004: d2
#0098: 000004: d3
#0099: 000002: d
#0100: 000013: dd
#0111: 000001: 23
#0112: 000001: 15
-これを見ると、変数xx, yy, ddの出現頻度が高そうです。あと...
>regVar(0, xx, yy, dd, x, y, d0, d1)
48 8b 9d e8 ...
(len=49)
>run maze.c
b8 f0 02 00 ...
(len=1289)
#0036: 000032: _t0
#0037: 000010: _t1
#0038: 000008: _t2
#0049: 000003: sub_xorShift
#0050: 000009: sub_aGetPix
#0056: 000007: sub_aFilRct0
#0059: 000001: sub_opnWin
#0060: 000001: sub_aWait
#0089: 000001: w
#0090: 000003: i
#0097: 000004: d2
#0098: 000004: d3
#0099: 000002: d
#0111: 000001: 23
#0112: 000001: 15
-ということで、このregVarの設定ではプログラムの大きさが16...
** (2) プログラムの説明
-まず変数vc[]を追加します。
-そしてputIcX64_sub()関数で、%mで参照されるたびにvc[]を加...
-あとはoptimizerX64()関数で最適化の結果、メモリ変数へのア...
-最後にcodedumpで機械語を出力するついでにvc[]の値を表示し...
** (3) 成果の比較
-上記みたいなのはすごく特別でレアケースなのか、それともよ...
-サイズが小さくなったからいいとか悪いとかではなく、「サイ...
||HL-19a|HL-20|HL-20a|HL-20b|HL-21|HL-21a|HL-22|HL-22a|備...
|mandel.c|RIGHT:1200|RIGHT:1088|RIGHT:989|RIGHT:989|RIGHT...
|maze.c|RIGHT:2331|RIGHT:2331|RIGHT:2331|RIGHT:2331|RIGHT...
|kcube.c|RIGHT:5207|RIGHT:5207|RIGHT:5207|RIGHT:5207|RIGH...
|invader.c|RIGHT:3567|RIGHT:3567|RIGHT:3567|RIGHT:3567|RI...
** 次回に続く
-次回: ''a21_txt02_13''
*こめんと欄
#comment
ページ名: