From: Stefan Behnel Date: Thu, 7 Feb 2013 17:59:43 +0000 (+0100) Subject: reimplement SimplifyCalls transform in-place in GeneralCallNode.analyse_types() X-Git-Tag: 0.19b1~226 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9b0031737a1523ba4fad0131804ace547cb20450;p=platform%2Fupstream%2Fpython-cython.git reimplement SimplifyCalls transform in-place in GeneralCallNode.analyse_types() --- diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 5ece4e9..6ee1d05 100755 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -4313,7 +4313,6 @@ class GeneralCallNode(CallNode): # keyword_args ExprNode or None Dict of keyword arguments type = py_object_type - is_simple_call = False subexprs = ['function', 'positional_args', 'keyword_args'] @@ -4344,8 +4343,10 @@ class GeneralCallNode(CallNode): self.type = error_type return self if hasattr(self.function, 'entry'): - self.map_keywords_to_posargs() - if not self.is_simple_call: + node = self.map_keywords_to_posargs(env) + if node is not None: + return node.analyse_types(env) + else: if self.function.entry.as_variable: self.function = self.function.coerce_to_pyobject(env) else: @@ -4370,17 +4371,17 @@ class GeneralCallNode(CallNode): self.is_temp = 1 return self - def map_keywords_to_posargs(self): + def map_keywords_to_posargs(self, env): if not isinstance(self.positional_args, TupleNode): # has starred argument - return + return None if not isinstance(self.keyword_args, DictNode): # nothing to do here - return + return None function = self.function entry = getattr(function, 'entry', None) if not entry or not entry.is_cfunction: - return + return None args = self.positional_args.args kwargs = self.keyword_args @@ -4389,7 +4390,7 @@ class GeneralCallNode(CallNode): # will lead to an error elsewhere error(self.pos, "function call got too many positional arguments, " "expected %d, got %s" % (len(declared_args), len(args))) - return + return None matched_pos_args = set([arg.name for arg in declared_args[:len(args)]]) unmatched_args = declared_args[len(args):] @@ -4401,7 +4402,7 @@ class GeneralCallNode(CallNode): name = arg.key.value if name in matched_pos_args: error(arg.pos, "keyword argument '%s' passed twice" % name) - return + return None if decl_arg.name == name: matched_kwargs.add(name) args.append(arg.value) @@ -4427,15 +4428,17 @@ class GeneralCallNode(CallNode): # into ordered temps if necessary if not matched_kwargs: - return + return None self.positional_args.args = args if len(kwargs.key_value_pairs) == len(matched_kwargs): - self.keyword_args = None - self.is_simple_call = True - else: - kwargs.key_value_pairs = [ - item for item in kwargs.key_value_pairs - if item.key.value not in matched_kwargs ] + # all keywords mapped => only positional arguments left + return SimpleCallNode( + self.pos, function=function, args=args) + + kwargs.key_value_pairs = [ + item for item in kwargs.key_value_pairs + if item.key.value not in matched_kwargs ] + return None def generate_result_code(self, code): if self.type.is_error: return diff --git a/Cython/Compiler/Optimize.py b/Cython/Compiler/Optimize.py index 6ba0dd8..d9b4965 100644 --- a/Cython/Compiler/Optimize.py +++ b/Cython/Compiler/Optimize.py @@ -1173,27 +1173,6 @@ class DropRefcountingTransform(Visitor.VisitorTransform): return (base.name, index_val) -class SimplifyCalls(Visitor.EnvTransform): - """ - Replace GeneralCallNode by SimpleCallNode if possible. - """ - def visit_GeneralCallNode(self, node): - self.visitchildren(node) - if not node.is_simple_call: - return node - args = [ unwrap_coerced_node(arg) - for arg in node.positional_args.args ] - call_node = ExprNodes.SimpleCallNode( - node.pos, - function=node.function, - args=args) - call_node = call_node.analyse_types(self.current_env()) - if node.type != call_node.type: - call_node = call_node.coerce_to( - node.type, self.current_env()) - return call_node - - class EarlyReplaceBuiltinCalls(Visitor.EnvTransform): """Optimize some common calls to builtin types *before* the type analysis phase and *after* the declarations analysis phase. diff --git a/Cython/Compiler/Pipeline.py b/Cython/Compiler/Pipeline.py index 55588fb..b945fce 100644 --- a/Cython/Compiler/Pipeline.py +++ b/Cython/Compiler/Pipeline.py @@ -141,7 +141,7 @@ def create_pipeline(context, mode, exclude_classes=()): from AutoDocTransforms import EmbedSignature from Optimize import FlattenInListTransform, SwitchTransform, IterationTransform from Optimize import EarlyReplaceBuiltinCalls, OptimizeBuiltinCalls - from Optimize import InlineDefNodeCalls, SimplifyCalls + from Optimize import InlineDefNodeCalls from Optimize import ConstantFolding, FinalOptimizePhase from Optimize import DropRefcountingTransform from Optimize import ConsolidateOverflowCheck @@ -193,7 +193,6 @@ def create_pipeline(context, mode, exclude_classes=()): _check_c_declarations, InlineDefNodeCalls(context), AnalyseExpressionsTransform(context), - SimplifyCalls(context), FindInvalidUseOfFusedTypes(context), CreateClosureClasses(context), ## After all lookups and type inference ExpandInplaceOperators(context),