[net.lang.c] Can ANSI Standard C be "Optimized"

minow@decvax.UUCP (Martin Minow) (03/13/84)

In the interesting and well-detailed series of optimization
comparisons between C and Bliss, it was pointed out several
times that Bliss performs many multi-statement optimizations
the C ignores.

If I read the Draft ANSI Standard correctly, it would seem to preclude
any optimizations across statement (;) boundaries.  Thus, simple for
satements cannot take advantage of loop control instructions such
as SOB on the PDP-11.

Therefore, many of the failings of the C optimizers are inherent
in the definition of the language, and not simply due to laziness
on the part of the compiler writers.  (And, no, I don't know
why this restriction was put in the draft standard.)

Martin Minow
decvax!minow

wcs@homxa.UUCP (Bill Stewart HO 4K-437 x0705) (03/14/84)

Martin Minow reports that:
	If I read the Draft ANSI Standard correctly, it would seem to preclude
	any optimizations across statement (;) boundaries.  
	..........
	Therefore, many of the failings of the C optimizers are inherent
	in the definition of the language, and not simply due to laziness
	on the part of the compiler writers.  (And, no, I don't know
	why this restriction was put in the draft standard.)

One reason optimization is difficult in C is the *EXISTENCE* of
pointers, which makes common-subexpression elimination very tough.
Consider the following code

	foo = bar * ( zed + bazoo / gletch)
	*ptr= foo
	baz = diddle( zed + bazoo / gletch )

The obvious optimization for the compiler to do is to calculate the
expression ( zed + bazoo / gletch ) once, store it in a temporary
location, and reuse it in the call to diddle.  However, the
assignment *ptr = foo could have changed the value of zed, bazoo, or
gletch, rendering the stored value useless.  For complicated expressions,
it may still be profitable to test "ptr==&zed || ptr==&bazoo ||
ptr==&gletch", instead of recalculating, but the utility is greatly
reduced.

In general, anything that has side-effects makes optimization
dangerous; assigning a value to *ptr may change the value of any
variable that ptr could point to.  This may be why the standard
limits optimization to very narrow locations, and is one reason why
overprotective languages like ADA(tm) or Modula-2 have their devotees.

				Bill
-- 
"The first major program written in ADA will be a COBOL interpreter."
					Stewart, 1984
Bill Stewart
AT&T Bell Labs, Holmdel NJ
HO 4K-437 x0705   (201-949-0705)
ho95b!wcs
ucbvax!ihnp4!ho95b!wcs
decvax1harpo!ho95b!wcs

lwall@sdcrdcf.UUCP (Larry Wall) (03/15/84)

In article <139@homxa.UUCP> wcs@homxa.UUCP (Bill Stewart) writes:
>
>In general, anything that has side-effects makes optimization
>dangerous; assigning a value to *ptr may change the value of any
>variable that ptr could point to.  This may be why the standard
>limits optimization to very narrow locations, and is one reason why
>overprotective languages like ADA(tm) or Modula-2 have their devotees.

I don't think Ada(r) is overly protective--you can still cheat; it's just
not the default like in C.  :-)

And who was ADA?  I always thought her name was Ada.

>"The first major program written in ADA will be a COBOL interpreter."

Nonsense.  The first major program written in Ada will be (is?) an Ada
compiler. Now if you don't think an Ada compiler is a major program you've
been out chasing wombats.  And if you think a COBOL interpreter is
equivalent to an Ada compiler, you *should* be out chasing wombats.

Fullname'(GIVEN => "Larry", SUR => "Wall")
{allegra,burdvax,cbosgd,hplabs,ihnp4,sdcsvax}!sdcrdcf!lwall

P.S. Ya don't gotta say "(char *)NULL" in Ada.  Nyaa nyaa!

dmmartindale@watcgl.UUCP (Dave Martindale) (03/18/84)

The "no optimization across statement boundaries" certainly wasn't part
of the language spec before the ANSI committee.

For as long as I can remember, the Ritchie C compiler for the PDP11
(actually c2, the optimizer) was happy to generate a SOB instruction
if it could be done.  You'll see some C code that contains loops of the
form
	if (n > 0)
		do {
			<whatever>
		} while (--n);

By putting the loop termination condition in exactly that form, you got
a SOB (Subtract One and Branch if non-zero) inserted.  Writing the code
using a while loop would have been clearer but slower.

gnu@sun.uucp (John Gilmore) (03/19/84)

Rather than add the "volatile" attribute to variable declarations, the C
standards committee has taken a safer alternative:  Assume that everything
is volatile, but permit it to be declared "const".  An object declared
"const" cannot be modified.  Furthermore, the "const" attribute can appear
at each level of indirection; eg

	const char *pcc;

declares a (modifiable) pointer, which is guaranteed by the programmer
to point to non-modifiable storage (a const char).  If you say

	char *const pcc = "string";

then it can (for example) put the string in the text segment.  A declaration
like

	char *const cpc;

declares a pointer, cp, which is not modifiable; but the object it points
to (a char) can be modified.

This can be used by the compiler -- there's no need to worry about aliasing
of const things.  For example, if a compiler already has the value of cpc in
a register due to a previous calculation, it need not reload it.  This can
be valuable for function parameters -- mostly they are constant throughout
the function.

The draft standard goes into more detail.  If you don't know anyone who has
one (or is on the committee), call CBEMA at 202-737-8888; they should be
able to point you right.  (Don't ask me.)

tim@unc.UUCP (Tim Maroney) (03/29/84)

J  Rather than add the "volatile" attribute to variable
O  declarations, the C standards committee has taken a safer
H  alternative:  Assume that everything is volatile, but permit it
N  to be declared "const".  An object declared "const" cannot be
.  modified.  Furthermore, the "const" attribute can appear at each
J  level of indirection; eg
O
H          const char *pcc;
N
.  declares a (modifiable) pointer, which is guaranteed by the
J  programmer to point to non-modifiable storage (a const char).

This does not speak to the problem at hand at all, which is making it
possible to optimize code containing references to data which may be changed
by external events.

By the way, I am somewhat distressed that everyone has decided to talk about
string and array comparisons, which were just an aside at the end of the
article on improving C's generality, and which really are not very
interesting and add nothing to C's generality.  Doesn't anyone have anything
to say about the rest of my suggestions?  Even flames?
--
Tim Maroney, The Censored Hacker
mcnc!unc!tim (USENET), tim.unc@csnet-relay (ARPA)

All opinions expressed herein are completely my own, so don't go assuming
that anyone else at UNC feels the same way.