Research V5 development
authorDennis Ritchie <dmr@research.uucp>
Tue, 26 Nov 1974 23:13:21 +0000 (18:13 -0500)
committerDennis Ritchie <dmr@research.uucp>
Tue, 26 Nov 1974 23:13:21 +0000 (18:13 -0500)
Work on file usr/c/c20.c

Synthesized-from: v5

usr/c/c20.c [new file with mode: 0644]

diff --git a/usr/c/c20.c b/usr/c/c20.c
new file mode 100644 (file)
index 0000000..51f2c10
--- /dev/null
@@ -0,0 +1,639 @@
+#
+/*
+ *      C object code improver
+ *       Copyright 1974 Bell Telephone Laboratories, Incorporated
+ */
+
+#include "c2h.c"
+
+struct optab optab[] {
+       "jbr",  JBR,
+       "jeq",  CBR | JEQ<<8,
+       "jne",  CBR | JNE<<8,
+       "jle",  CBR | JLE<<8,
+       "jge",  CBR | JGE<<8,
+       "jlt",  CBR | JLT<<8,
+       "jgt",  CBR | JGT<<8,
+       "jlo",  CBR | JLO<<8,
+       "jhi",  CBR | JHI<<8,
+       "jlos", CBR | JLOS<<8,
+       "jhis", CBR | JHIS<<8,
+       "jmp",  JMP,
+       ".globl",EROU,
+       "mov",  MOV,
+       "clr",  CLR,
+       "com",  COM,
+       "inc",  INC,
+       "dec",  DEC,
+       "neg",  NEG,
+       "tst",  TST,
+       "asr",  ASR,
+       "asl",  ASL,
+       "sxt",  SXT,
+       "cmp",  CMP,
+       "add",  ADD,
+       "sub",  SUB,
+       "bit",  BIT,
+       "bic",  BIC,
+       "bis",  BIS,
+       "mul",  MUL,
+       "ash",  ASH,
+       "xor",  XOR,
+       ".text",TEXT,
+       ".data",DATA,
+       ".bss", BSS,
+       ".even",EVEN,
+       "movf", MOVF,
+       "movof",MOVOF,
+       "movfo",MOVFO,
+       "addf", ADDF,
+       "subf", SUBF,
+       "divf", DIVF,
+       "mulf", MULF,
+       "clrf", CLRF,
+       "cmpf", CMPF,
+       "negf", NEGF,
+       "tstf", TSTF,
+       "cfcc", CFCC,
+       "sob",  SOB,
+       "jsr",  JSR,
+       ".end", END,
+       0,      0};
+
+char   revbr[] { JNE, JEQ, JGT, JLT, JGE, JLE, JHIS, JLOS, JHI, JLO };
+int    isn     20000;
+
+main(argc, argv)
+char **argv;
+{
+       register int niter, maxiter, isend;
+       extern end;
+       extern fin, fout;
+       int nflag;
+
+       if (argc>1 && argv[1][0]=='+') {
+               argc--;
+               argv++;
+               debug++;
+       }
+       if (argc>1 && argv[1][0]=='-') {
+               argc--;
+               argv++;
+               nflag++;
+       }
+       if (argc>1) {
+               if ((fin = open(argv[1], 0)) < 0) {
+                       printf("C2: can't find %s\n", argv[1]);
+                       exit(1);
+               }
+       } else
+               fin = dup(0);
+       if (argc>2) {
+               if ((fout = creat(argv[2], 0666)) < 0) {
+                       fout = 1;
+                       printf("C2: can't create %s\n", argv[2]);
+                       exit(1);
+               }
+       } else
+               fout = dup(1);
+       lasta = firstr = lastr = sbrk(2);
+       maxiter = 0;
+       opsetup();
+       do {
+               isend = input();
+               movedat();
+               niter = 0;
+               do {
+                       refcount();
+                       do {
+                               iterate();
+                               clearreg();
+                               niter++;
+                       } while (nchange);
+                       comjump();
+                       rmove();
+               } while (nchange || jumpsw());
+               addsob();
+               output();
+               if (niter > maxiter)
+                       maxiter = niter;
+               lasta = firstr;
+       } while (isend);
+       flush();
+       fout = 2;
+       if (nflag) {
+               printf("%d iterations\n", maxiter);
+               printf("%d jumps to jumps\n", nbrbr);
+               printf("%d inst. after jumps\n", iaftbr);
+               printf("%d jumps to .+2\n", njp1);
+               printf("%d redundant labels\n", nrlab);
+               printf("%d cross-jumps\n", nxjump);
+               printf("%d code motions\n", ncmot);
+               printf("%d branches reversed\n", nrevbr);
+               printf("%d redundant moves\n", redunm);
+               printf("%d simplified addresses\n", nsaddr);
+               printf("%d loops inverted\n", loopiv);
+               printf("%d redundant jumps\n", nredunj);
+               printf("%d common seqs before jmp's\n", ncomj);
+               printf("%d skips over jumps\n", nskip);
+               printf("%d sob's added\n", nsob);
+               printf("%d redundant tst's\n", nrtst);
+               printf("%dK core\n", ((lastr+01777)>>10)&077);
+               flush();
+       }
+}
+
+input()
+{
+       register struct node *p, *lastp;
+       register int op;
+
+       lastp = &first;
+       for (;;) {
+               op = getline();
+               switch (op.op) {
+       
+               case LABEL:
+                       p = alloc(sizeof first);
+                       if (line[0] == 'L') {
+                               p->combop = LABEL;
+                               p->labno = getnum(line+1);
+                               p->code = 0;
+                       } else {
+                               p->combop = DLABEL;
+                               p->labno = 0;
+                               p->code = copy(line);
+                       }
+                       break;
+       
+               case JBR:
+               case CBR:
+               case JMP:
+               case JSW:
+                       p = alloc(sizeof first);
+                       p->combop = op;
+                       if (*curlp=='L' && (p->labno = getnum(curlp+1)))
+                               p->code = 0;
+                       else {
+                               p->labno = 0;
+                               p->code = copy(curlp);
+                       }
+                       break;
+
+               default:
+                       p = alloc(sizeof first);
+                       p->combop = op;
+                       p->labno = 0;
+                       p->code = copy(curlp);
+                       break;
+
+               }
+               p->forw = 0;
+               p->back = lastp;
+               lastp->forw = p;
+               lastp = p;
+               p->ref = 0;
+               if (op==EROU)
+                       return(1);
+               if (op==END)
+                       return(0);
+       }
+}
+
+getline()
+{
+       register char *lp;
+       register c;
+
+       lp = line;
+       while (c = getchar()) {
+               if (c==':') {
+                       *lp++ = 0;
+                       return(LABEL);
+               }
+               if (c=='\n') {
+                       *lp++ = 0;
+                       return(oplook());
+               }
+               *lp++ = c;
+       }
+       *lp++ = 0;
+       return(END);
+}
+
+getnum(ap)
+char *ap;
+{
+       register char *p;
+       register n, c;
+
+       p = ap;
+       n = 0;
+       while ((c = *p++) >= '0' && c <= '9')
+               n = n*10 + c - '0';
+       if (*--p != 0)
+               return(0);
+       return(n);
+}
+
+output()
+{
+       register struct node *t;
+       register struct optab *op;
+       register int byte;
+
+       t = &first;
+       while (t = t->forw) switch (t->op) {
+
+       case END:
+               return;
+
+       case LABEL:
+               printf("L%d:", t->labno);
+               continue;
+
+       case DLABEL:
+               printf("%s:", t->code);
+               continue;
+
+       default:
+               if ((byte = t->subop) == BYTE)
+                       t->subop = 0;
+               for (op = optab; op->opstring!=0; op++) 
+                       if (op->opcode == t->combop) {
+                               printf("%s", op->opstring);
+                               if (byte==BYTE)
+                                       printf("b");
+                               break;
+                       }
+               if (t->code)
+                       printf("\t%s\n", t->code);
+               else if (t->op==JBR || t->op==CBR)
+                       printf("\tL%d\n", t->labno);
+               else
+                       printf("\n");
+               continue;
+
+       case JSW:
+               printf("L%d\n", t->labno);
+               continue;
+
+       case SOB:
+               printf("sob     %s,L%d\n", t->code, t->labno);
+               continue;
+
+       case 0:
+               if (t->code)
+                       printf("%s", t->code);
+               printf("\n");
+               continue;
+       }
+}
+
+copy(ap)
+char *ap;
+{
+       register char *p, *np;
+       char *onp;
+       register n;
+       int na;
+
+       na = nargs();
+       p = ap;
+       n = 0;
+       if (*p==0)
+               return(0);
+       do
+               n++;
+       while (*p++);
+       if (na>1) {
+               p = (&ap)[1];
+               while (*p++)
+                       n++;
+       }
+       onp = np = alloc(n);
+       p = ap;
+       while (*np++ = *p++);
+       if (na>1) {
+               p = (&ap)[1];
+               np--;
+               while (*np++ = *p++);
+       }
+       return(onp);
+}
+
+opsetup()
+{
+       register struct optab *optp, **ophp;
+       register int *p;
+
+       for (optp = optab; p = optp->opstring; optp++) {
+               ophp = &ophash[((p[0]+p[1].lbyte)&077777) % OPHS];
+               while (*ophp++)
+                       if (ophp > &ophash[OPHS])
+                               ophp = ophash;
+               *--ophp = optp;
+       }
+}
+
+oplook()
+{
+       register struct optab *optp;
+       register char *lp, *op;
+       static char tmpop[32];
+       struct optab **ophp;
+
+       op = tmpop;
+       for (lp = line; *lp && *lp!=' ' && *lp!='\t';)
+               *op++ = *lp++;
+       *op++ = 0;
+       while (*lp=='\t' || *lp==' ')
+               lp++;
+       curlp = lp;
+       ophp = &ophash[((tmpop[0].int+tmpop[2])&077777) % OPHS];
+       while (optp = *ophp) {
+               op = optp->opstring;
+               lp = tmpop;
+               while (*lp == *op++)
+                       if (*lp++ == 0)
+                               return(optp->opcode);
+               if (*lp++=='b' && *lp++==0 && *--op==0)
+                       return(optp->opcode + (BYTE<<8));
+               ophp++;
+               if (ophp >= &ophash[OPHS])
+                       ophp = ophash;
+       }
+       if (line[0]=='L') {
+               lp = &line[1];
+               while (*lp)
+                       if (*lp<'0' || *lp++>'9')
+                               return(0);
+               curlp = line;
+               return(JSW);
+       }
+       curlp = line;
+       return(0);
+}
+
+refcount()
+{
+       register struct node *p, *lp;
+       static struct node *labhash[LABHS];
+       register struct node **hp;
+
+       for (hp = labhash; hp < &labhash[LABHS];)
+               *hp++ = 0;
+       for (p = first.forw; p!=0; p = p->forw)
+               if (p->op==LABEL) {
+                       labhash[p->labno % LABHS] = p;
+                       p->refc = 0;
+               }
+       for (p = first.forw; p!=0; p = p->forw) {
+               if (p->op==JBR || p->op==CBR || p->op==JSW) {
+                       p->ref = 0;
+                       lp = labhash[p->labno % LABHS];
+                       if (lp==0 || p->labno!=lp->labno)
+                       for (lp = first.forw; lp!=0; lp = lp->forw) {
+                               if (lp->op==LABEL && p->labno==lp->labno)
+                                       break;
+                       }
+                       if (lp) {
+                               hp = nonlab(lp)->back;
+                               if (hp!=lp) {
+                                       p->labno = hp->labno;
+                                       lp = hp;
+                               }
+                               p->ref = lp;
+                               lp->refc++;
+                       }
+               }
+       }
+       for (p = first.forw; p!=0; p = p->forw)
+               if (p->op==LABEL && p->refc==0
+                && (lp = nonlab(p))->op && lp->op!=JSW)
+                       decref(p);
+}
+
+iterate()
+{
+       register struct node *p, *rp, *p1;
+
+       nchange = 0;
+       for (p = first.forw; p!=0; p = p->forw) {
+               if ((p->op==JBR||p->op==CBR||p->op==JSW) && p->ref) {
+                       rp = nonlab(p->ref);
+                       if (rp->op==JBR && rp->labno) {
+                               nbrbr++;
+                               p->labno = rp->labno;
+                               decref(p->ref);
+                               rp->ref->refc++;
+                               p->ref = rp->ref;
+                               nchange++;
+                       }
+               }
+               if (p->op==CBR && (p1 = p->forw)->op==JBR) {
+                       rp = p->ref;
+                       do
+                               rp = rp->back;
+                       while (rp->op==LABEL);
+                       if (rp==p1) {
+                               decref(p->ref);
+                               p->ref = p1->ref;
+                               p->labno = p1->labno;
+                               p1->forw->back = p;
+                               p->forw = p1->forw;
+                               p->subop = revbr[p->subop];
+                               nchange++;
+                               nskip++;
+                       }
+               }
+               if (p->op==JBR || p->op==JMP) {
+                       while (p->forw && p->forw->op!=LABEL
+                               && p->forw->op!=EROU && p->forw->op!=END) {
+                               nchange++;
+                               iaftbr++;
+                               if (p->forw->ref)
+                                       decref(p->forw->ref);
+                               p->forw = p->forw->forw;
+                               p->forw->back = p;
+                       }
+                       rp = p->forw;
+                       while (rp && rp->op==LABEL) {
+                               if (p->ref == rp) {
+                                       p->back->forw = p->forw;
+                                       p->forw->back = p->back;
+                                       p = p->back;
+                                       decref(rp);
+                                       nchange++;
+                                       njp1++;
+                                       break;
+                               }
+                               rp = rp->forw;
+                       }
+                       xjump(p);
+                       p = codemove(p);
+               }
+       }
+}
+
+xjump(ap)
+{
+       register int *p1, *p2, *p3;
+       int nxj;
+
+       nxj = 0;
+       p1 = ap;
+       if ((p2 = p1->ref) == 0)
+               return(0);
+       for (;;) {
+               while ((p1 = p1->back) && p1->op==LABEL);
+               while ((p2 = p2->back) && p2->op==LABEL);
+               if (!equop(p1, p2))
+                       return(nxj);
+               p3 = insertl(p2);
+               p1->combop = JBR;
+               p1->ref = p3;
+               p1->labno = p3->labno;
+               p1->code = 0;
+               nxj++;
+               nxjump++;
+               nchange++;
+       }
+}
+
+insertl(ap)
+struct node *ap;
+{
+       register struct node *lp, *op;
+
+       op = ap;
+       if (op->op == LABEL) {
+               op->refc++;
+               return(op);
+       }
+       if (op->back->op == LABEL) {
+               op = op->back;
+               op->refc++;
+               return(op);
+       }
+       lp = alloc(sizeof first);
+       lp->combop = LABEL;
+       lp->labno = isn++;
+       lp->ref = 0;
+       lp->code = 0;
+       lp->refc = 1;
+       lp->back = op->back;
+       lp->forw = op;
+       op->back->forw = lp;
+       op->back = lp;
+       return(lp);
+}
+
+codemove(ap)
+struct node *ap;
+{
+       register struct node *p1, *p2, *p3;
+       struct node *t, *tl;
+       int n;
+
+       p1 = ap;
+       if (p1->op!=JBR || (p2 = p1->ref)==0)
+               return(p1);
+       while (p2->op == LABEL)
+               if ((p2 = p2->back) == 0)
+                       return(p1);
+       if (p2->op!=JBR && p2->op!=JMP)
+               goto ivloop;
+       p2 = p2->forw;
+       p3 = p1->ref;
+       while (p3) {
+               if (p3->op==JBR || p3->op==JMP) {
+                       if (p1==p3)
+                               return(p1);
+                       ncmot++;
+                       nchange++;
+                       p1->back->forw = p2;
+                       p1->forw->back = p3;
+                       p2->back->forw = p3->forw;
+                       p3->forw->back = p2->back;
+                       p2->back = p1->back;
+                       p3->forw = p1->forw;
+                       decref(p1->ref);
+                       return(p2);
+               } else
+                       p3 = p3->forw;
+       }
+       return(p1);
+ivloop:
+       if (p1->forw->op!=LABEL)
+               return(p1);
+       p3 = p2 = p2->forw;
+       n = 16;
+       do {
+               if ((p3 = p3->forw) == 0 || p3==p1 || --n==0)
+                       return(p1);
+       } while (p3->op!=CBR || p3->labno!=p1->forw->labno);
+       do 
+               if ((p1 = p1->back) == 0)
+                       return(ap);
+       while (p1!=p3);
+       p1 = ap;
+       tl = insertl(p1);
+       p3->subop = revbr[p3->subop];
+       decref(p3->ref);
+       p2->back->forw = p1;
+       p3->forw->back = p1;
+       p1->back->forw = p2;
+       p1->forw->back = p3;
+       t = p1->back;
+       p1->back = p2->back;
+       p2->back = t;
+       t = p1->forw;
+       p1->forw = p3->forw;
+       p3->forw = t;
+       p2 = insertl(p1->forw);
+       p3->labno = p2->labno;
+       p3->ref = p2;
+       decref(tl);
+       if (tl->refc<=0)
+               nrlab--;
+       loopiv++;
+       nchange++;
+       return(p3);
+}
+
+comjump()
+{
+       register struct node *p1, *p2, *p3;
+
+       for (p1 = first.forw; p1!=0; p1 = p1->forw)
+               if (p1->op==JBR && (p2 = p1->ref) && p2->refc > 1)
+                       for (p3 = p1->forw; p3!=0; p3 = p3->forw)
+                               if (p3->op==JBR && p3->ref == p2)
+                                       backjmp(p1, p3);
+}
+
+backjmp(ap1, ap2)
+struct node *ap1, *ap2;
+{
+       register struct node *p1, *p2, *p3;
+
+       p1 = ap1;
+       p2 = ap2;
+       for(;;) {
+               while ((p1 = p1->back) && p1->op==LABEL);
+               p2 = p2->back;
+               if (equop(p1, p2)) {
+                       p3 = insertl(p1);
+                       p2->back->forw = p2->forw;
+                       p2->forw->back = p2->back;
+                       p2 = p2->forw;
+                       decref(p2->ref);
+                       p2->labno = p3->labno;
+                       p2->ref = p3;
+                       nchange++;
+                       ncomj++;
+               } else
+                       return;
+       }
+}