Subject: C optimizer fixes Index: lib/c2/c21.c 2.11BSD Description: The C optimizer misses some easy optimizations. In particular double 'tst' instructions are not reduced to a single 'tst' and the condition codes are not paid attention to when set by instructions such as 'add', 'sub', 'inc', 'bic', etc. Repeat-By: Compile the following test program and examine the generated code. Annontated generated code is included. int x, y; main() { if (x > 3 * y / 2) exit(); x += y; if (x) exit(); x &= 7; if (x) exit(); } /* generated code from above program */ _main: jsr r5,csv mov _y,r1 mul $3,r1 tst r1 tst r1 <----- redundant 'tst' sxt r0 div $2,r0 cmp _x,r0 jle L4 jsr pc,_exit L4: add _y,_x tst _x <----- unneeded 'tst'. the 'add' just above sets the condition codes - an explicit 'tst' is not necessary. jeq L5 jsr pc,_exit L5: bic $-10,_x tst _x <----- another example of an extra 'tst'. 'bic' sets the condition codes - an explicit 'tst' is not needed. jeq L3 jsr pc,_exit L3: jmp cret Fix: Apply the patch below, recompile and install 'c2'. Testing has been quite thorough, including a recompile of /lib/libc.a and the kernel - no problems have been encountered. -------------------------------------------------------------------------- *** c21.c.old Tue Oct 21 01:23:50 1986 --- c21.c Fri Oct 4 08:39:10 1991 *************** *** 94,100 **** dest(regs[RT2], flt); if (p->op==DIV && (r = isreg(regs[RT2])>=0)) regs[r+1][0] = 0; ! ccloc[0] = 0; continue; case CLRF: --- 94,111 ---- dest(regs[RT2], flt); if (p->op==DIV && (r = isreg(regs[RT2])>=0)) regs[r+1][0] = 0; ! switch (p->op) ! { ! case ADD: ! case SUB: ! case BIC: ! case BIS: ! case ASH: ! setcc(regs[RT2]); ! break; ! default: ! ccloc[0] = 0; ! } continue; case CLRF: *************** *** 113,123 **** sngl: dest(regs[RT1], flt); if (p->op==CLR && flt==0) if ((r = isreg(regs[RT1])) >= 0) savereg(r, "$0"); else setcon("$0", regs[RT1]); ! ccloc[0] = 0; continue; case TSTF: --- 124,138 ---- sngl: dest(regs[RT1], flt); if (p->op==CLR && flt==0) + { if ((r = isreg(regs[RT1])) >= 0) savereg(r, "$0"); else setcon("$0", regs[RT1]); ! ccloc[0] = 0; ! } ! else ! setcc(regs[RT1]); continue; case TSTF: *************** *** 134,139 **** --- 149,156 ---- nrtst++; nchange++; } + else + setcc(regs[RT1]); /* XXX - double TST in a row */ continue; case CMPF: *************** *** 328,333 **** --- 345,351 ---- } abs(x) + register int x; { return(x<0? -x: x); } *************** *** 367,373 **** struct node * nonlab(p) ! struct node *p; { CHECK(10); while (p && p->op==LABEL) --- 385,391 ---- struct node * nonlab(p) ! register struct node *p; { CHECK(10); while (p && p->op==LABEL) *************** *** 782,788 **** equstr(ap1, ap2) char *ap1, *ap2; { ! char *p1, *p2; p1 = ap1; p2 = ap2; --- 800,806 ---- equstr(ap1, ap2) char *ap1, *ap2; { ! register char *p1, *p2; p1 = ap1; p2 = ap2;