[net.micro.mac] slow C compilers

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