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 */
72 for(r=firstr; r!=R; r=r->link) {
77 if(regtyp(&p->from)) {
82 if(subprop(r) && copyprop(r)) {
97 if(p->as == p1->as && p->to.type == p1->from.type)
109 && p1->to.type == p->to.type
110 && p1->from.type-D_INDIR == p->to.type
111 && p1->from.index == D_NONE
112 && p1->from.offset == 0){
123 if(p->from.type != D_CONST || needc(p->link))
125 if(p->from.offset == -1){
130 p->from = zprog.from;
132 else if(p->from.offset == 1){
137 p->from = zprog.from;
142 if(p->from.type != D_CONST || needc(p->link))
144 if(p->from.offset == -1) {
149 p->from = zprog.from;
151 else if(p->from.offset == 1){
156 p->from = zprog.from;
161 if(p->to.type != D_CONST || p->to.offset != 0 || regtyp(&p->from) == 0)
163 if(p->link == P || (p->link->as != AJEQ && p->link->as != AJNE))
166 while(r1 != R && r1->prog->as == ANOP)
168 if(r1 == R || r1->prog->to.type != p->from.type)
176 /* shift doesnt affect ZF when shift count is zero */
177 if(p1->from.type != D_CONST || p1->from.offset == 0)
205 p->from = zprog.from;
217 if(r1 == R || r1->p2link != R)
247 if(t >= D_AX && t <= D_DI)
253 * the idea is to substitute
254 * one register for another
255 * from one MOV to another
257 * ADD b, R0 / no use of R1
259 * would be converted to
263 * hopefully, then the former or latter MOV
264 * will be eliminated by copy propagation.
281 for(r=uniqp(r0); r!=R; r=uniqp(r)) {
288 if(p->to.type != D_NONE)
337 if(p->from.type == D_CX && v1->type == D_CX)
352 * MOV R2, R1 / no use for R1
354 if(p->to.type == v1->type && p->from.type == v2->type){
355 copysub(&p->from, v2, v1, 1);
361 if(p->to.type == v1->type)
365 if(copyau(&p->from, v2) ||
368 if(copysub(&p->from, v1, v2, 0) ||
369 copysub(&p->to, v1, v2, 0))
375 copysub(&p->to, v1, v2, 1);
377 print("gotit: %D->%D\n%P", v1, v2, r->prog);
378 if(p->from.type == v2->type)
382 for(r=uniqs(r); r!=r0; r=uniqs(r)) {
384 copysub(&p->from, v1, v2, 1);
385 copysub(&p->to, v1, v2, 1);
387 print("%P\n", r->prog);
393 print("%P last\n", r->prog);
398 * The idea is to remove redundant copies.
407 * set v2 return success
421 for(r=firstr; r!=R; r=r->link)
423 return copy1(v1, v2, r0->s1, 0);
427 copy1(Adr *v1, Adr *v2, Reg *r, int f)
434 print("act set; return 1\n");
439 print("copy %D->%D f=%d\n", v1, v2, f);
440 for(; r != R; r = r->s1) {
444 if(!f && uniqp(r) == R) {
447 print("; merge; f=%d", f);
451 case 2: /* rar, cant split */
453 print("; %D rar; return 0\n", v2);
458 print("; %D set; return 1\n", v2);
461 case 1: /* used, substitute */
462 case 4: /* use and set */
467 print("; %D used+set and f=%d; return 0\n", v2, f);
469 print("; %D used and f=%d; return 0\n", v2, f);
472 if(copyu(p, v2, v1)) {
474 print("; sub fail; return 0\n");
478 print("; sub %D/%D", v2, v1);
481 print("; %D used+set; return 1\n", v2);
488 if(!f && (t == 2 || t == 3 || t == 4)) {
491 print("; %D set and !f; f=%d", v1, f);
497 if(!copy1(v1, v2, r->s2, f))
505 * 1 if v only used (and substitute),
506 * 2 if read-alter-rewrite
509 * 0 otherwise (not touched)
512 copyu(Prog *p, Adr *v, Adr *s)
519 print("unknown op %A\n", p->as);
528 if(copyas(&p->to, v))
532 case ALEAL: /* lhs addr, rhs store */
533 if(copyas(&p->from, v))
537 case ANOP: /* rhs store */
543 if(copyas(&p->to, v)) {
545 return copysub(&p->from, v, s, 1);
546 if(copyau(&p->from, v))
570 if(copyas(&p->to, v))
572 if(copyas(&p->from, v))
573 if(p->from.type == D_CX)
577 case AADDB: /* rhs rar */
643 if(copyas(&p->to, v))
647 case ACMPL: /* read only */
667 if(copysub(&p->from, v, s, 1))
669 return copysub(&p->to, v, s, 1);
671 if(copyau(&p->from, v))
673 if(copyau(&p->to, v))
677 case AJGE: /* no reference */
697 if(p->to.type != D_NONE) {
698 if(copyas(&p->to, v))
716 if(v->type == D_AX || v->type == D_DX)
728 if(v->type == D_DI || v->type == D_SI)
734 if(v->type == D_AX || v->type == D_DI)
743 case AJMP: /* funny */
745 if(copysub(&p->to, v, s, 1))
749 if(copyau(&p->to, v))
753 case ARET: /* funny */
754 if(v->type == REGRET)
760 case ACALL: /* funny */
761 if(REGARG>=0 && v->type == REGARG)
765 if(copysub(&p->to, v, s, 1))
769 if(copyau(&p->to, v))
778 * could be set/use depending on
782 copyas(Adr *a, Adr *v)
784 if(a->type != v->type)
788 if(v->type == D_AUTO || v->type == D_PARAM)
789 if(v->offset == a->offset)
795 * either direct or indirect
798 copyau(Adr *a, Adr *v)
804 if(a->type-D_INDIR == v->type)
806 if(a->index == v->type)
813 * substitute s for v in a
814 * return failure to substitute
817 copysub(Adr *a, Adr *v, Adr *s, int f)
823 if(t >= D_AX && t <= D_DI) {
831 if(a->type == t+D_INDIR) {
832 if(s->type == D_BP && a->index != D_NONE)
833 return 1; /* can't use BP-base with index */
835 a->type = s->type+D_INDIR;