From 6633bf5aa146cc04479427a682fcfe43d14e85d9 Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Sun, 7 Dec 2008 21:14:13 +0100 Subject: [PATCH] fixed FlattenInListTransform by providing a temp block expression that injects the temp result into a subexpression --- Cython/Compiler/Main.py | 2 +- Cython/Compiler/Optimize.py | 13 +++---- Cython/Compiler/UtilNodes.py | 69 ++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 10 deletions(-) diff --git a/Cython/Compiler/Main.py b/Cython/Compiler/Main.py index 330e7554..14cc6a63 100644 --- a/Cython/Compiler/Main.py +++ b/Cython/Compiler/Main.py @@ -114,7 +114,7 @@ class Context: _specific_post_parse, InterpretCompilerDirectives(self, self.pragma_overrides), _align_function_definitions, -# FlattenInListTransform(), + FlattenInListTransform(), WithTransform(self), DecoratorTransform(self), AnalyseDeclarationsTransform(self), diff --git a/Cython/Compiler/Optimize.py b/Cython/Compiler/Optimize.py index d59b5765..a6c819b9 100644 --- a/Cython/Compiler/Optimize.py +++ b/Cython/Compiler/Optimize.py @@ -321,11 +321,7 @@ class FlattenInListTransform(Visitor.VisitorTransform, SkipDeclarations): if len(args) == 0: return ExprNodes.BoolNode(pos = node.pos, value = node.operator == 'not_in') - if True or node.operand1.is_simple(): - lhs = node.operand1 - else: - # FIXME: allocate temp for evaluated node.operand1 - return node + lhs = UtilNodes.ResultRefNode(node.operand1) conds = [] for arg in args: @@ -339,8 +335,6 @@ class FlattenInListTransform(Visitor.VisitorTransform, SkipDeclarations): pos = node.pos, operand = cond, type = PyrexTypes.c_bint_type)) - if type(lhs) is not ExprNodes.CloneNode: - lhs = ExprNodes.CloneNode(lhs) def concat(left, right): return ExprNodes.BoolBinopNode( pos = node.pos, @@ -348,8 +342,9 @@ class FlattenInListTransform(Visitor.VisitorTransform, SkipDeclarations): operand1 = left, operand2 = right) - return reduce(concat, conds) - + condition = reduce(concat, conds) + return UtilNodes.TempBlockExprNode(lhs, condition) + def visit_Node(self, node): self.visitchildren(node) return node diff --git a/Cython/Compiler/UtilNodes.py b/Cython/Compiler/UtilNodes.py index 3563d490..780b8c89 100644 --- a/Cython/Compiler/UtilNodes.py +++ b/Cython/Compiler/UtilNodes.py @@ -105,3 +105,72 @@ class TempsBlockNode(Node): def annotate(self, code): self.body.annotate(code) + +class ResultRefNode(AtomicExprNode): + # A reference to the result of an expression. The result_code + # must be set externally (usually a temp name). + + subexprs = [] + + def __init__(self, expression): + self.pos = expression.pos + self.expression = expression + + def analyse_types(self, env): + self.type = self.expression.type + + def result(self): + return self.result_code + + def generate_evaluation_code(self, code): + pass + + def generate_result_code(self, code): + pass + + def generate_disposal_code(self, code): + pass + + def allocate_temps(self, env): + pass + + def release_temp(self, env): + pass + + def free_temps(self, code): + pass + + +class TempBlockExprNode(ExprNodes.NewTempExprNode): + # A wrapper around a subexpression that moves an expression into a + # temp variable and provides it to the subexpression. + + subexprs = ['temp_expression', 'subexpression'] + + def __init__(self, lazy_temp, subexpression): + self.pos = subexpression.pos + self.lazy_temp = lazy_temp + self.temp_expression = lazy_temp.expression + self.subexpression = subexpression + + def result(self): + return self.subexpression.result() + + def analyse_types(self, env): + self.temp_expression.analyse_types(env) + self.subexpression.analyse_types(env) + self.type = self.subexpression.type + + def generate_evaluation_code(self, code): + self.temp_expression.generate_evaluation_code(code) + if self.temp_expression.is_temp: + temp = self.temp_expression.result() + else: + self.temp_expression.make_owned_reference(code) + temp = code.funcstate.allocate_temp( + self.temp_expression.type, manage_ref=True) + code.putln("%s = %s;" % (temp, self.temp_expression.result())) + self.lazy_temp.result_code = temp + self.subexpression.generate_evaluation_code(code) + if not self.temp_expression.is_temp: + code.funcstate.release_temp(temp) -- 2.26.2