Commit 1d7072f1 authored by Stefan Behnel's avatar Stefan Behnel

rely on code generation phase to include required utility code instead of...

rely on code generation phase to include required utility code instead of always including all of it in a separate pipeline phase
parent a767e7e8
...@@ -5277,7 +5277,8 @@ class SimpleCallNode(CallNode): ...@@ -5277,7 +5277,8 @@ class SimpleCallNode(CallNode):
self.type = func_type.return_type self.type = func_type.return_type
if self.function.is_name or self.function.is_attribute: if self.function.is_name or self.function.is_attribute:
if self.function.entry and self.function.entry.utility_code: func_entry = self.function.entry
if func_entry and (func_entry.utility_code or func_entry.utility_code_definition):
self.is_temp = 1 # currently doesn't work for self.calculate_result_code() self.is_temp = 1 # currently doesn't work for self.calculate_result_code()
if self.type.is_pyobject: if self.type.is_pyobject:
...@@ -5345,8 +5346,7 @@ class SimpleCallNode(CallNode): ...@@ -5345,8 +5346,7 @@ class SimpleCallNode(CallNode):
def generate_result_code(self, code): def generate_result_code(self, code):
func_type = self.function_type() func_type = self.function_type()
if self.function.is_name or self.function.is_attribute: if self.function.is_name or self.function.is_attribute:
if self.function.entry and self.function.entry.utility_code: code.globalstate.use_entry_utility_code(self.function.entry)
code.globalstate.use_utility_code(self.function.entry.utility_code)
if func_type.is_pyobject: if func_type.is_pyobject:
if func_type is not type_type and not self.arg_tuple.args and self.arg_tuple.is_literal: if func_type is not type_type and not self.arg_tuple.args and self.arg_tuple.is_literal:
code.globalstate.use_utility_code(UtilityCode.load_cached( code.globalstate.use_utility_code(UtilityCode.load_cached(
...@@ -6609,9 +6609,9 @@ class AttributeNode(ExprNode): ...@@ -6609,9 +6609,9 @@ class AttributeNode(ExprNode):
# a check and raise an exception # a check and raise an exception
if self.obj.type.is_extension_type: if self.obj.type.is_extension_type:
pass pass
elif self.entry and self.entry.is_cmethod and self.entry.utility_code: elif self.entry and self.entry.is_cmethod:
# C method implemented as function call with utility code # C method implemented as function call with utility code
code.globalstate.use_utility_code(self.entry.utility_code) code.globalstate.use_entry_utility_code(self.entry)
def generate_disposal_code(self, code): def generate_disposal_code(self, code):
if self.is_temp and self.type.is_memoryviewslice and self.is_memslice_transpose: if self.is_temp and self.type.is_memoryviewslice and self.is_memslice_transpose:
......
...@@ -134,30 +134,6 @@ def inject_utility_code_stage_factory(context): ...@@ -134,30 +134,6 @@ def inject_utility_code_stage_factory(context):
return inject_utility_code_stage return inject_utility_code_stage
class UseUtilityCodeDefinitions(CythonTransform):
# Temporary hack to use any utility code in nodes' "utility_code_definitions".
# This should be moved to the code generation phase of the relevant nodes once
# it is safe to generate CythonUtilityCode at code generation time.
def __call__(self, node):
self.scope = node.scope
return super(UseUtilityCodeDefinitions, self).__call__(node)
def process_entry(self, entry):
if entry:
for utility_code in (entry.utility_code, entry.utility_code_definition):
if utility_code:
self.scope.use_utility_code(utility_code)
def visit_AttributeNode(self, node):
self.process_entry(node.entry)
return node
def visit_NameNode(self, node):
self.process_entry(node.entry)
self.process_entry(node.type_entry)
return node
# #
# Pipeline factories # Pipeline factories
# #
...@@ -243,7 +219,6 @@ def create_pipeline(context, mode, exclude_classes=()): ...@@ -243,7 +219,6 @@ def create_pipeline(context, mode, exclude_classes=()):
DropRefcountingTransform(), DropRefcountingTransform(),
FinalOptimizePhase(context), FinalOptimizePhase(context),
GilCheck(), GilCheck(),
UseUtilityCodeDefinitions(context),
] ]
filtered_stages = [] filtered_stages = []
for s in stages: for s in stages:
......
...@@ -852,6 +852,9 @@ class Scope(object): ...@@ -852,6 +852,9 @@ class Scope(object):
def use_utility_code(self, new_code): def use_utility_code(self, new_code):
self.global_scope().use_utility_code(new_code) self.global_scope().use_utility_code(new_code)
def use_entry_utility_code(self, entry):
self.global_scope().use_entry_utility_code(entry)
def generate_library_function_declarations(self, code): def generate_library_function_declarations(self, code):
# Generate extern decls for C library funcs used. # Generate extern decls for C library funcs used.
pass pass
...@@ -1328,6 +1331,14 @@ class ModuleScope(Scope): ...@@ -1328,6 +1331,14 @@ class ModuleScope(Scope):
if new_code is not None: if new_code is not None:
self.utility_code_list.append(new_code) self.utility_code_list.append(new_code)
def use_entry_utility_code(self, entry):
if entry is None:
return
if entry.utility_code:
self.utility_code_list.append(entry.utility_code)
if entry.utility_code_definition:
self.utility_code_list.append(entry.utility_code_definition)
def declare_c_class(self, name, pos, defining = 0, implementing = 0, def declare_c_class(self, name, pos, defining = 0, implementing = 0,
module_name = None, base_type = None, objstruct_cname = None, module_name = None, base_type = None, objstruct_cname = None,
typeobj_cname = None, typeptr_cname = None, visibility = 'private', typedef_flag = 0, api = 0, typeobj_cname = None, typeptr_cname = None, visibility = 'private', typedef_flag = 0, api = 0,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment