Next: , Previous: , Up: Source Optimization   [Contents][Index]


5.4.4 Control Optimization

The most important optimization of control is recognizing when an if test is known at compile time, then deleting the if, the test expression, and the unreachable branch of the if. This can be considered a special case of constant folding, although the test doesn’t have to be truly constant as long as it is definitely not nil. Note also, that type inference propagates the result of an if test to the true and false branches, see constraint-propagation.

A related if optimization is this transformation:11

(if (if a b c) x y)

into:

(if a
    (if b x y)
    (if c x y))

The opportunity for this sort of optimization usually results from a conditional macro. For example:

(if (not a) x y)

is actually implemented as this:

(if (if a nil t) x y)

which is transformed to this:

(if a
    (if nil x y)
    (if t x y))

which is then optimized to this:

(if a y x)

Note that due to Python’s internal representations, the ifif situation will be recognized even if other forms are wrapped around the inner if, like:

(if (let ((g ...))
      (loop
        ...
        (return (not g))
        ...))
    x y)

In Python, all the Common Lisp macros really are macros, written in terms of if, block and tagbody, so user-defined control macros can be just as efficient as the standard ones. Python emits basic blocks using a heuristic that minimizes the number of unconditional branches. The code in a tagbody will not be emitted in the order it appeared in the source, so there is no point in arranging the code to make control drop through to the target.


Footnotes

(11)

Note that the code for x and y isn’t actually replicated.


Next: Unreachable Code Deletion, Previous: Unused Expression Elimination, Up: Source Optimization   [Contents][Index]