19 if(p->to.type == D_BRANCH)
35 * complete R structure
38 for(r=firstr; r!=R; r=r1) {
67 pc = 0; /* speculating it won't kill */
74 for(r=firstr; r!=R; r=r->link) {
79 if(regtyp(&p->from)) {
84 if(subprop(r) && copyprop(r)) {
99 if(p->as == p1->as && p->to.type == p1->from.type)
106 if(p->from.type != D_CONST || needc(p->link))
108 if(p->from.offset == -1){
113 p->from = zprog.from;
115 else if(p->from.offset == 1){
120 p->from = zprog.from;
125 if(p->from.type != D_CONST || needc(p->link))
127 if(p->from.offset == -1) {
132 p->from = zprog.from;
134 else if(p->from.offset == 1){
139 p->from = zprog.from;
155 p->from = zprog.from;
167 if(r1 == R || r1->p2link != R)
197 if(t >= D_AX && t <= D_DI)
203 * the idea is to substitute
204 * one register for another
205 * from one MOV to another
207 * ADD b, R0 / no use of R1
209 * would be converted to
213 * hopefully, then the former or latter MOV
214 * will be eliminated by copy propagation.
231 for(r=uniqp(r0); r!=R; r=uniqp(r)) {
241 if(p->to.type != D_NONE)
285 if(p->to.type == v1->type)
289 if(copyau(&p->from, v2) ||
292 if(copysub(&p->from, v1, v2, 0) ||
293 copysub(&p->to, v1, v2, 0))
299 copysub(&p->to, v1, v2, 1);
301 print("gotit: %D->%D\n%P", v1, v2, r->prog);
302 if(p->from.type == v2->type)
306 for(r=uniqs(r); r!=r0; r=uniqs(r)) {
308 copysub(&p->from, v1, v2, 1);
309 copysub(&p->to, v1, v2, 1);
311 print("%P\n", r->prog);
317 print("%P last\n", r->prog);
322 * The idea is to remove redundant copies.
331 * set v2 return success
345 for(r=firstr; r!=R; r=r->link)
347 return copy1(v1, v2, r0->s1, 0);
351 copy1(Adr *v1, Adr *v2, Reg *r, int f)
358 print("act set; return 1\n");
363 print("copy %D->%D f=%d\n", v1, v2, f);
364 for(; r != R; r = r->s1) {
368 if(!f && uniqp(r) == R) {
371 print("; merge; f=%d", f);
375 case 2: /* rar, cant split */
377 print("; %D rar; return 0\n", v2);
382 print("; %D set; return 1\n", v2);
385 case 1: /* used, substitute */
386 case 4: /* use and set */
391 print("; %D used+set and f=%d; return 0\n", v2, f);
393 print("; %D used and f=%d; return 0\n", v2, f);
396 if(copyu(p, v2, v1)) {
398 print("; sub fail; return 0\n");
402 print("; sub %D/%D", v2, v1);
405 print("; %D used+set; return 1\n", v2);
412 if(!f && (t == 2 || t == 3 || t == 4)) {
415 print("; %D set and !f; f=%d", v1, f);
421 if(!copy1(v1, v2, r->s2, f))
429 * 1 if v only used (and substitute),
430 * 2 if read-alter-rewrite
433 * 0 otherwise (not touched)
436 copyu(Prog *p, Adr *v, Adr *s)
443 print("unknown op %A\n", p->as);
452 if(copyas(&p->to, v))
456 case ALEAL: /* lhs addr, rhs store */
457 if(copyas(&p->from, v))
461 case ANOP: /* rhs store */
467 if(copyas(&p->to, v)) {
469 return copysub(&p->from, v, s, 1);
470 if(copyau(&p->from, v))
494 if(copyas(&p->to, v))
496 if(copyas(&p->from, v))
497 if(p->from.type == D_CX)
501 case AADDB: /* rhs rar */
567 if(copyas(&p->to, v))
571 case ACMPL: /* read only */
591 if(copysub(&p->from, v, s, 1))
593 return copysub(&p->to, v, s, 1);
595 if(copyau(&p->from, v))
597 if(copyau(&p->to, v))
601 case AJGE: /* no reference */
621 if(p->to.type != D_NONE) {
622 if(copyas(&p->to, v))
640 if(v->type == D_AX || v->type == D_DX)
647 if(v->type == D_CX || v->type == D_DI || v->type == D_SI)
656 case AJMP: /* funny */
658 if(copysub(&p->to, v, s, 1))
662 if(copyau(&p->to, v))
666 case ARET: /* funny */
667 if(v->type == REGRET)
673 case ACALL: /* funny */
674 if(REGARG>=0 && v->type == REGARG)
678 if(copysub(&p->to, v, s, 1))
682 if(copyau(&p->to, v))
691 * could be set/use depending on
695 copyas(Adr *a, Adr *v)
697 if(a->type != v->type)
701 if(v->type == D_AUTO || v->type == D_PARAM)
702 if(v->offset == a->offset)
708 * either direct or indirect
711 copyau(Adr *a, Adr *v)
717 if(a->type-D_INDIR == v->type)
719 if(a->index == v->type)
726 * substitute s for v in a
727 * return failure to substitute
730 copysub(Adr *a, Adr *v, Adr *s, int f)
736 if(t >= D_AX && t <= D_DI) {
744 if(a->type == t+D_INDIR) {
745 if(s->type == D_BP && a->index != D_NONE)
746 return 1; /* can't use BP-base with index */
748 a->type = s->type+D_INDIR;