Bad optimization in PCC?

Robert Firth firth at sei.cmu.edu
Wed Apr 27 07:05:29 AEST 1988


In article <793 at amnesix.liu.se> mikpe at amnesix.liu.se (Mikael Pettersson) writes:

[a missed optimisation in some C compilers: the code reads as shown]

>(1) while(*np && (*np++ == *ep++))
>        /* empty */ ;
>(2) if(!*np)
>        *envp = val;
>
>Notice that the value of the test at line (2) is known if the '*np'
>part of line (1) evaluates to 0.
>
>Actual code generated (compiling flags: -O -S):
>
>Sun CC, SunOS3.2                  GNU CC, ver 1.18 for Sun3
>-----------------------------------------------------------
>L18:    tstb    a3@               L5:     moveb a1@,d0
>     (+)jeq     L19   <-----THIS-----> (+)jeq L6
>        cmpmb   a4 at +,a3 at +                 addql #1,a1
>        jeq     L18                       cmpb a0 at +,d0
>L19:    tstb    a3@                       jeq L5
>     (*)jne     L20               L6:     tstb a1@
>        movl    a6@(12),a5@            (*)jne L7
>L20:                                      movel d1,a2@
>                                  L7:

Just to add my own comments.  The optimisation requested should happen
as part of a set of transformations that might be called "branch chaining".

This kind of thing is pretty easy:

	goto L1
	...
    L1: goto L2

The optimiser looks at the target of the jump, sees it is another jump,
and simply changes the first jump to read 'goto L2', naturally also
decrementing the reference count of L1.  (Incidentally, it is sometimes
advantageous to make the reverse transformation, but that's another
story.)

As a next step, observe that the first jump can easily be conditional;
the transformation is still valid:

	if B goto L1
	...
    L1: goto L2

=>	if B goto L2

The third step is where BOTH jumps are conditional.  If the truth
of the first condition implies the truth of the second, we can still
chain:
	if B1 goto L1
	...
    L1: if B2 goto L2	/* B1 implies B2 */

=>	if B1 goto L2

Finally, if the truth of the first condition implies the FALSEHOOD of
the second condition, we can retarget the first branch, giving:

	if B1 goto L1a
	...
    L1: if B2 goto L2	/* B1 implies NOT B2 */
    L1a:

This is the required transformation.  Note, though, that it is a lot
easier to do on the attributed parse tree - optimising the Assembler
code involves also understanding why the second test instruction can
be bypassed, for example.



More information about the Comp.lang.c mailing list