From: Dag Sverre Seljebotn Date: Sun, 20 Jul 2008 11:10:22 +0000 (+0200) Subject: Optimize refcounting for cdef assignments (like it was) X-Git-Tag: 0.9.8.1~49^2~86 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=35b2180b2fa097673f3b69e904b036e2aeddcd8c;p=cython.git Optimize refcounting for cdef assignments (like it was) --- diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index dd00df9d..4f02ef1e 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -809,6 +809,7 @@ class NameNode(AtomicExprNode): # interned_cname string is_name = 1 + skip_assignment_decref = False def create_analysed_rvalue(pos, env, entry): node = NameNode(pos) @@ -1030,7 +1031,7 @@ class NameNode(AtomicExprNode): rhs.generate_disposal_code(code) else: - if self.type.is_pyobject: + if self.type.is_pyobject and not self.skip_assignment_decref: #print "NameNode.generate_assignment_code: to", self.name ### #print "...from", rhs ### #print "...LHS type", self.type, "ctype", self.ctype() ### diff --git a/Cython/Compiler/Main.py b/Cython/Compiler/Main.py index dfe10a24..ea2ed78d 100644 --- a/Cython/Compiler/Main.py +++ b/Cython/Compiler/Main.py @@ -359,7 +359,7 @@ def create_default_pipeline(context, options, result): from ParseTreeTransforms import WithTransform, NormalizeTree, PostParse from ParseTreeTransforms import AnalyseDeclarationsTransform, AnalyseExpressionsTransform from ParseTreeTransforms import CreateClosureClasses, MarkClosureVisitor, DecoratorTransform - from Optimize import FlattenInListTransform, SwitchTransform + from Optimize import FlattenInListTransform, SwitchTransform, OptimizeRefcounting from Buffer import BufferTransform from ModuleNode import check_c_classes @@ -374,7 +374,8 @@ def create_default_pipeline(context, options, result): check_c_classes, AnalyseExpressionsTransform(context), BufferTransform(context), - SwitchTransform(), + SwitchTransform(), + OptimizeRefcounting(context), # CreateClosureClasses(context), create_generate_code(context, options, result) ] diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index c5e0487e..14e15ede 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -2231,8 +2231,10 @@ class SingleAssignmentNode(AssignmentNode): # # lhs ExprNode Left hand side # rhs ExprNode Right hand side + # first bool Is this guaranteed the first assignment to lhs? child_attrs = ["lhs", "rhs"] + first = False def analyse_declarations(self, env): self.lhs.analyse_target_declaration(env) @@ -2265,7 +2267,7 @@ class SingleAssignmentNode(AssignmentNode): # self.lhs.allocate_target_temps(env) # self.lhs.release_target_temp(env) # self.rhs.release_temp(env) - + def generate_rhs_evaluation_code(self, code): self.rhs.generate_evaluation_code(code) diff --git a/Cython/Compiler/Optimize.py b/Cython/Compiler/Optimize.py index ae4dbcc9..eb4195a1 100644 --- a/Cython/Compiler/Optimize.py +++ b/Cython/Compiler/Optimize.py @@ -134,3 +134,16 @@ class FlattenInListTransform(Visitor.VisitorTransform): def visit_Node(self, node): self.visitchildren(node) return node + + +class OptimizeRefcounting(Visitor.CythonTransform): + def visit_SingleAssignmentNode(self, node): + if node.first: + lhs = node.lhs + if isinstance(lhs, ExprNodes.NameNode) and lhs.entry.type.is_pyobject: + # Have variable initialized to 0 rather than None + lhs.entry.init_to_none = False + lhs.entry.init = 0 + # Set a flag in NameNode to skip the decref + lhs.skip_assignment_decref = True + return node diff --git a/Cython/Compiler/ParseTreeTransforms.py b/Cython/Compiler/ParseTreeTransforms.py index 81eeecf8..5d6a03f9 100644 --- a/Cython/Compiler/ParseTreeTransforms.py +++ b/Cython/Compiler/ParseTreeTransforms.py @@ -138,7 +138,7 @@ class PostParse(CythonTransform): raise PostParseError(decl.pos, ERR_CDEF_INCLASS) stats.append(SingleAssignmentNode(node.pos, lhs=NameNode(node.pos, name=decl.name), - rhs=decl.default)) + rhs=decl.default, first=True)) decl.default = None return stats