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.