summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2019-03-16 22:55:32 +0100
committerStefan Behnel <stefan_ml@behnel.de>2019-03-16 22:55:32 +0100
commite969ef32633d9c6823b9a6133a4bf5b92300cdab (patch)
tree51f5212a7a82c54ad3ce85dc75ea3043c86713a1
parent714123e3c1f43a05d23f4625edc04b847f19c042 (diff)
downloadcython-e969ef32633d9c6823b9a6133a4bf5b92300cdab.tar.gz
Simplify optimisation code for cascaded comparisons and improve its test coverage.
-rw-r--r--Cython/Compiler/Optimize.py10
-rw-r--r--tests/compile/cascmp.pyx17
-rw-r--r--tests/run/cascmp.pyx38
3 files changed, 42 insertions, 23 deletions
diff --git a/Cython/Compiler/Optimize.py b/Cython/Compiler/Optimize.py
index d48f98155..9e8724d3e 100644
--- a/Cython/Compiler/Optimize.py
+++ b/Cython/Compiler/Optimize.py
@@ -4527,22 +4527,20 @@ class ConstantFolding(Visitor.VisitorTransform, SkipDeclarations):
cascades = [[node.operand1]]
final_false_result = []
- def split_cascades(cmp_node):
+ cmp_node = node
+ while cmp_node is not None:
if cmp_node.has_constant_result():
if not cmp_node.constant_result:
# False => short-circuit
final_false_result.append(self._bool_node(cmp_node, False))
- return
+ break
else:
# True => discard and start new cascade
cascades.append([cmp_node.operand2])
else:
# not constant => append to current cascade
cascades[-1].append(cmp_node)
- if cmp_node.cascade:
- split_cascades(cmp_node.cascade)
-
- split_cascades(node)
+ cmp_node = cmp_node.cascade
cmp_nodes = []
for cascade in cascades:
diff --git a/tests/compile/cascmp.pyx b/tests/compile/cascmp.pyx
deleted file mode 100644
index c36997fbb..000000000
--- a/tests/compile/cascmp.pyx
+++ /dev/null
@@ -1,17 +0,0 @@
-# mode: compile
-
-cdef void foo():
- cdef int bool, int1=0, int2=0, int3=0, int4=0
- cdef object obj1, obj2, obj3, obj4
- obj1 = 1
- obj2 = 2
- obj3 = 3
- obj4 = 4
- bool = int1 < int2 < int3
- bool = obj1 < obj2 < obj3
- bool = int1 < int2 < obj3
- bool = obj1 < 2 < 3
- bool = obj1 < 2 < 3 < 4
- bool = int1 < (int2 == int3) < int4
-
-foo()
diff --git a/tests/run/cascmp.pyx b/tests/run/cascmp.pyx
new file mode 100644
index 000000000..becae3fc5
--- /dev/null
+++ b/tests/run/cascmp.pyx
@@ -0,0 +1,38 @@
+# mode: run
+# tag: cascade, compare
+
+def ints_and_objects():
+ """
+ >>> ints_and_objects()
+ (0, 1, 0, 1, 1, 0)
+ """
+ cdef int int1=0, int2=0, int3=0, int4=0
+ cdef int r1, r2, r3, r4, r5, r6
+ cdef object obj1, obj2, obj3, obj4
+ obj1 = 1
+ obj2 = 2
+ obj3 = 3
+ obj4 = 4
+ r1 = int1 < int2 < int3
+ r2 = obj1 < obj2 < obj3
+ r3 = int1 < int2 < obj3
+ r4 = obj1 < 2 < 3
+ r5 = obj1 < 2 < 3 < 4
+ r6 = int1 < (int2 == int3) < int4
+ return r1, r2, r3, r4, r5, r6
+
+
+def const_cascade(x):
+ """
+ >>> const_cascade(2)
+ (True, False, True, False, False, True, False)
+ """
+ return (
+ 0 <= 1,
+ 1 <= 0,
+ 1 <= 1 <= 2,
+ 1 <= 0 < 1,
+ 1 <= 1 <= 0,
+ 1 <= 1 <= x <= 2 <= 3 > x <= 2 <= 2,
+ 1 <= 1 <= x <= 1 <= 1 <= x <= 2,
+ )