Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!pyrdc!gmu90x!dolqci!vrdxhq!umd5!mimsy!chris From: chris@mimsy.UUCP (Chris Torek) Newsgroups: comp.sources.d Subject: Re: ctex documentation (why c is better than pascal) Message-ID: <8826@mimsy.UUCP> Date: Tue, 29-Sep-87 11:36:11 EDT Article-I.D.: mimsy.8826 Posted: Tue Sep 29 11:36:11 1987 Date-Received: Thu, 1-Oct-87 05:46:29 EDT References: <1742@cp1.BELL-ATL.COM> <540@rocky.STANFORD.EDU> <4313@ncoast.UUCP> <1698@briar.Philips.Com> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 334 In article <1698@briar.Philips.Com> rob@philabs.Philips.Com (Rob Robertson) writes: >The berkeley pascal compilers ON 4.X BSD VAXEN is a pig, it generates >enormous code that runs slow. By just doing a Pascal->C translation a >gain of about 20-30 percent can be achieved. The same improvement can be had by doing two things: 1) add a default clause for case statements (~15%)---this is trivial, for the compiler already generates code for the default; all you need do is make it generate different code if there is an `otherwise'; and 2) run another peephole optimiser on the assembly out of /lib/c2 (~15%). A third hack that helps somewhat is to patch the Fortran code generator (yes, pc uses f1) to recognise a = a + b; and convert this to a += b; although in fact this should be done in pc itself. On the other hand, using a better compiler, such as Pastel, gives a 50% improvement: the resulting TeX runs about twice as fast as plain-old-Berkeley-pc TeX. (On the bright side for Berkeley pc, TeX did not break the compiler, as it did for most other Pascals. There is *something* to be said for slow and stupid. :-) ) Here is the post-c2-optimiser I used. It was written quite some time ago, and has things I would do differently now.... In fact, these should probably be merged into c2 itself. #ifndef lint static char rcsid[] = "$Header: fiddle.c$"; #endif /* * fiddle - fiddle with assembly code (play peephole optimizer) */ #include #include char inbuf[BUFSIZ]; main () { register char *p, *bufp; while (fgets (inbuf, sizeof inbuf, stdin)) { retry: p = bufp = inbuf; while (*p) if (*p++ == ':') bufp = p; p = bufp; if (p > inbuf) { register int c = *p; *p = 0; fputs (inbuf, stdout); *p = c; } if (*p++ == 'a' && *p++ == 'd' && *p++ == 'd' && *p++ == 'l' && *p++ == '2' && *p++ == '\t') { /* stuff depending on "addl2\t" */ if (try1 (p)) goto retry; if (try2 (p)) goto retry; } p = bufp; if (*p++ == 'a' && *p++ == 's' && *p++ == 'h' && *p++ == 'l' && *p++ == '\t' && *p++ == '$' && *p++ == '2' && *p++ == ',' && *p++ == 'r') { /* stuff depending on "ashl\t$2,r" */ if (try3 ()) goto retry; } fputs (bufp, stdout); } exit (0); } char * getreg (p, ar) register char *p; int *ar; { register int r; r = *p++ - '0'; if (r == 1 && isdigit (*p)) r = 10 + *p++ - '0'; *ar = r; return p; } char * getconst (p, ac) register char *p; int *ac; { register int r; if (!isdigit (*p)) return 0; r = *p++ - '0'; while (isdigit (*p)) r = r * 10 + *p++ - '0'; *ac = r; return p; } /* * Try to convert * * addl2 $const,rX \ * ashl $2,rX,rX > moval y+4*const[rX],rX * addl2 $y,rX,rX / * * addl2 $const,rX \ * ashl $2,rX,rX -- moval 4*const[rX],rX * * return 0 iff didn't do anything at all */ try1 (p) register char *p; { register int n, r; int n2, r2; if (*p++ != '$') return 0; n = 0; while (isdigit (*p)) n = n * 10 + *p++ - '0'; if (*p++ != ',' || *p++ != 'r' || !isdigit (*p)) return 0; r = *p++ - '0'; if (r == 1 && isdigit (*p)) r = 10 + *p++ - '0'; if (*p != '\n') { /* shouldn't happen */ fprintf (stderr, "\n? left over: %s\n", p); return 0; } /* * About to be committed... */ if (fgets (inbuf, sizeof inbuf, stdin) == NULL) { e_o_f: inbuf[0] = 0; give_up: printf ("addl2\t$%d,r%d\n", n, r); return 1; } /* * addl2 $c1,rX \ * addl2 $c2,rX -- addl2 $c1+c2,rX */ more_adds: if (inbuf[0] == 'a' && inbuf[1] == 'd' && inbuf[2] == 'd' && inbuf[3] == 'l' && inbuf[4] == '2' && inbuf[5] == '\t' && inbuf[6] == '$') { p = &inbuf[7]; p = getconst (p, &n2); if (p == 0 || *p++ != ',' || *p++ != 'r') goto give_up; p = getreg (p, &r2); if (r2 != r || *p != '\n') goto give_up; n += n2; /* collapse the constants */ if (fgets (inbuf, sizeof inbuf, stdin) == NULL) goto e_o_f; goto more_adds; } if (inbuf[0] != 'a' || inbuf[1] != 's' || inbuf[2] != 'h' || inbuf[3] != 'l' || inbuf[4] != '\t' || inbuf[5] != '$' || inbuf[6] != '2' || inbuf[7] != ',' || inbuf[8] != 'r') goto give_up; p = &inbuf[9]; p = getreg (p, &r2); if (r2 != r || *p++ != ',' || *p++ != 'r') goto give_up; p = getreg (p, &r2); if (r2 != r || *p != '\n') goto give_up; putc ('#', stderr); (void) fflush (stderr); /* * One more trick: if next line is another "addl2 $y,rX", we can * use the instruction "moval $const*4+(y),rX". */ if (fgets (inbuf, sizeof inbuf, stdin) == NULL) { inbuf[0] = 0; just_one: printf ("moval\t%d[r%d],r%d\n", n << 2, r, r); return 1; } if (inbuf[0] == 'a' && inbuf[1] == 'd' && inbuf[2] == 'd' && inbuf[3] == 'l' && inbuf[4] == '2' && inbuf[5] == '\t' && inbuf[6] == '$') { char *end_of_y; p = &inbuf[7]; while (*p != ',') p++; end_of_y = p; p++; if (*p++ != 'r') goto just_one; p = getreg (p, &r2); if (r2 != r || *p != '\n') goto just_one; /* bingo! */ putc ('!', stderr); (void) fflush (stderr); *end_of_y = 0; printf ("moval\t%s+%d[r%d],r%d\n", &inbuf[7], n << 2, r, r); if (fgets (inbuf, sizeof inbuf, stdin) == NULL) inbuf[0] = 0; return 1; } goto just_one; } /* * Try to convert: * * addl2 rX,rX \ * addl2 $y,rX -- movaw y[rX],rX */ try2 (p) register char *p; { int r1, r2; char *end_of_y; if (*p++ != 'r') return 0; p = getreg (p, &r1); if (*p++ != ',' || *p++ != 'r') return 0; p = getreg (p, &r2); if (*p != '\n' || r1 != r2) return 0; if (fgets (inbuf, sizeof inbuf, stdin) == NULL) { inbuf[0] = 0; give_up: printf ("addl2\tr%d,r%d\n", r1, r1); return 1; } if (inbuf[0] != 'a' || inbuf[1] != 'd' || inbuf[2] != 'd' || inbuf[3] != 'l' || inbuf[4] != '2' || inbuf[5] != '\t' || inbuf[6] != '$') goto give_up; p = &inbuf[7]; while (*p != ',') p++; end_of_y = p; p++; if (*p++ != 'r') goto give_up; p = getreg (p, &r2); if (*p != '\n' || r1 != r2) goto give_up; /* got it */ putc ('>', stderr); (void) fflush (stderr); *end_of_y = 0; printf ("movaw\t%s[r%d],r%d\n", &inbuf[7], r1, r1); if (fgets (inbuf, sizeof inbuf, stdin) == NULL) inbuf[0] = 0; return 1; } /* * Try to convert: * * ashl $2,rX,rX \ * addl2 $y,rX -- moval y[rX],rX */ try3 (p) register char *p; { int r1, r2; char *end_of_y; p = getreg (&inbuf[9], &r1); if (*p++ != ',' || *p++ != 'r') return 0; p = getreg (p, &r2); if (*p != '\n' || r1 != r2) return 0; if (fgets (inbuf, sizeof inbuf, stdin) == NULL) { inbuf[0] = 0; give_up: printf ("ashl\t$2,r%d,r%d\n", r1, r1); return 1; } if (inbuf[0] != 'a' || inbuf[1] != 'd' || inbuf[2] != 'd' || inbuf[3] != 'l' || inbuf[4] != '2' || inbuf[5] != '\t' || inbuf[6] != '$') goto give_up; p = &inbuf[7]; while (*p != ',') p++; end_of_y = p; p++; if (*p++ != 'r') goto give_up; p = getreg (p, &r2); if (*p != '\n' || r1 != r2) goto give_up; /* got it */ putc ('-', stderr); (void) fflush (stderr); *end_of_y = 0; printf ("moval\t%s[r%d],r%d\n", &inbuf[7], r1, r1); if (fgets (inbuf, sizeof inbuf, stdin) == NULL) inbuf[0] = 0; return 1; } -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris