[Python-Dev] AST Optimization: Branch Elimination in Generator Functions

Thomas Lee tom at vector-seven.com
Sat May 3 04:22:34 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