[comp.lang.c] goto's and optimization

bright@Data-IO.COM (Walter Bright) (09/28/89)

In article <1098@cernvax.UUCP> hjm@cernvax.UUCP (Hubert Matthews) writes:
>In article <11132@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes:
>>Actually, most Algol-like languages can be better optimized with less
>>effort if GOTOs are outlawed.
>Programs that don't use GOTOs generate only reducible flow-graphs;
>programs that use GOTOs may generate irreducible flow-graphs.
>Optimising a reducible flow-graph can be done without having to resort
>to full data-flow analysis (just consider the problem of trying to
>find loop-invariant expressions if you don't know trivially where the
>loops are).  Thus, the optimiser can be simpler for languages such as
>C, PASCAL and Modula-2 compared to FORTRAN.

I've written an optimizer that analyzes the flow graph to find loops. It
turns out that standard, published algorithms can be used, and it just
isn't that hard.

If you have an optimizer, try an experiment to see how good it is,
write the same loop 3 ways:
	int array[10];

1.	for (i = 0; i < 10; i++)
		func(array[i]);

2.	i = 0;
	while (i < 10)
	{	func(array[i]);
		i++;
	}

3.	i = 0;
    L2:	if (i >= 10)
		goto L1;
	func(array[i]);
	i++;
	goto L2;
    L1: ;

I've seen some 'optimizers' that would only handle case 1.

A good optimizer will produce the same result for all three cases.
Being able to handle case 3 properly is important to handle the situation
where the compiler is working on machine-generated C code. It's easier
to generate C as a bunch of expressions connected by goto's than
trying to figure out an equivalent set of if's, for's, etc.

P.S. The optimized result should be something like:
	int *p;

	p = &array[0];
    L1:	func(p);
	p++;
	if (p < &array[10])
		goto L1;