📄 peep.c
字号:
break; } r = r1; p = r->prog; if(usedin(t, &p->from)) break; if(usedin(t, &p->to)) { if(p->as == o) if(p->to.type == t) if(p->from.type == D_CONST) if(p->from.offset == s) return r; break; } } return R;}intregtyp(int t){ if(t >= D_R0 && t < D_R0+8) return 1; if(t >= D_A0 && t < D_A0+8) return 1; if(t >= D_F0 && t < D_F0+8) return 1; return 0;}intanyvar(Adr *a){ if(regtyp(a->type)) return 1; return 0;}/* * the idea is to substitute * one register for another * from one MOV to another * MOV a, R0 * ADD b, R0 / no use of R1 * MOV R0, R1 * would be converted to * MOV a, R1 * ADD b, R1 * MOV R1, R0 * hopefully, then the former or latter MOVL * will be eliminated by copy propagation. */intsubprop(Reg *r0){ Prog *p; Adr *v1, *v2; Reg *r; int t; p = r0->prog; v1 = &p->from; if(!regtyp(v1->type)) return 0; v2 = &p->to; if(!regtyp(v2->type)) return 0; for(r=uniqp(r0); r!=R; r=uniqp(r)) { if(uniqs(r) == R) break; p = r->prog; switch(p->as) { case ADIVUW: /* these set Rn and Rn+1 */ case ADIVUL: case ADIVSW: case ADIVSL: case ABSR: return 0; case AFMOVED: case AFMOVEF: case AMOVL: if(p->to.type == v1->type) goto gotit; } if(copyau(&p->from, v2) || copyau(&p->to, v2)) break; if(copysub(&p->from, v1, v2, p, 0) || copysub(&p->to, v1, v2, p, 0)) break; } return 0;gotit: copysub(&p->to, v1, v2, p, 1); if(debug['P']) { print("gotit: %D->%D\n%P", v1, v2, r->prog); if(p->from.type == v2->type) print(" excise"); print("\n"); } if(p->from.type == v2->type) excise(r); for(r=uniqs(r); r!=r0; r=uniqs(r)) { p = r->prog; copysub(&p->from, v1, v2, p, 1); copysub(&p->to, v1, v2, p, 1); if(debug['P']) print("%P\n", r->prog); } t = v1->type; v1->type = v2->type; v2->type = t; if(debug['P']) print("%P last\n", r->prog); return 1;}/* * The idea is to remove redundant copies. * v1->v2 F=0 * (use v2 s/v2/v1/)* * set v1 F=1 * use v2 return fail * ----------------- * v1->v2 F=0 * (use v2 s/v2/v1/)* * set v1 F=1 * set v2 return success */intcopyprop(Reg *r0){ Prog *p; Adr *v1, *v2; Reg *r; p = r0->prog; v1 = &p->from; v2 = &p->to; if(copyas(v1, v2)) return 1; for(r=firstr; r!=R; r=r->link) r->active = 0; return copy1(v1, v2, r0->s1, 0);}intcopy1(Adr *v1, Adr *v2, Reg *r, int f){ int t; if(r->active) { if(debug['P']) print("copyret 1\n"); return 1; } r->active = 1; if(debug['P']) print("copy %D->%D\n", v1, v2); for(; r != R; r = r->s1) { if(debug['P']) print("%P", r->prog); if(!f && uniqp(r) == R) { f = 1; if(debug['P']) print("; merge; f=%d", f); } t = copyu(r->prog, v2, A); switch(t) { case 2: /* rar, cant split */ if(debug['P']) print("; rar return 0\n"); return 0; case 3: /* set */ if(debug['P']) print("; set; return 1\n"); return 1; case 1: /* used, substitute */ case 4: /* use and set */ if(f) { if(debug['P']) print("; used and f; return 0\n"); return 0; } if(copyu(r->prog, v2, v1)) { if(debug['P']) print("; sub fail; return 0\n"); return 0; } if(debug['P']) print("; substitute"); if(t == 4) { if(debug['P']) print("; used and set; return 1\n"); return 1; } break; } if(!f) { t = copyu(r->prog, v1, A); if(!f && (t == 2 || t == 3 || t == 4)) { if(debug['P']) print("; f set used"); f = 1; } } if(debug['P']) print("\n"); if(r->s2) if(!copy1(v1, v2, r->s2, f)) return 0; } return 1;}/* * return * 1 if v only used (and substitute), * 2 if read-alter-rewrite * 3 if set * 4 if set and used * 0 otherwise (not touched) */intcopyu(Prog *p, Adr *v, Adr *s){ int t; switch(p->as) { default: if(debug['P']) print("unknown op %A\n", p->as); return 2; case APEA: /* rhs addr */ if(copyas(&p->to, v)) return 2; goto caseread; case ALEA: /* lhs addr, rhs store */ if(copyas(&p->from, v)) return 2; case AMOVL: /* rhs store */ case ACLRL: case AFMOVEF: case AFMOVED: case AFMOVEB: case AFMOVEW: case AFMOVEL: case ANOP: if(copyas(&p->to, v)) { if(s != A) return copysub(&p->from, v, s, p, 1); if(copyau(&p->from, v)) return 4; return 3; } goto caseread; case AADDL: /* rhs rar */ case AADDW: case AADDB: case ASUBL: case ASUBW: case ASUBB: case AANDL: case AANDW: case AANDB: case AORL: case AORW: case AORB: case AEORL: case AEORW: case AEORB: case AASRL: case AASRW: case AASRB: case AASLL: case AASLW: case AASLB: case ALSRL: case ALSRW: case ALSRB: case ANOTL: case ANOTW: case ANOTB: case ANEGL: case ANEGW: case ANEGB: case AEXTBL: case AEXTWL: case AEXTBW: case AMULSL: case AMULUL: case AMOVW: /* only sets part of register */ case AMOVB: case ACLRW: case ACLRB: case AFADDD: case AFMULD: case AFDIVD: case AFSUBD: case AFNEGD: case AFADDF: case AFMULF: case AFDIVF: case AFSUBF: case AFNEGF: if(copyas(&p->to, v)) return 2; goto caseread; case ADBF: /* lhs rar */ if(copyas(&p->from, v)) return 2; goto caseread; case ACMPL: /* read only */ case ACMPW: case ACMPB: case AFCMPF: case AFCMPD: case ATSTL: case ATSTW: case ATSTB: case AFTSTF: case AFTSTD: caseread: if(s != A) { if(copysub(&p->from, v, s, p, 1)) return 1; return copysub(&p->to, v, s, p, 1); } if(copyau(&p->from, v)) return 1; if(copyau(&p->to, v)) return 1; break; case ABRA: /* no reference */ 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 AFBEQ: case AFBNE: case AFBGT: case AFBGE: case AFBLE: case AFBLT: case AADJSP: case ACASEW: break; case ADIVUW: /* these set Rn and Rn+1 */ case ADIVUL: case ADIVSW: case ADIVSL: t = v->type; if(t == p->to.type || t == p->to.type+1) return 2; goto caseread; case ARTS: /* funny */ t = v->type; if(t == D_R0 || t == D_F0) return 2; if(t >= D_R0 && t < D_R0+NREG) if(t-D_R0 > exregoffset) return 2; if(t >= D_A0 && t < D_A0+NREG) if(t-D_A0 > exaregoffset) return 2; if(t >= D_F0 && t < D_F0+NREG) if(t-D_F0 > exfregoffset) return 2; return 3; case ABSR: /* funny */ t = v->type; if(t >= D_R0 && t < D_R0+NREG) if(t-D_R0 > exregoffset) return 2; if(t >= D_A0 && t < D_A0+NREG) if(t-D_A0 > exaregoffset) return 2; if(t >= D_F0 && t < D_F0+NREG) if(t-D_F0 > exfregoffset) return 2; if(copyau(&p->to, v)) return 2; return 3; } return 0;}/* * direct reference, * could be set/use depending on * semantics */intcopyas(Adr *a, Adr *v){ if(a->type != v->type) return 0; if(regtyp(v->type)) return 1; if(v->type == D_AUTO || v->type == D_PARAM) { if(v->offset == a->offset) return 1; return 0; } return 0;}/* * indirect */inttasas(Adr *a, Adr *v){ int t; t = a->type; if(t < I_INDIR+D_A0 && t >= I_INDIR+D_A0+8) return 0; if(v->type != t) return 0; if(a->displace != v->displace) return 0; return 1;}/* * either direct or indirect */intcopyau(Adr *a, Adr *v){ int t; if(copyas(a, v)) return 1; t = v->type; if(regtyp(t)) { if((a->type & D_MASK) == t) return 1; } return 0;}/* * substitute s for v in a * return failure to substitute */intcopysub(Adr *a, Adr *v, Adr *s, Prog *p, int f){ int t; if(copyas(a, v)) { t = s->type; if(t >= D_F0 && t < D_F0+8) { if(f) a->type = t; return 0; } if(t >= D_R0 && t < D_R0+8) { if(f) a->type = t; return 0; } if(!(t >= D_A0 && t < D_A0+8)) return 1; switch(p->as) { default: return 1; case AMOVL: case AMOVW: case ACMPL: case ACMPW: break; case AADDL: case AADDW: case ASUBL: case ASUBW: if(a == &p->from && !regtyp(p->to.type)) return 1; break; } if(f) a->type = t; return 0; } t = v->type; if(regtyp(t)) { if((a->type & D_MASK) == t) { if((s->type ^ t) & ~(NREG-1)) return 1; if(f) a->type = (a->type & ~D_MASK) | s->type; return 0; } return 0; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -