[pypy-svn] r35396 - in pypy/dist/pypy/rpython: . lltypesystem
mwh at codespeak.net
mwh at codespeak.net
Wed Dec 6 15:33:04 CET 2006
Author: mwh
Date: Wed Dec 6 15:33:01 2006
New Revision: 35396
Modified:
pypy/dist/pypy/rpython/lltypesystem/rpbc.py
pypy/dist/pypy/rpython/rpbc.py
Log:
first cut at trying to represent small (<4) sets of functions as indexes into
an array.
Modified: pypy/dist/pypy/rpython/lltypesystem/rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rpbc.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/rpbc.py Wed Dec 6 15:33:01 2006
@@ -4,15 +4,15 @@
from pypy.annotation import model as annmodel
from pypy.objspace.flow.model import Constant, Variable
from pypy.rpython.lltypesystem.lltype import \
- typeOf, Void, ForwardReference, Struct, Bool, \
- Ptr, malloc, nullptr
+ typeOf, Void, ForwardReference, Struct, Bool, Char, \
+ Ptr, malloc, nullptr, Array, Signed
from pypy.rpython.rmodel import Repr, TyperError, inputconst, inputdesc
from pypy.rpython.rpbc import samesig,\
commonbase, allattributenames, adjust_shape, \
AbstractClassesPBCRepr, AbstractMethodsPBCRepr, OverriddenFunctionPBCRepr, \
AbstractMultipleFrozenPBCRepr, MethodOfFrozenPBCRepr, \
AbstractFunctionsPBCRepr, AbstractMultipleUnrelatedFrozenPBCRepr, \
- SingleFrozenPBCRepr, none_frozen_pbc_repr
+ SingleFrozenPBCRepr, none_frozen_pbc_repr, get_concrete_calltable
from pypy.rpython.lltypesystem import rclass, llmemory
from pypy.tool.sourcetools import has_varargs
@@ -112,7 +112,108 @@
def get_specfunc_row(self, llop, v, c_rowname, resulttype):
return llop.genop('getfield', [v, c_rowname], resulttype=resulttype)
-
+
+class SmallFunctionSetPBCRepr(Repr):
+ def __init__(self, rtyper, s_pbc):
+ self.rtyper = rtyper
+ self.s_pbc = s_pbc
+ self.callfamily = s_pbc.descriptions.iterkeys().next().getcallfamily()
+ concretetable, uniquerows = get_concrete_calltable(self.rtyper,
+ self.callfamily)
+ assert len(uniquerows) == 1
+ self.lowleveltype = Char
+ self.pointer_repr = FunctionsPBCRepr(rtyper, s_pbc)
+ self.descriptions = list(s_pbc.descriptions)
+ if self.s_pbc.can_be_None:
+ self.descriptions.insert(0, None)
+
+ def _setup_repr(self):
+ POINTER_TABLE = Array(self.pointer_repr.lowleveltype)
+ pointer_table = malloc(POINTER_TABLE, len(self.descriptions),
+ immortal=True)
+ for i, desc in enumerate(self.descriptions):
+ pointer_table[i] = self.pointer_repr.convert_desc(desc)
+ self.c_pointer_table = inputconst(Ptr(POINTER_TABLE), pointer_table)
+
+ def get_s_callable(self):
+ return self.s_pbc
+
+ def get_r_implfunc(self):
+ return self, 0
+
+ def get_s_signatures(self, shape):
+ funcdesc = self.s_pbc.descriptions.iterkeys().next()
+ return funcdesc.get_s_signatures(shape)
+
+ def convert_desc(self, funcdesc):
+ return chr(self.descriptions.index(funcdesc))
+
+ def convert_const(self, value):
+ if isinstance(value, types.MethodType) and value.im_self is None:
+ value = value.im_func # unbound method -> bare function
+ if value is None:
+ return chr(0)
+ funcdesc = self.rtyper.annotator.bookkeeper.getdesc(value)
+ return self.convert_desc(funcdesc)
+
+## def convert_to_concrete_llfn(self, v, shape, index, llop):
+## return v
+
+ def rtype_simple_call(self, hop):
+ v_index = hop.inputarg(self, arg=0)
+ v_ptr = hop.llops.convertvar(v_index, self, self.pointer_repr)
+ hop2 = hop.copy()
+ hop2.args_r[0] = self.pointer_repr
+ hop2.args_v[0] = v_ptr
+ return hop2.dispatch()
+
+ rtype_call_args = rtype_simple_call
+
+class __extend__(pairtype(SmallFunctionSetPBCRepr, FunctionsPBCRepr)):
+ def convert_from_to((r_set, r_ptr), v, llops):
+ if r_ptr.lowleveltype is Void:
+ wrapper = HalfConcreteWrapper(r_ptr.get_unique_llfn)
+ return inputconst(Void, wrapper)
+ else:
+ v_int = llops.genop('cast_char_to_int', [v],
+ resulttype=Signed)
+ return llops.genop('getarrayitem', [r_set.c_pointer_table, v_int],
+ resulttype=r_ptr.lowleveltype)
+
+class __extend__(pairtype(FunctionsPBCRepr, SmallFunctionSetPBCRepr)):
+ def convert_from_to((r_ptr, r_set), v, llops):
+ assert r_ptr.lowleveltype is Void
+ desc, = r_ptr.s_pbc.descriptions
+ return inputconst(Char, r_set.convert_desc(desc))
+
+_conversion_tables = {}
+def conversion_table(r_from, r_to):
+ key = r_from, r_to
+ if key in _conversion_tables:
+ return _conversion_tables[key]
+ else:
+ t = malloc(Array(Char), len(r_from.descriptions), immortal=True)
+ l = []
+ for i, d in enumerate(r_from.descriptions):
+ j = r_to.descriptions.index(d)
+ l.append(j)
+ t[i] = chr(j)
+ if l == range(len(r_from.descriptions)):
+ r = None
+ else:
+ r = inputconst(Ptr(Array(Char)), t)
+ _conversion_tables[key] = r
+ return r
+
+class __extend__(pairtype(SmallFunctionSetPBCRepr, SmallFunctionSetPBCRepr)):
+ def convert_from_to((r_from, r_to), v, llops):
+ c_table = conversion_table(r_from, r_to)
+ if c_table:
+ return llops.genop('getarrayitem', [c_table, v],
+ resulttype=lltype.Char)
+ else:
+ return v
+
class MethodsPBCRepr(AbstractMethodsPBCRepr):
"""Representation selected for a PBC of the form {func: classdef...}.
It assumes that all the methods come from the same name in a base
@@ -128,7 +229,8 @@
r_class = self.r_im_self.rclass
mangled_name, r_func = r_class.clsfields[self.methodname]
assert isinstance(r_func, (FunctionsPBCRepr,
- OverriddenFunctionPBCRepr))
+ OverriddenFunctionPBCRepr,
+ SmallFunctionSetPBCRepr))
# s_func = r_func.s_pbc -- not precise enough, see
# test_precise_method_call_1. Build a more precise one...
funcdescs = [desc.funcdesc for desc in hop.args_s[0].descriptions]
Modified: pypy/dist/pypy/rpython/rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/rpbc.py (original)
+++ pypy/dist/pypy/rpython/rpbc.py Wed Dec 6 15:33:01 2006
@@ -27,6 +27,13 @@
getRepr = OverriddenFunctionPBCRepr
else:
getRepr = rtyper.type_system.rpbc.FunctionsPBCRepr
+ if rtyper.getconfig().translation.withsmallfuncsets and \
+ 1 < len(self.descriptions) < 4 and \
+ hasattr(rtyper.type_system.rpbc, 'SmallFunctionSetPBCRepr'):
+ callfamily = self.descriptions.iterkeys().next().getcallfamily()
+ concretetable, uniquerows = get_concrete_calltable(rtyper, callfamily)
+ if len(uniquerows) == 1:
+ getRepr = rtyper.type_system.rpbc.SmallFunctionSetPBCRepr
else:
getRepr = getFrozenPBCRepr
elif issubclass(kind, description.ClassDesc):
More information about the Pypy-commit
mailing list