[Python-Dev] AST Optimization: Branch Elimination in Generator Functions
Thomas Lee
tom at vector-seven.com
Sat May 3 06:51:47 CEST 2008
The next problem that cropped up during the implementation of the AST
code optimizer is related to branch elimination and the elimination of
any code after a return.
Within a FunctionDef node, we would (ideally) like to blow away If nodes
with a constant - but false - test expression. e.g.:
def foo():
if False:
# ... stuff ...
For most functions, this will cause no problems and the code will behave
as expected. However, if the eliminated branch contains a "yield"
expression, the function is actually a generator function - even if the
yield expression can never be reached:
def foo():
if False:
yield 5
In addition to this, the following should also be treated as a generator
even though we'd like to be able to get rid of all the code following
the "return" statement:
def foo():
return
yield 5
Again, blowing away the yield results in a normal function instead of a
generator. Not what we want: we need to preserve the generator semantics.
Upon revisiting this, it's actually made me reconsider the use of a
Const node for the earlier problem relating to arbitrary constants. We
may be better off with annotations after all ... then we could mark
FunctionDef nodes as being generators at the AST level to force the
compiler to produce code for a generator, but eliminate the branches
anyway.
The other alternative I can think of is injecting a yield node somewhere
unreachable and ensuring it doesn't get optimized away, but this seems
pretty hacky in comparison.
Any other ideas?
Cheers,
Tom
More information about the Python-Dev
mailing list