[pypy-svn] r63419 - in pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp: . test
fijal at codespeak.net
fijal at codespeak.net
Sun Mar 29 21:34:23 CEST 2009
Author: fijal
Date: Sun Mar 29 21:34:20 2009
New Revision: 63419
Modified:
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/compile.py
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/optimize.py
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/specnode.py
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_virtualizable.py
Log:
Port one more fix from virtualizable-specnodes, less terrible than on the
branch
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/compile.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/compile.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/compile.py Sun Mar 29 21:34:20 2009
@@ -137,6 +137,9 @@
# ____________________________________________________________
+def update_loop(loop, spec):
+ pass
+
def compile_fresh_bridge(metainterp, old_loops, resumekey):
#temp = TreeLoop('temp')
#temp.operations = metainterp.history.operations
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/optimize.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/optimize.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/optimize.py Sun Mar 29 21:34:20 2009
@@ -162,6 +162,8 @@
assert other.virtualized
assert self is other
offsets = self.allfields
+ if offsets is None:
+ return None
sort_descrs(offsets)
fields = []
for ofs in offsets:
@@ -217,8 +219,14 @@
perfect_specializer.find_nodes()
for old_loop in old_loops:
if perfect_specializer.match(old_loop):
- perfect_specializer.adapt_for_match(old_loop)
+ # xxx slow, maybe
+ for node in perfect_specializer.nodes.values():
+ if node.startbox:
+ node.cls = None
+ assert not node.virtual
+ ofs = perfect_specializer.adapt_for_match(old_loop)
perfect_specializer.optimize_loop()
+ perfect_specializer.update_loop(ofs, old_loop)
return old_loop
return None # no loop matches
@@ -436,14 +444,13 @@
specnodes.append(enternode.intersect(leavenode, self.nodes))
self.specnodes = specnodes
- def expanded_version_of(self, boxlist, oplist):
- # oplist is None means at the start
+ def expanded_version_of(self, boxlist):
newboxlist = []
assert len(boxlist) == len(self.specnodes)
for i in range(len(boxlist)):
box = boxlist[i]
specnode = self.specnodes[i]
- specnode.expand_boxlist(self.nodes[box], newboxlist, oplist)
+ specnode.expand_boxlist(self.nodes[box], newboxlist)
return newboxlist
def prepare_rebuild_ops(self, instnode, rebuild_ops, memo):
@@ -572,7 +579,9 @@
return True
# this means field comes from a virtualizable but is never
# written.
- self.nodes[box] = InstanceNode(box)
+ node = InstanceNode(box)
+ self.nodes[box] = node
+ instnode.curfields[ofs] = node
return True
#if ofs in instnode.cleanfields:
# self.nodes[box] = instnode.cleanfields[ofs]
@@ -604,20 +613,15 @@
for i in range(len(self.specnodes)):
box = self.history.inputargs[i]
self.specnodes[i].mutate_nodes(self.nodes[box])
- newinputargs = self.expanded_version_of(self.history.inputargs,
- None)
+ newinputargs = self.expanded_version_of(self.history.inputargs)
else:
# making a bridge
- for node in self.nodes.values(): # xxx slow, maybe
- if node.startbox:
- node.cls = None
- assert not node.virtual
newinputargs = None
#
for op in self.history.operations:
opnum = op.opnum
if opnum == rop.JUMP:
- args = self.expanded_version_of(op.args, newoperations)
+ args = self.expanded_version_of(op.args)
for arg in args:
if arg in self.nodes:
assert not self.nodes[arg].virtual
@@ -821,10 +825,59 @@
jump_op = self.history.operations[-1]
assert jump_op.opnum == rop.JUMP
self.specnodes = old_loop.specnodes
+ all_offsets = []
for i in range(len(old_loop.specnodes)):
old_specnode = old_loop.specnodes[i]
new_instnode = self.getnode(jump_op.args[i])
- old_specnode.adapt_to(new_instnode)
+ offsets = []
+ old_specnode.adapt_to(new_instnode, offsets)
+ all_offsets.append(offsets)
+ return all_offsets
+
+ def update_loop(self, offsets, loop):
+ j = 0
+ new_inputargs = []
+ new_jumpargs = []
+ if loop.operations[-1].jump_target is loop:
+ patch_jump = True
+ jumpargs = loop.operations[-1].args
+ else:
+ patch_jump = False
+ jumpargs = []
+ prev_ofs = 0
+ rebuild_ops = []
+ memo = {}
+ for i in range(len(offsets)):
+ for specnode, descr, parentnode, rel_ofs, node in offsets[i]:
+ while parentnode.source != loop.inputargs[j]:
+ j += 1
+ ofs = j + rel_ofs + 1
+ new_inputargs.extend(loop.inputargs[prev_ofs:ofs])
+ if patch_jump:
+ new_jumpargs.extend(jumpargs[prev_ofs:ofs])
+ prev_ofs = ofs
+ boxlist = []
+ specnode.expand_boxlist(node, boxlist)
+ new_inputargs.extend(boxlist)
+ new_jumpargs.extend(boxlist)
+ box = self.prepare_rebuild_ops(node, rebuild_ops, memo)
+ if (parentnode.cls and
+ isinstance(parentnode.cls.source, FixedList)):
+ rebuild_ops.append(ResOperation(rop.SETARRAYITEM_GC,
+ [parentnode.source, descr, box], None,
+ parentnode.cls.source.arraydescr))
+ else:
+ rebuild_ops.append(ResOperation(rop.SETFIELD_GC,
+ [parentnode.source, box], None, descr))
+ new_inputargs.extend(loop.inputargs[prev_ofs:])
+ loop.inputargs = new_inputargs
+ if patch_jump:
+ new_jumpargs.extend(loop.operations[-1].args[prev_ofs:])
+ loop.operations[-1].args = new_jumpargs
+ for op in loop.operations:
+ if op.is_guard():
+ op.suboperations = (op.suboperations[:-1] + rebuild_ops +
+ [op.suboperations[-1]])
def get_in_list(dict, boxes_or_consts):
result = []
@@ -851,6 +904,7 @@
## # done
## return [currentvalues[box] for box in guard_op.unoptboxes]
+# ---------------------------------------------------------------
def partition(array, left, right):
last_item = array[right]
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/specnode.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/specnode.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/specnode.py Sun Mar 29 21:34:20 2009
@@ -3,13 +3,13 @@
class SpecNode(object):
- def expand_boxlist(self, instnode, newboxlist, start):
+ def expand_boxlist(self, instnode, newboxlist):
newboxlist.append(instnode.source)
def extract_runtime_data(self, cpu, valuebox, resultlist):
resultlist.append(valuebox)
- def adapt_to(self, instnode):
+ def adapt_to(self, instnode, offsets):
instnode.escaped = True
def mutate_nodes(self, instnode):
@@ -21,6 +21,9 @@
def matches(self, other):
raise NotImplementedError
+ def compute_number_of_nodes(self):
+ raise NotImplementedError
+
class NotSpecNode(SpecNode):
def mutate_nodes(self, instnode):
instnode.cursize = -1
@@ -34,8 +37,13 @@
# NotSpecNode matches everything
return True
+ def compute_number_of_nodes(self):
+ return 1
+
class MatchEverythingSpecNode(SpecNode):
- pass
+
+ def compute_number_of_nodes(self):
+ return 0
#class SpecNodeWithBox(NotSpecNode):
# # XXX what is this class used for?
@@ -71,6 +79,9 @@
return False
return instnode.cls.source.equals(self.known_class)
+ def compute_number_of_nodes(self):
+ return 1
+
##class FixedListSpecNode(FixedClassSpecNode):
## def equals(self, other):
@@ -125,11 +136,11 @@
return False
return True
- def expand_boxlist(self, instnode, newboxlist, start):
+ def expand_boxlist(self, instnode, newboxlist):
for ofs, subspecnode in self.fields:
if not isinstance(subspecnode, MatchEverythingSpecNode):
subinstnode = instnode.curfields[ofs] # should really be there
- subspecnode.expand_boxlist(subinstnode, newboxlist, start)
+ subspecnode.expand_boxlist(subinstnode, newboxlist)
def extract_runtime_data(self, cpu, valuebox, resultlist):
for ofs, subspecnode in self.fields:
@@ -140,9 +151,15 @@
[valuebox], ofs)
subspecnode.extract_runtime_data(cpu, fieldbox, resultlist)
- def adapt_to(self, instnode):
+ def adapt_to(self, instnode, offsets):
+ for ofs, subspecnode in self.fields:
+ subspecnode.adapt_to(instnode.curfields[ofs], offsets)
+
+ def compute_number_of_nodes(self):
+ counter = 0
for ofs, subspecnode in self.fields:
- subspecnode.adapt_to(instnode.curfields[ofs])
+ counter += subspecnode.compute_number_of_nodes()
+ return counter
class VirtualizedSpecNode(SpecNodeWithFields):
@@ -158,18 +175,50 @@
if not self.fields[i][1].equals(other.fields[i][1]):
return False
return True
+
+ def matches(self, instnode):
+ for key, value in self.fields:
+ if not isinstance(value, MatchEverythingSpecNode):
+ if key not in instnode.curfields:
+ return False
+ if value is not None and not value.matches(instnode.curfields[key]):
+ return False
+ return True
- def expand_boxlist(self, instnode, newboxlist, start):
+ def expand_boxlist(self, instnode, newboxlist):
newboxlist.append(instnode.source)
- SpecNodeWithFields.expand_boxlist(self, instnode, newboxlist, start)
+ SpecNodeWithFields.expand_boxlist(self, instnode, newboxlist)
def extract_runtime_data(self, cpu, valuebox, resultlist):
resultlist.append(valuebox)
SpecNodeWithFields.extract_runtime_data(self, cpu, valuebox, resultlist)
- def adapt_to(self, instnode):
+ def adapt_to(self, instnode, offsets_relative_to):
instnode.escaped = True
- SpecNodeWithFields.adapt_to(self, instnode)
+ fields = []
+ offsets_so_far = 0
+ for ofs, subspecnode in self.fields:
+ if isinstance(subspecnode, MatchEverythingSpecNode):
+ node = None
+ if ofs in instnode.curfields:
+ node = instnode.curfields[ofs]
+ orignode = instnode.origfields[ofs]
+ subspecnode = orignode.intersect(node, {})
+ elif ofs in instnode.origfields:
+ node = instnode.origfields[ofs]
+ subspecnode = node.intersect(node, {})
+ orignode = node
+ if node is not None:
+ subspecnode.mutate_nodes(orignode)
+ offsets_relative_to.append((subspecnode, ofs, instnode,
+ offsets_so_far, orignode))
+ else:
+ subspecnode.adapt_to(instnode.curfields[ofs],
+ offsets_relative_to)
+ offsets_so_far += subspecnode.compute_number_of_nodes()
+ fields.append((ofs, subspecnode))
+
+ self.fields = fields
# class DelayedSpecNode(VirtualizedSpecNode):
@@ -238,9 +287,9 @@
return False
return VirtualizedSpecNode.equals(self, other)
- def adapt_to(self, instnode):
+ def adapt_to(self, instnode, offsets):
instnode.virtualized = True
- VirtualizedSpecNode.adapt_to(self, instnode)
+ VirtualizedSpecNode.adapt_to(self, instnode, offsets)
class VirtualizableListSpecNode(VirtualizedSpecNode):
@@ -265,15 +314,15 @@
[valuebox, ofs], arraydescr)
subspecnode.extract_runtime_data(cpu, fieldbox, resultlist)
- def adapt_to(self, instnode):
+ def adapt_to(self, instnode, offsets):
instnode.virtualized = True
- VirtualizedSpecNode.adapt_to(self, instnode)
+ VirtualizedSpecNode.adapt_to(self, instnode, offsets)
class VirtualSpecNode(SpecNodeWithFields):
- def adapt_to(self, instnode):
+ def adapt_to(self, instnode, offsets):
instnode.virtual = True
- SpecNodeWithFields.adapt_to(self, instnode)
+ SpecNodeWithFields.adapt_to(self, instnode, offsets)
def mutate_nodes(self, instnode):
SpecNodeWithFields.mutate_nodes(self, instnode)
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_virtualizable.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_virtualizable.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_virtualizable.py Sun Mar 29 21:34:20 2009
@@ -423,7 +423,7 @@
res = self.meta_interp(f, [30], listops=True)
self.check_loops(setarrayitem_gc=0)
- #self.check_loop_count(2) # -- this is hard to predict right now:
+ self.check_loop_count(2) # -- this is hard to predict right now:
# what occurs is that one path through the loop is compiled,
# then exits; then later when we compile again we see the other
# path of the loop by chance, then exits; then finally we see
@@ -439,7 +439,6 @@
assert isinstance(op.args[1], history.BoxInt)
def test_virtual_obj_on_always_virtual(self):
- py.test.skip("XX")
jitdriver = JitDriver(greens = [], reds = ['frame', 'n', 's'],
virtualizables = ['frame'])
More information about the Pypy-commit
mailing list