fix evaluation of assignment order when considering DefNode calls for inlining
authorStefan Behnel <stefan_ml@behnel.de>
Sat, 29 Dec 2012 16:25:51 +0000 (17:25 +0100)
committerStefan Behnel <stefan_ml@behnel.de>
Sat, 29 Dec 2012 16:25:51 +0000 (17:25 +0100)
Cython/Compiler/Optimize.py

index 815aeb1..4c60773 100644 (file)
@@ -1660,18 +1660,25 @@ class EarlyReplaceBuiltinCalls(Visitor.EnvTransform):
 class InlineDefNodeCalls(Visitor.EnvTransform):
     visit_Node = Visitor.VisitorTransform.recurse_to_children
 
+    def get_constant_value_node(self, name_node):
+        if not name_node.cf_state or not name_node.cf_state.is_single:
+            # no single assignment in the current scope
+            return None
+        entry = self.current_env().lookup(name_node.name)
+        if not entry or (not entry.cf_assignments
+                         or len(entry.cf_assignments) != 1):
+            # not just a single assignment in all closures
+            return None
+        return name_node.cf_state.one().rhs
+
     def visit_SimpleCallNode(self, node):
         self.visitchildren(node)
         if not self.current_directives.get('optimize.inline_defnode_calls'):
             return node
         function_name = node.function
-        if not function_name.is_name or function_name.cf_state is None:
-            return node
-        entry = self.current_env().lookup(function_name.name)
-        if not entry or (not entry.cf_assignments
-                         or len(entry.cf_assignments) != 1):
+        if not function_name.is_name:
             return node
-        function = entry.cf_assignments[0].rhs
+        function = self.get_constant_value_node(function_name)
         if not isinstance(function, ExprNodes.PyCFunctionNode):
             return node
         inlined = ExprNodes.InlinedDefNodeCallNode(