Author: Ronan Lamy <ronan.l...@gmail.com> Branch: Changeset: r76264:4b7d6f8bc860 Date: 2015-03-07 01:57 +0000 http://bitbucket.org/pypy/pypy/changeset/4b7d6f8bc860/
Log: merge branch 'online-transforms-2' diff --git a/rpython/annotator/annrpython.py b/rpython/annotator/annrpython.py --- a/rpython/annotator/annrpython.py +++ b/rpython/annotator/annrpython.py @@ -399,12 +399,22 @@ def flowin(self, graph, block): try: - for i, op in enumerate(block.operations): + i = 0 + while i < len(block.operations): + op = block.operations[i] self.bookkeeper.enter((graph, block, i)) try: + new_ops = op.transform(self) + if new_ops is not None: + block.operations[i:i+1] = new_ops + if not new_ops: + continue + new_ops[-1].result = op.result + op = new_ops[0] self.consider_op(op) finally: self.bookkeeper.leave() + i += 1 except BlockedInference as e: if e.op is block.raising_op: diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py --- a/rpython/annotator/binaryop.py +++ b/rpython/annotator/binaryop.py @@ -2,7 +2,6 @@ Binary operations between SomeValues. """ -import operator from rpython.tool.pairtype import pair, pairtype from rpython.annotator.model import ( SomeObject, SomeInteger, SomeBool, s_Bool, SomeString, SomeChar, SomeList, @@ -14,7 +13,7 @@ read_can_only_throw, add_knowntypedata, merge_knowntypedata,) from rpython.annotator.bookkeeper import immutablevalue -from rpython.flowspace.model import Variable, Constant +from rpython.flowspace.model import Variable, Constant, const from rpython.flowspace.operation import op from rpython.rlib import rarithmetic from rpython.annotator.model import AnnotatorError @@ -689,12 +688,16 @@ return super(thistype, pair(ins1, ins2)).improve() -class __extend__(pairtype(SomeInstance, SomeObject)): - def getitem((s_ins, s_idx)): - return s_ins._emulate_call("__getitem__", s_idx) +@op.getitem.register_transform(SomeInstance, SomeObject) +def getitem_SomeInstance(annotator, v_ins, v_idx): + get_getitem = op.getattr(v_ins, const('__getitem__')) + return [get_getitem, op.simple_call(get_getitem.result, v_idx)] - def setitem((s_ins, s_idx), s_value): - return s_ins._emulate_call("__setitem__", s_idx, s_value) +@op.setitem.register_transform(SomeInstance, SomeObject) +def setitem_SomeInstance(annotator, v_ins, v_idx, v_value): + get_setitem = op.getattr(v_ins, const('__setitem__')) + return [get_setitem, + op.simple_call(get_setitem.result, v_idx, v_value)] class __extend__(pairtype(SomeIterator, SomeIterator)): diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py --- a/rpython/annotator/unaryop.py +++ b/rpython/annotator/unaryop.py @@ -5,6 +5,7 @@ from __future__ import absolute_import from rpython.flowspace.operation import op +from rpython.flowspace.model import const from rpython.annotator.model import (SomeObject, SomeInteger, SomeBool, SomeString, SomeChar, SomeList, SomeDict, SomeTuple, SomeImpossibleValue, SomeUnicodeCodePoint, SomeInstance, SomeBuiltin, SomeBuiltinMethod, @@ -686,27 +687,33 @@ if not self.can_be_None: s.const = True - def _emulate_call(self, meth_name, *args_s): - bk = getbookkeeper() - s_attr = self._true_getattr(meth_name) - # record for calltables - bk.emulate_pbc_call(bk.position_key, s_attr, args_s) - return s_attr.call(simple_args(args_s)) +@op.len.register_transform(SomeInstance) +def len_SomeInstance(annotator, v_arg): + get_len = op.getattr(v_arg, const('__len__')) + return [get_len, op.simple_call(get_len.result)] - def iter(self): - return self._emulate_call('__iter__') +@op.iter.register_transform(SomeInstance) +def iter_SomeInstance(annotator, v_arg): + get_iter = op.getattr(v_arg, const('__iter__')) + return [get_iter, op.simple_call(get_iter.result)] - def next(self): - return self._emulate_call('next') +@op.next.register_transform(SomeInstance) +def next_SomeInstance(annotator, v_arg): + get_next = op.getattr(v_arg, const('next')) + return [get_next, op.simple_call(get_next.result)] - def len(self): - return self._emulate_call('__len__') +@op.getslice.register_transform(SomeInstance) +def getslice_SomeInstance(annotator, v_obj, v_start, v_stop): + get_getslice = op.getattr(v_obj, const('__getslice__')) + return [get_getslice, op.simple_call(get_getslice.result, v_start, v_stop)] - def getslice(self, s_start, s_stop): - return self._emulate_call('__getslice__', s_start, s_stop) - def setslice(self, s_start, s_stop, s_iterable): - return self._emulate_call('__setslice__', s_start, s_stop, s_iterable) +@op.setslice.register_transform(SomeInstance) +def setslice_SomeInstance(annotator, v_obj, v_start, v_stop, v_iterable): + get_setslice = op.getattr(v_obj, const('__setslice__')) + return [get_setslice, + op.simple_call(get_setslice.result, v_start, v_stop, v_iterable)] + class __extend__(SomeBuiltin): def call(self, args, implicit_init=False): diff --git a/rpython/flowspace/operation.py b/rpython/flowspace/operation.py --- a/rpython/flowspace/operation.py +++ b/rpython/flowspace/operation.py @@ -57,8 +57,10 @@ setattr(op, cls.opname, cls) if cls.dispatch == 1: cls._registry = {} + cls._transform = {} elif cls.dispatch == 2: cls._registry = DoubleDispatchRegistry() + cls._transform = DoubleDispatchRegistry() class HLOperation(SpaceOperation): @@ -104,6 +106,14 @@ def get_can_only_throw(self, annotator): return None + def get_transformer(self, *args_s): + return lambda *args: None + + def transform(self, annotator): + args_s = [annotator.annotation(arg) for arg in self.args] + transformer = self.get_transformer(*args_s) + return transformer(annotator, *self.args) + class PureOperation(HLOperation): pure = True @@ -185,6 +195,37 @@ except AttributeError: return cls._dispatch(type(s_arg)) + @classmethod + def get_specialization(cls, s_arg, *_ignored): + try: + impl = getattr(s_arg, cls.opname) + + def specialized(annotator, arg, *other_args): + return impl(*[annotator.annotation(x) for x in other_args]) + try: + specialized.can_only_throw = impl.can_only_throw + except AttributeError: + pass + return specialized + except AttributeError: + return cls._dispatch(type(s_arg)) + + @classmethod + def register_transform(cls, Some_cls): + def decorator(func): + cls._transform[Some_cls] = func + return func + return decorator + + @classmethod + def get_transformer(cls, s_arg, *_ignored): + for c in type(s_arg).__mro__: + try: + return cls._transform[c] + except KeyError: + pass + return lambda *args: None + class DoubleDispatchMixin(object): dispatch = 2 @@ -216,6 +257,20 @@ spec = type(self).get_specialization(*args_s) return read_can_only_throw(spec, args_s[0], args_s[1]) + @classmethod + def register_transform(cls, Some1, Some2): + def decorator(func): + cls._transform[Some1, Some2] = func + return func + return decorator + + @classmethod + def get_transformer(cls, s_arg1, s_arg2, *_ignored): + try: + return cls._transform[type(s_arg1), type(s_arg2)] + except KeyError: + return lambda *args: None + def add_operator(name, arity, dispatch=None, pyfunc=None, pure=False, ovf=False): operator_func = getattr(operator, name, None) diff --git a/rpython/rtyper/rclass.py b/rpython/rtyper/rclass.py --- a/rpython/rtyper/rclass.py +++ b/rpython/rtyper/rclass.py @@ -820,40 +820,6 @@ vinst, = hop.inputargs(self) return hop.genop('ptr_nonzero', [vinst], resulttype=Bool) - def _emulate_call(self, hop, meth_name): - vinst = hop.args_v[0] - clsdef = hop.args_s[0].classdef - s_unbound_attr = clsdef.find_attribute(meth_name).getvalue() - s_attr = clsdef.lookup_filter(s_unbound_attr, meth_name, - hop.args_s[0].flags) - # does that even happen? - assert not s_attr.is_constant() - if '__iter__' in self.allinstancefields: - raise Exception("__iter__ on instance disallowed") - r_method = self.rtyper.getrepr(s_attr) - r_method.get_method_from_instance(self, vinst, hop.llops) - hop2 = hop.copy() - hop2.spaceop = op.simple_call(*hop.spaceop.args) - hop2.spaceop.result = hop.spaceop.result - hop2.args_r[0] = r_method - hop2.args_s[0] = s_attr - return hop2.dispatch() - - def rtype_iter(self, hop): - return self._emulate_call(hop, '__iter__') - - def rtype_next(self, hop): - return self._emulate_call(hop, 'next') - - def rtype_getslice(self, hop): - return self._emulate_call(hop, "__getslice__") - - def rtype_setslice(self, hop): - return self._emulate_call(hop, "__setslice__") - - def rtype_len(self, hop): - return self._emulate_call(hop, "__len__") - def ll_str(self, i): # doesn't work for non-gc classes! from rpython.rtyper.lltypesystem.ll_str import ll_int2hex from rpython.rlib.rarithmetic import r_uint @@ -1023,14 +989,6 @@ return hop.gendirectcall(ll_isinstance, v_obj, v_cls) -class __extend__(pairtype(InstanceRepr, Repr)): - def rtype_getitem((r_ins, r_obj), hop): - return r_ins._emulate_call(hop, "__getitem__") - - def rtype_setitem((r_ins, r_obj), hop): - return r_ins._emulate_call(hop, "__setitem__") - - class __extend__(pairtype(InstanceRepr, InstanceRepr)): def convert_from_to((r_ins1, r_ins2), v, llops): # which is a subclass of which? _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit