home *** CD-ROM | disk | FTP | other *** search
- .SH
- Delaying and reordering
- .PP
- Intertwined with the code generation routines are two other,
- interrelated processes.
- The first, implemented by a routine called
- .II delay,
- is based on the observation that
- naive code generation for the expression
- `a = b++' would produce
- .DS
- mov b,r0
- inc b
- mov r0,a
- .DE
- The point is that the table for postfix ++ has to preserve
- the value of
- .II b
- before incrementing it;
- the general way to do this is to preserve its value in a register.
- A cleverer scheme would generate
- .DS
- mov b,a
- inc b
- .DE
- .II Delay
- is called for each expression input to
- .II rcexpr,
- and it searches for postfix ++ and \-\-
- operators.
- If one is found applied to a variable,
- the tree is patched to bypass the operator
- and compiled as it stands;
- then the increment or decrement itself is done.
- The effect is as if `a = b; b++' had been written.
- In this example, of course, the user himself could have done the same job,
- but more complicated examples are easily constructed, for example
- `switch (x++)'.
- An essential restriction is that the condition codes not
- be required.
- It would be incorrect to compile
- `if (a++) ...'
- as
- .DS
- tst a
- inc a
- beq ...
- .DE
- because the `inc' destroys the required setting of the condition codes.
- .PP
- Reordering is a similar sort of optimization.
- Many cases which it detects are useful
- mainly with register variables.
- If
- .II r
- is a register variable,
- the expression `r = x+y' is best compiled
- as
- .DS
- mov x,r
- add y,r
- .DE
- but the codes tables would produce
- .DS
- mov x,r0
- add y,r0
- mov r0,r
- .DE
- which is in fact preferred if
- .II r
- is not a register.
- (If
- .II r
- is not a register,
- the
- two sequences are the same size, but the
- second is slightly faster.)
- The scheme is to compile the expression as if it had been written
- `r = x; r =+ y'.
- The
- .II reorder
- routine
- is called with a pointer to each tree that
- .II rcexpr
- is about to compile;
- if it has the right characteristics,
- the `r = x' tree is constructed and passed recursively
- to
- .II rcexpr;
- then the original tree is modified to read `r =+ y'
- and the calling instance of
- .II rcexpr
- compiles that instead.
- Of course the whole business is itself recursive
- so that more extended forms of the same phenomenon are
- handled, like `r = x + y | z'.
- .PP
- Care does have to be taken
- to avoid `optimizing' an expression like `r = x + r'
- into `r = x; r =+ r'.
- It is required that the right operand of the expression on the right
- of the `=' be a ', distinct from the register variable.
- .PP
- The second case that
- .II reorder
- handles is expressions of the form `r = X' used as a subexpression.
- Again, the code out of the tables for
- `x = r = y'
- would be
- .DS
- mov y,r0
- mov r0,r
- mov r0,x
- .DE
- whereas if
- .II r
- were a register it would be better to produce
- .DS
- mov y,r
- mov r,x
- .DE
- When
- .II reorder
- discovers that
- a register variable is being assigned to
- in a subexpression,
- it calls
- .II rcexpr
- recursively to
- compile the subexpression, then fiddles the tree passed
- to it so that the register variable itself appears
- as the operand instead of the whole subexpression.
- Here care has to be taken to avoid an infinite regress,
- with
- .II rcexpr
- and
- .II reorder
- calling each other forever to handle assignments to registers.
- .PP
- A third set of cases treated by
- .II reorder
- comes up when any name, not necessarily a register,
- occurs as a left operand of an assignment operator other than `='
- or as an operand of prefix `++' or `\-\-'.
- Unless condition-code tests are involved,
- when a subexpression like `(a =+ b)' is seen,
- the assignment is performed and the argument tree
- modified so that
- .II a
- is its operand;
- effectively
- `x + (y =+ z)' is compiled as `y =+ z; x + y'.
- Similarly, prefix increment and decrement are pulled out
- and performed first, then the remainder of the expression.
- .PP
- Throughout code generation,
- the expression optimizer is called whenever
- .II delay
- or
- .II reorder
- change the expression tree.
- This allows some special cases to be found that otherwise
- would not be seen.
-