Optimize refcounting for cdef assignments (like it was)
authorDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Sun, 20 Jul 2008 11:10:22 +0000 (13:10 +0200)
committerDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Sun, 20 Jul 2008 11:10:22 +0000 (13:10 +0200)
Cython/Compiler/ExprNodes.py
Cython/Compiler/Main.py
Cython/Compiler/Nodes.py
Cython/Compiler/Optimize.py
Cython/Compiler/ParseTreeTransforms.py

index dd00df9db287987bd3d5a5f753254a5874c47d17..4f02ef1eab18e1ff03ca5735f3629f81aff5b28e 100644 (file)
@@ -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() ###
index dfe10a24612139368c5cb2686e95d703b6162221..ea2ed78d711ff8bd1f967417206e28b17600c74b 100644 (file)
@@ -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)
     ]
index c5e0487e949c8723f420295a98071ed293106ece..14e15ede61544b4c57fa7137675f686ddb5d3bbf 100644 (file)
@@ -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)
     
index ae4dbcc9239e426406a3495f59faf487427fa7cc..eb4195a1f443d0caf8500f9d888d25fe4fb248d5 100644 (file)
@@ -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
index 81eeecf84d9e546cdea028e245250b204881a950..5d6a03f9c68d5d283bed2c0df307e28713145144 100644 (file)
@@ -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