BSD 3 development
[unix-history] / usr / doc / ctour / cdoc4
CommitLineData
8340f87c
BJ
1.SH
2Delaying and reordering
3.PP
4Intertwined with the code generation routines are two other,
5interrelated processes.
6The first, implemented by a routine called
7.II delay,
8is based on the observation that
9naive code generation for the expression
10`a = b++' would produce
11.DS
12mov b,r0
13inc b
14mov r0,a
15.DE
16The point is that the table for postfix ++ has to preserve
17the value of
18.II b
19before incrementing it;
20the general way to do this is to preserve its value in a register.
21A cleverer scheme would generate
22.DS
23mov b,a
24inc b
25.DE
26.II Delay
27is called for each expression input to
28.II rcexpr,
29and it searches for postfix ++ and \-\-
30operators.
31If one is found applied to a variable,
32the tree is patched to bypass the operator
33and compiled as it stands;
34then the increment or decrement itself is done.
35The effect is as if `a = b; b++' had been written.
36In this example, of course, the user himself could have done the same job,
37but more complicated examples are easily constructed, for example
38`switch (x++)'.
39An essential restriction is that the condition codes not
40be required.
41It would be incorrect to compile
42`if (a++) ...'
43as
44.DS
45tst a
46inc a
47beq ...
48.DE
49because the `inc' destroys the required setting of the condition codes.
50.PP
51Reordering is a similar sort of optimization.
52Many cases which it detects are useful
53mainly with register variables.
54If
55.II r
56is a register variable,
57the expression `r = x+y' is best compiled
58as
59.DS
60mov x,r
61add y,r
62.DE
63but the codes tables would produce
64.DS
65mov x,r0
66add y,r0
67mov r0,r
68.DE
69which is in fact preferred if
70.II r
71is not a register.
72(If
73.II r
74is not a register,
75the
76two sequences are the same size, but the
77second is slightly faster.)
78The scheme is to compile the expression as if it had been written
79`r = x; r =+ y'.
80The
81.II reorder
82routine
83is called with a pointer to each tree that
84.II rcexpr
85is about to compile;
86if it has the right characteristics,
87the `r = x' tree is constructed and passed recursively
88to
89.II rcexpr;
90then the original tree is modified to read `r =+ y'
91and the calling instance of
92.II rcexpr
93compiles that instead.
94Of course the whole business is itself recursive
95so that more extended forms of the same phenomenon are
96handled, like `r = x + y | z'.
97.PP
98Care does have to be taken
99to avoid `optimizing' an expression like `r = x + r'
100into `r = x; r =+ r'.
101It is required that the right operand of the expression on the right
102of the `=' be a ', distinct from the register variable.
103.PP
104The second case that
105.II reorder
106handles is expressions of the form `r = X' used as a subexpression.
107Again, the code out of the tables for
108`x = r = y'
109would be
110.DS
111mov y,r0
112mov r0,r
113mov r0,x
114.DE
115whereas if
116.II r
117were a register it would be better to produce
118.DS
119mov y,r
120mov r,x
121.DE
122When
123.II reorder
124discovers that
125a register variable is being assigned to
126in a subexpression,
127it calls
128.II rcexpr
129recursively to
130compile the subexpression, then fiddles the tree passed
131to it so that the register variable itself appears
132as the operand instead of the whole subexpression.
133Here care has to be taken to avoid an infinite regress,
134with
135.II rcexpr
136and
137.II reorder
138calling each other forever to handle assignments to registers.
139.PP
140A third set of cases treated by
141.II reorder
142comes up when any name, not necessarily a register,
143occurs as a left operand of an assignment operator other than `='
144or as an operand of prefix `++' or `\-\-'.
145Unless condition-code tests are involved,
146when a subexpression like `(a =+ b)' is seen,
147the assignment is performed and the argument tree
148modified so that
149.II a
150is its operand;
151effectively
152`x + (y =+ z)' is compiled as `y =+ z; x + y'.
153Similarly, prefix increment and decrement are pulled out
154and performed first, then the remainder of the expression.
155.PP
156Throughout code generation,
157the expression optimizer is called whenever
158.II delay
159or
160.II reorder
161change the expression tree.
162This allows some special cases to be found that otherwise
163would not be seen.