From f3b0b9774bfcb000a96678c6731ed93d63dc4f1c Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Fri, 13 Dec 2013 21:31:26 +0100 Subject: [PATCH] simplify constant folded comparison code a little and extend the test for it --- Cython/Compiler/Optimize.py | 15 ++++------ tests/run/constant_folding.py | 67 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 9 deletions(-) diff --git a/Cython/Compiler/Optimize.py b/Cython/Compiler/Optimize.py index a7044de..8eacef1 100644 --- a/Cython/Compiler/Optimize.py +++ b/Cython/Compiler/Optimize.py @@ -3307,19 +3307,13 @@ class ConstantFolding(Visitor.VisitorTransform, SkipDeclarations): # collect partial cascades: [[value, CmpNode...], [value, CmpNode, ...], ...] cascades = [[node.operand1]] + final_result = [True] def split_cascades(cmp_node): if cmp_node.has_constant_result(): if not cmp_node.constant_result: # False => short-circuit - cascades.append([ - self._bool_node(cmp_node, True), - ExprNodes.CascadedCmpNode( - cmp_node.pos, - operator='==', - operand2=self._bool_node(cmp_node, False), - constant_result=False) - ]) + final_result[0] = False return else: # True => discard and start new cascade @@ -3351,7 +3345,10 @@ class ConstantFolding(Visitor.VisitorTransform, SkipDeclarations): last_cmp_node = cmp_node last_cmp_node.cascade = None - if not cmp_nodes: + if not final_result[0]: + # last cascade was constant False + cmp_nodes.append(self._bool_node(cmp_node, False)) + elif not cmp_nodes: # only constants, but no False result return self._bool_node(node, True) node = cmp_nodes[0] diff --git a/tests/run/constant_folding.py b/tests/run/constant_folding.py index dc4d955..803cf35 100644 --- a/tests/run/constant_folding.py +++ b/tests/run/constant_folding.py @@ -361,3 +361,70 @@ def combined(): True """ return 5 in 100 * [1, 2] * 0 or 5 not in 100 * [] * 10 + + +@cython.test_assert_path_exists( + '//IntNode[@value = "2"]', + '//IntNode[@value = "4"]', + '//IntNode[@value = "5"]', + '//IntNode[@value = "7"]', + '//BoolBinopNode//PrimaryCmpNode', + '//BoolBinopNode[.//PrimaryCmpNode//IntNode[@value = "4"] and .//PrimaryCmpNode//IntNode[@value = "5"]]', + '//PrimaryCmpNode[.//IntNode[@value = "2"] and .//IntNode[@value = "4"]]', + '//PrimaryCmpNode[.//IntNode[@value = "5"] and .//IntNode[@value = "7"]]', +) +@cython.test_fail_if_path_exists( + '//IntNode[@value = "1"]', + '//IntNode[@value = "8"]', + '//PrimaryCmpNode[.//IntNode[@value = "4"] and .//IntNode[@value = "5"]]', + '//PrimaryCmpNode[.//IntNode[@value = "2"] and .//IntNode[@value = "7"]]', + '//BoolNode', +) +def cascaded_cmp_with_partial_constants(a, b): + """ + >>> cascaded_cmp_with_partial_constants(3, 6) + True + >>> cascaded_cmp_with_partial_constants(1, 6) + False + >>> cascaded_cmp_with_partial_constants(4, 6) + False + >>> cascaded_cmp_with_partial_constants(3, 7) + False + >>> cascaded_cmp_with_partial_constants(3, 6) + True + """ + return 1 < 2 < a < 4 < 5 < b < 7 < 8 + + +@cython.test_assert_path_exists( + '//IntNode[@value = "2"]', + '//IntNode[@value = "4"]', + '//IntNode[@value = "5"]', + '//IntNode[@value = "7"]', + '//BoolBinopNode', + '//SingleAssignmentNode//BoolBinopNode', + '//SingleAssignmentNode//BoolBinopNode//NameNode[@name = "a"]', + '//SingleAssignmentNode//BoolBinopNode//NameNode[@name = "b"]', + '//BoolBinopNode[.//PrimaryCmpNode//IntNode[@value = "4"] and .//PrimaryCmpNode//IntNode[@value = "5"]]', + '//BoolNode[@value = False]', +) +@cython.test_fail_if_path_exists( + '//SingleAssignmentNode//NameNode[@name = "c"]', + '//IntNode[@value = "1"]', + '//PrimaryCmpNode[.//IntNode[@value = "4"] and .//IntNode[@value = "5"]]', + '//PrimaryCmpNode[.//IntNode[@value = "2"] and .//IntNode[@value = "7"]]', + '//BoolNode[@value = True]', +) +def cascaded_cmp_with_partial_constants_and_false_end(a, b, c): + """ + >>> cascaded_cmp_with_partial_constants_and_false_end(3, 6, 8) + False + >>> cascaded_cmp_with_partial_constants_and_false_end(1, 6, 8) + False + >>> cascaded_cmp_with_partial_constants_and_false_end(4, 6, 8) + False + >>> cascaded_cmp_with_partial_constants_and_false_end(3, 7, 8) + False + """ + x = 1 < 2 < a < 4 < 5 < b < 7 < 7 < c + return x -- 2.7.4