Skip to content

Commit

Permalink
disable virtualization for arrays of structs, to be fixed by the virt…
Browse files Browse the repository at this point in the history
…ual-dicts branch. in practice this wasn't very useful because it only worked on empty dicts.
  • Loading branch information
alex committed Oct 23, 2011
1 parent 27c9500 commit ca68209
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 7 deletions.
7 changes: 6 additions & 1 deletion pypy/jit/backend/llgraph/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from pypy.rpython.ootypesystem import ootype
from pypy.rpython.llinterp import LLInterpreter
from pypy.jit.metainterp import history
from pypy.jit.metainterp.history import REF, INT, FLOAT
from pypy.jit.metainterp.history import REF, INT, FLOAT, STRUCT
from pypy.jit.metainterp.warmstate import unwrap
from pypy.jit.metainterp.resoperation import rop
from pypy.jit.backend import model
Expand Down Expand Up @@ -60,6 +60,9 @@ def is_array_of_pointers(self):
def is_array_of_floats(self):
return self.typeinfo == FLOAT

def is_array_of_structs(self):
return self.typeinfo == STRUCT

def as_vtable_size_descr(self):
return self

Expand Down Expand Up @@ -365,6 +368,8 @@ def arraydescrof(self, A):
size = symbolic.get_size(A)
if isinstance(A.OF, lltype.Ptr) or isinstance(A.OF, lltype.Primitive):
token = history.getkind(A.OF)[0]
elif isinstance(A.OF, lltype.Struct):
token = 's'
else:
token = '?'
return self.getdescr(size, token)
Expand Down
17 changes: 17 additions & 0 deletions pypy/jit/backend/llsupport/descr.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ def get_item_size(self, translate_support_code):

_is_array_of_pointers = False # unless overridden by GcPtrArrayDescr
_is_array_of_floats = False # unless overridden by FloatArrayDescr
_is_array_of_structs = False # unless overridden by StructArrayDescr
_is_item_signed = False # unless overridden by XxxArrayDescr

def is_array_of_pointers(self):
Expand All @@ -172,6 +173,9 @@ def is_array_of_pointers(self):
def is_array_of_floats(self):
return self._is_array_of_floats

def is_array_of_structs(self):
return self._is_array_of_structs

def is_item_signed(self):
return self._is_item_signed

Expand All @@ -196,6 +200,12 @@ def get_base_size(self, translate_support_code):
def get_item_size(self, translate_support_code):
return symbolic.get_size(lltype.Float, translate_support_code)

class StructArrayDescr(BaseArrayDescr):
_clsname = 'StructArrayDescr'
_is_array_of_structs = True
def get_item_size(self, translate_support_code):
return symbolic.get_size()

class BaseArrayNoLengthDescr(BaseArrayDescr):
def get_base_size(self, translate_support_code):
return 0
Expand All @@ -215,6 +225,13 @@ class GcPtrArrayNoLengthDescr(NonGcPtrArrayNoLengthDescr):
def getArrayDescrClass(ARRAY):
if ARRAY.OF is lltype.Float:
return FloatArrayDescr
elif isinstance(ARRAY.OF, lltype.Struct):
class Descr(StructArrayDescr):
_clsname = '%sArrayDescr' % ARRAY.OF._name
def get_item_size(self, translate_support_code):
return symbolic.get_size(ARRAY.OF, translate_support_code)
Descr.__name__ = Descr._clsname
return Descr
return getDescrClass(ARRAY.OF, BaseArrayDescr, GcPtrArrayDescr,
NonGcPtrArrayDescr, 'Array', 'get_item_size',
'_is_array_of_floats', '_is_item_signed')
Expand Down
6 changes: 6 additions & 0 deletions pypy/jit/metainterp/history.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
INT = 'i'
REF = 'r'
FLOAT = 'f'
STRUCT = 's'
HOLE = '_'
VOID = 'v'

Expand Down Expand Up @@ -172,6 +173,11 @@ def is_array_of_floats(self):
"""
raise NotImplementedError

def is_array_of_structs(self):
""" Implement for array descr
"""
raise NotImplementedError

def is_pointer_field(self):
""" Implement for field descr
"""
Expand Down
13 changes: 7 additions & 6 deletions pypy/jit/metainterp/optimizeopt/virtualize.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def _really_force(self, optforce):

def import_from(self, other, optimizer):
raise NotImplementedError("should not be called at this level")

def get_fielddescrlist_cache(cpu):
if not hasattr(cpu, '_optimizeopt_fielddescrlist_cache'):
result = descrlist_dict()
Expand Down Expand Up @@ -113,7 +113,7 @@ def _really_force(self, optforce):
#
if not we_are_translated():
op.name = 'FORCE ' + self.source_op.name

if self._is_immutable_and_filled_with_constants(optforce):
box = optforce.optimizer.constant_fold(op)
self.make_constant(box)
Expand Down Expand Up @@ -239,12 +239,12 @@ def force_at_end_of_preamble(self, already_forced, optforce):
for index in range(len(self._items)):
self._items[index] = self._items[index].force_at_end_of_preamble(already_forced, optforce)
return self

def _really_force(self, optforce):
assert self.source_op is not None
if not we_are_translated():
self.source_op.name = 'FORCE ' + self.source_op.name
optforce.emit_operation(self.source_op)
optforce.emit_operation(self.source_op)
self.box = box = self.source_op.result
for index in range(len(self._items)):
subvalue = self._items[index]
Expand Down Expand Up @@ -276,7 +276,7 @@ class OptVirtualize(optimizer.Optimization):

def new(self):
return OptVirtualize()

def make_virtual(self, known_class, box, source_op=None):
vvalue = VirtualValue(self.optimizer.cpu, known_class, box, source_op)
self.make_equal_to(box, vvalue)
Expand Down Expand Up @@ -386,7 +386,8 @@ def optimize_NEW(self, op):

def optimize_NEW_ARRAY(self, op):
sizebox = self.get_constant_box(op.getarg(0))
if sizebox is not None:
# For now we can't make arrays of structs virtual.
if sizebox is not None and not op.getdescr().is_array_of_structs():
# if the original 'op' did not have a ConstInt as argument,
# build a new one with the ConstInt argument
if not isinstance(op.getarg(0), ConstInt):
Expand Down
16 changes: 16 additions & 0 deletions pypy/jit/metainterp/test/test_ajit.py
Original file line number Diff line number Diff line change
Expand Up @@ -3452,6 +3452,22 @@ def f(n, x):
res = self.meta_interp(f, [10, 1])
assert res == 0

def test_virtual_array_of_structs(self):
myjitdriver = JitDriver(greens = [], reds=["n", "d"])
def f(n):
d = None
while n > 0:
myjitdriver.jit_merge_point(n=n, d=d)
d = {}
if n % 2:
d["k"] = n
else:
d["z"] = n
n -= len(d)
return n
res = self.meta_interp(f, [10])
assert res == 0



class TestLLtype(BaseLLtypeTests, LLJitMixin):
Expand Down

0 comments on commit ca68209

Please sign in to comment.