diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2023-02-04 20:54:45 +0000 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2023-02-04 20:54:45 +0000 |
commit | bc8eb6ef45d6831975606eb9932c6e72dd470b82 (patch) | |
tree | a9ae774fcb094eabbc829f65a38c6c505dbf3bc8 /sys/src/cmd/7c | |
parent | 693325b47ace28d68459911ac3d670bb0c0db79b (diff) |
7c: help and improve peephole optimizer
When using non signed integer variables, the registerizer
would produce multiple converting load instructions on each
use, which gives the peephole optimizer a hard time as it
assumes that converting move instructions are there to
actually change the data type (hence it cannot eleminate
them).
To avoid this, when we replace a variable reference with
a register, we check that the move instruction is in fact
the same as used in the initial load (which is based
on variable type only), and replace the instruction with
a full register move (AMOV).
The peephole optimizer then is able to eleminate these
instruction giving way better code.
Diffstat (limited to 'sys/src/cmd/7c')
-rw-r--r-- | sys/src/cmd/7c/peep.c | 35 | ||||
-rw-r--r-- | sys/src/cmd/7c/reg.c | 17 |
2 files changed, 43 insertions, 9 deletions
diff --git a/sys/src/cmd/7c/peep.c b/sys/src/cmd/7c/peep.c index 8d07cfcc9..92c12399e 100644 --- a/sys/src/cmd/7c/peep.c +++ b/sys/src/cmd/7c/peep.c @@ -57,8 +57,9 @@ loop1: excise(r); t++; } - } - if(p->as == ASXTW){ + } else + if(p->as == ASXTW + && regtyp(&p->from) && regtyp(&p->to)){ r1 = findpre(r, &p->from); if(r1 != R){ p1 = r1->prog; @@ -68,11 +69,22 @@ loop1: case AMOVH: case AMOVHU: case AMOVW: - p->as = AMOVW; + if(p1->to.type == p->from.type) + p->as = AMOVW; break; } } + } else + if((p->as == AMOVB || p->as == AMOVBU || p->as == AMOVH || p->as == AMOVHU || p->as == AMOVWU) + && regtyp(&p->from) && regtyp(&p->to)){ + r1 = findpre(r, &p->from); + if(r1 != R){ + p1 = r1->prog; + if(p1->as == p->as && p1->to.type == p->from.type) + p->as = AMOV; + } } + if(p->as == AMOV || p->as == AMOVW || p->as == AFMOVS || p->as == AFMOVD) if(regtyp(&p->to)) { if(p->from.type == D_CONST) @@ -441,7 +453,12 @@ subprop(Reg *r0) case AFSQRTD: case AFMOVS: case AFMOVD: + case AMOVB: + case AMOVBU: + case AMOVH: + case AMOVHU: case AMOVW: + case AMOVWU: case AMOV: case ASXTW: if(p->to.type == v1->type) @@ -541,12 +558,12 @@ copy1(Adr *v1, Adr *v2, Reg *r, int f) switch(t) { case 2: /* rar, cant split */ if(debug['P']) - print("; %Drar; return 0\n", v2); + print("; %D rar; return 0\n", v2); return 0; case 3: /* set */ if(debug['P']) - print("; %Dset; return 1\n", v2); + print("; %D set; return 1\n", v2); return 1; case 1: /* used, substitute */ @@ -555,9 +572,9 @@ copy1(Adr *v1, Adr *v2, Reg *r, int f) if(!debug['P']) return 0; if(t == 4) - print("; %Dused+set and f=%d; return 0\n", v2, f); + print("; %D used+set and f=%d; return 0\n", v2, f); else - print("; %Dused and f=%d; return 0\n", v2, f); + print("; %D used and f=%d; return 0\n", v2, f); return 0; } if(copyu(p, v2, v1)) { @@ -569,7 +586,7 @@ copy1(Adr *v1, Adr *v2, Reg *r, int f) print("; sub%D/%D", v2, v1); if(t == 4) { if(debug['P']) - print("; %Dused+set; return 1\n", v2); + print("; %D used+set; return 1\n", v2); return 1; } break; @@ -579,7 +596,7 @@ copy1(Adr *v1, Adr *v2, Reg *r, int f) if(!f && (t == 2 || t == 3 || t == 4)) { f = 1; if(debug['P']) - print("; %Dset and !f; f=%d", v1, f); + print("; %D set and !f; f=%d", v1, f); } } if(debug['P']) diff --git a/sys/src/cmd/7c/reg.c b/sys/src/cmd/7c/reg.c index d992ba8f9..af40accbb 100644 --- a/sys/src/cmd/7c/reg.c +++ b/sys/src/cmd/7c/reg.c @@ -1058,9 +1058,26 @@ paint3(Reg *r, int bn, long rb, int rn) p = r->prog; if(r->use1.b[z] & bb) { + int et = var[bn].etype; + if(debug['R']) print("%P", p); addreg(&p->from, rn); + + /* + * avoid type converting move instructions when variable type matches. + * the register is already loaded with the correct type conversion + * and type conversing move instructions prevent the peephole optimizer + * from eleminating redundant moves. + */ + if(p->as == AMOVB && et == TCHAR + || p->as == AMOVBU && et == TUCHAR + || p->as == AMOVH && et == TSHORT + || p->as == AMOVHU && et == TUSHORT + || p->as == AMOVW && (et == TLONG || et == TINT) + || p->as == AMOVWU && (et == TULONG || et == TUINT)) + p->as = AMOV; + if(debug['R']) print("\t.c%P\n", p); } |