📄 peep.c
字号:
#include "gc.h"voidpeep(void){ Reg *r, *r1, *r2; Prog *p, *p1; int t, s;/* * complete R structure */ t = 0; for(r=firstr; r!=R; r=r1) { r1 = r->link; if(r1 == R) break; p = r->prog->link; while(p != r1->prog) switch(p->as) { default: r2 = rega(); r->link = r2; r2->link = r1; r2->prog = p; r2->p1 = r; r->s1 = r2; r2->s1 = r1; r1->p1 = r2; r = r2; t++; case ADATA: case AGLOBL: case ANAME: case ASIGNAME: p = p->link; } }loop1: /* * propigate move's by renaming */ t = 0; for(r=firstr; r!=R; r=r->link) { p = r->prog; if(p->as == AMOVL || p->as == AFMOVEF || p->as == AFMOVED) if(regtyp(p->from.type)) if(anyvar(&p->to)) { if(copyprop(r)) { excise(r); t++; } else if(subprop(r) && copyprop(r)) { excise(r); t++; } } } if(t) goto loop1; for(r=firstr; r!=R; r=r->link) { p = r->prog; /* * convert (A) ... A++ into (A)++ * and A-- ... (A) into --(A) */ t = aregind(&p->from); if(t == D_NONE) goto out1; s = asize(p->as); if(s == 0) goto out1; r1 = findop(r, t, AADDL, s); if(r1 != R) { if(usedin(t, &p->to)) goto out1; p->from.type += I_INDINC - I_INDIR; excise(r1); goto out1; } r1 = findop(r, t, ASUBL, s); if(r1 != R) { p->from.type += I_INDDEC - I_INDIR; excise(r1); } out1: t = aregind(&p->to); if(t == D_NONE) goto out2; s = asize(p->as); if(s == 0) goto out2; r1 = findop(r, t, AADDL, s); if(r1 != R) { p->to.type += I_INDINC - I_INDIR; excise(r1); goto out2; } r1 = findop(r, t, ASUBL, s); if(r1 != R) { if(usedin(t, &p->from)) goto out2; p->to.type += I_INDDEC - I_INDIR; excise(r1); } out2: /* * get rid of unneeded save/restore CCR */ if(p->from.type == D_CCR) { r1 = findccr(r); if(r1 != R) { excise(r); excise(r1); } } switch(p->as) { case ATSTB: case ATSTW: case ATSTL: if(findtst(r, r->prog, 0)) excise(r); } /* * turn TSTB (A); BLT; ORB $128,(A) into TAS (A); BLT; NOP */ if(p->as == ATSTB && (r1 = r->s1)) { if((r1->prog->as == ABLT && (r2 = r1->s1)) || (r1->prog->as == ABGE && (r2 = r1->s2))) { p1 = r2->prog; if(p1->as == AORB) if(p1->from.type == D_CONST) if(p1->from.offset == 128) if(r1 == uniqp(r2)) if(tasas(&p->to, &p1->to)) { p->as = ATAS; excise(r2); } } } }}voidexcise(Reg *r){ p = r->prog; p->as = ANOP; p->from = zprog.from; p->to = zprog.to;}Reg*uniqp(Reg *r){ Reg *r1; r1 = r->p1; if(r1 == R) { r1 = r->p2; if(r1 == R || r1->p2link != R) return R; } else if(r->p2 != R) return R; return r1;}Reg*uniqs(Reg *r){ Reg *r1; r1 = r->s1; if(r1 == R) { r1 = r->s2; if(r1 == R) return R; } else if(r->s2 != R) return R; return r1;}/* * chase backward all cc setting. * returns 1 if all set same. */intfindtst(Reg *r0, Prog *rp, int n){ Reg *r; int c;loop: n++; if(n >= 10) return 0; for(r=r0->p2; r!=R; r=r->p2link) { c = setcc(r->prog, rp); if(c > 0) continue; if(c == 0) return 0; if(findtst(r, rp, n) == 0) return 0; } r = r0->p1; if(r == R) return 1; c = setcc(r->prog, rp); if(c > 0) return 1; if(c == 0) return 0; r0 = r; goto loop;}/* * tests cc * returns -1 if no change * returns 1 if set the same * returns 0 if set different */intsetcc(Prog *p, Prog *rp){ int s; s = asize(rp->as); switch(p->as) { default: if(debug['P']) print("unknown setcc %A\n", p->as); break; case ACMPB: case ACMPW: case ACMPL: case ABSR: return 0; case ABRA: case ABGE: case ABNE: case ABLE: case ABEQ: case ABHI: case ABLS: case ABMI: case ABPL: case ABGT: case ABLT: case ABCC: case ABCS: case APEA: case ALEA: case ANOP: case AFADDD: case AFMULD: case AFDIVD: case AFSUBD: case AFADDF: case AFMULF: case AFDIVF: case AFSUBF: case AADJSP: return -1; case AADDW: case AADDL: case ASUBW: case ASUBL: case ACLRL: case ACLRW: if(p->to.type >= D_A0 && p->to.type < D_A0+8) goto areg; case AADDB: case ASUBB: case AANDB: case AANDW: case AANDL: case AORB: case AORW: case AORL: case AEORB: case AEORW: case AEORL: case ALSLB: case ALSLW: case ALSLL: case ALSRB: case ALSRW: case ALSRL: case AASLB: case AASLW: case AASLL: case AASRB: case AASRW: case AASRL: case ATSTB: case ATSTW: case ATSTL: case ANEGB: case ANEGW: case ANEGL: case ACLRB: if(asize(p->as) != s) break; if(compat(&rp->to, &p->to)) return 1; break; case AMOVW: case AMOVL: if(p->to.type >= D_A0 && p->to.type < D_A0+8) goto areg; case AMOVB: if(asize(p->as) != s) break; if(compat(&rp->to, &p->to)) return 1; if(compat(&rp->to, &p->from)) return 1; } return 0;areg: if((rp->to.type&D_MASK) == p->to.type) return 0; return -1;}intcompat(Adr *a, Adr *b){ int o; o = a->type; if((o >= D_R0 && o < D_R0+NREG) || (o >= D_A0 && o < D_A0+NREG)) return o == b->type; o &= D_MASK; if(o >= D_A0 && o < D_A0+NREG) { if(o != (b->type&D_MASK)) return 0; if(a->offset != b->offset) return 0; o = a->type & I_MASK; if(o == I_INDIR) { o = b->type & I_MASK; if(o == I_INDIR || o == I_INDDEC) return 1; return 0; } if(o == I_INDINC) { o = b->type & I_MASK; if(o == I_INDIR) { b->type += I_INDINC-I_INDIR; return 1; } if(o == I_INDDEC) { b->type += I_INDIR-I_INDDEC; return 1; } return 0; } } return 0;}intaregind(Adr *a){ int t; t = a->type; if(t >= (D_A0|I_INDIR) && t < ((D_A0+NREG)|I_INDIR)) while(a->offset == 0) return t & D_MASK; return D_NONE;}intasize(int a){ switch(a) { case AFTSTD: case AFMOVED: case AFADDD: case AFSUBD: case AFMULD: case AFDIVD: case AFCMPD: case AFNEGD: return 8; case AFTSTF: case AFMOVEF: case AFADDF: case AFSUBF: case AFMULF: case AFDIVF: case AFCMPF: case AFNEGF: case ACLRL: case ATSTL: case AMOVL: case AADDL: case ASUBL: case ACMPL: case AANDL: case AORL: case AEORL: case ALSLL: case ALSRL: case AASLL: case AASRL: case ANEGL: return 4; case ACLRW: case ATSTW: case AMOVW: case AADDW: case ASUBW: case ACMPW: case AANDW: case AORW: case AEORW: case ALSLW: case ALSRW: case AASLW: case AASRW: case ANEGW: return 2; case ACLRB: case ATSTB: case AMOVB: case AADDB: case ASUBB: case ACMPB: case AANDB: case AORB: case AEORB: case ALSLB: case ALSRB: case AASLB: case AASRB: case ANEGB: return 1; } if(debug['P']) print("unknown asize %A\n", p->as); return 0;}intusedin(int t, Adr *a){ if((a->type&D_MASK) == t) return 1; return 0;}Reg*findccr(Reg *r){ Prog *p; for(;;) { r = uniqs(r); if(r == R) break; p = r->prog; if(p->to.type == D_CCR) return r; if(setccr(p)) break; } return R;}intsetccr(Prog *p){ switch(p->as) { case ANOP: return 0; case AADDL: case AMOVL: case ACLRL: if(p->to.type >= D_A0 && p->to.type < D_A0+8) return 0; } return 1;}Reg*findop(Reg *r, int t, int o, int s){ Prog *p; Reg *r1; for(;;) { if(o == AADDL) { r1 = uniqs(r); if(r1 == R) break; if(uniqp(r1) != r) break; } else { r1 = uniqp(r); if(r1 == R) break; if(uniqs(r1) != r)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -