Next: Unreachable Code Deletion, Previous: Unused Expression Elimination, Up: Source Optimization [Contents][Index]
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
if
—if
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.
Next: Unreachable Code Deletion, Previous: Unused Expression Elimination, Up: Source Optimization [Contents][Index]