Commit 1fe57453 authored by Stefan Behnel's avatar Stefan Behnel

simplify and generalise comprehension/genexpr handling fix for if-const optimisation

--HG--
extra : transplant_source : %A6%DC%F6%80lF%5B%82W%E2%86%F9%8A%B9%FF%0FR%D1%E2H
parent 0f7f57f5
......@@ -3116,26 +3116,15 @@ class ConstantFolding(Visitor.VisitorTransform, SkipDeclarations):
node.else_clause = if_clause.body
break
else:
# False clauses can safely be deleted
assert condition_result == False
# prevent killing generator expressions,
# but simplify them as much as possible
yield_expr_stat = self._find_genexpr_yield_stat(if_clause.body)
if yield_expr_stat is not None:
# => if False: yield None
yield_expr = yield_expr_stat.expr
if_clause.condition = ExprNodes.BoolNode(
if_clause.condition.pos,
value=False, constant_result=False)
yield_expr.arg = ExprNodes.NoneNode(yield_expr.arg.pos)
if_clause.body = yield_expr_stat
if_clauses.append(if_clause)
else:
# False clauses outside of generators can safely be deleted
pass
if not if_clauses:
if if_clauses:
node.if_clauses = if_clauses
return node
elif node.else_clause:
return node.else_clause
node.if_clauses = if_clauses
return node
else:
return Nodes.StatListNode(node.pos, stats=[])
def _find_genexpr_yield_stat(self, node):
body_node_types = (Nodes.ForInStatNode, Nodes.IfStatNode)
......
# mode: run
# tag: generators
import cython
try:
from builtins import next # Py3k
except ImportError:
......@@ -362,3 +364,23 @@ def test_del_in_generator():
del x
yield a
del a
@cython.test_fail_if_path_exists("//IfStatNode", "//PrintStatNode")
def test_yield_in_const_conditional_false():
"""
>>> list(test_yield_in_const_conditional_false())
[]
"""
if False:
print(yield 1)
@cython.test_fail_if_path_exists("//IfStatNode")
@cython.test_assert_path_exists("//PrintStatNode")
def test_yield_in_const_conditional_true():
"""
>>> list(test_yield_in_const_conditional_true())
None
[1]
"""
if True:
print(yield 1)
......@@ -87,3 +87,23 @@ def sorted_listcomp(sequence):
[3, 4, 5]
"""
return sorted([ n+1 for n in sequence ])
@cython.test_fail_if_path_exists("//IfStatNode",
"//ComprehensionAppendNode")
@cython.test_assert_path_exists("//ComprehensionNode")
def listcomp_const_condition_false():
"""
>>> listcomp_const_condition_false()
[]
"""
return [x*2 for x in range(3) if False]
@cython.test_fail_if_path_exists("//IfStatNode")
@cython.test_assert_path_exists("//ComprehensionNode",
"//ComprehensionAppendNode")
def listcomp_const_condition_true():
"""
>>> listcomp_const_condition_true()
[0, 2, 4]
"""
return [x*2 for x in range(3) if True]
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment