vantreeck@logic.DEC (09/13/85)
>I used Hippo C and found it to be s-l-o-w. For compilation, Level 2 on a RAM >disk was no faster than some other compilers on floppies. I would gladly pay 2 to 3 times the current prices for a v-e-r-y s-l-o-w compiler on the Mac that makes several passes to generate optimized code. I'm looking for a compiler that does more than constant folding and compile time evaluation of constants. If anyone knows of a Mac C or Pascal compiler that performs at least most of the following optimizations, I and others would like to know about it. o Compile-time evaluation of constant expressions o Rearranging unary minus and not ("!") operations to eliminate unary negation/complement operations o Partial compile-time evaluation of logical expressions o Elimination of constant common subexpressions o Elimination of unreachable code o Code hoisting from structured statements o Removal of invariant computations from loops o Inline code expansion of small predeclared functions o Inline expansion of static (local), user defined functions o Global assignment of variables to registers base on frequency of reference o Reordering the evaluation of expressions to minimize the number of temporary values needed (may not garuntee left to right evaluation) o peephole optimzation of instruction sequences - the following are three examples of code generated by a popular C compiler, I'll use equivalent C statements for the generated code to make the example clearer. 1) char a; ... if (a & 0x80) /* test bit 7 of a */ generates: { register char t = a; t &= 0xFF; /* clear upper 3 bytes */ t &= 0x80; /* set bit 7 */ } if (t) ... correct code should be: { register char t = a; t &= 0x80; /* set bit 7 */ } if (t) ... obviously "t &= 0xFF" is entirely unnecessary because anding with 0x80 will clear the upper bytes anyway - doesn't have to be done by peephole optimizer but it can be done there. 2) char a; ... if (a & 0x80) /* test bit 7 of a */ The compiler fails to recognize the 0x80 is a number that is 2 raised to an integer value. If it did recognize that fact it, would be able to use a test bit instruction instead of anding and then testing the result. This can be generalized to the setting and clearing of bits as well - this doesn't have to to be done by the peephole optimizer but it can be. 3) struct foo { int a, b, c; }... foo.a = z; foo.b = 1; foo.c = alpha; The compiler will load a pointer to foo into a register, assign the value z to a, reload a pointer to foo into the same register as before, assign the value 1 to b, reload, AGAIN, a pointer to foo into the same register, assign alpha to foo.c. If the compiler were of any decent quality it would only load a pointer to foo ONCE!!! -George
mike@smu (09/16/85)
There's sort of a problem with the idea of an extensiveley optimizing C compiler. First, some of the optimizations mentioned (code hoisting, common subexpression elimination (I suppose beyond basic blocks), and various loop optimizations) take a lot of space (in general). Maybe you're willing to pay this price. The other (and real) problem is that C, because of its low-level (I don't really like that term) nature, is not supposed to be thusly optimized. Check pages 49 and 50 of K&R. I suppose I would sort of lke an optimizing compiler as well, but I've gotten pretty good at writing the source code efficiently to begin with (some would say this is a bad habit, but most of my life is pretty sleazy anyway so this doesn't bother me). I remember a possibly apocryphal story I heard in a compiler class about a guy who wrote a FORTRAN source code optimizer that was more effective than IBM's FORTRAN G (or maybe H, whichever is the good one). Mike McNally SMU mike@smu ...convex!smu!mike