[pypy-svn] r63113 - in pypy/branch/virtualizable-specnodes/pypy/jit/metainterp: . test
fijal at codespeak.net
fijal at codespeak.net
Fri Mar 20 09:49:35 CET 2009
Author: fijal
Date: Fri Mar 20 09:49:34 2009
New Revision: 63113
Modified:
pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/compile.py
pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/optimize.py
pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/specnode.py
pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/test/test_tl.py
Log:
an in-progress checkin of changes so-far
Modified: pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/compile.py
==============================================================================
--- pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/compile.py (original)
+++ pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/compile.py Fri Mar 20 09:49:34 2009
@@ -151,15 +151,6 @@
metainterp.cpu.compile_operations(loop.operations, guard_op)
metainterp.stats.loops.append(loop)
-def update_loop(metainterp, loop, guard_op, newboxlist):
- mp = loop.operations[0]
- mp.args += newboxlist
- jump = loop.operations[-1]
- jump.args += newboxlist
- guard_op.liveboxes += newboxlist
- guard_op.storage = None
- metainterp.cpu.update_loop(loop, mp, guard_op, newboxlist)
-
# ____________________________________________________________
def matching_merge_point(metainterp, targetmp, endliveboxes):
@@ -176,14 +167,14 @@
op = ResOperation(rop.JUMP, endliveboxes, None)
operations.append(op)
#
- old_loop, newboxlist = optimize.optimize_bridge(metainterp.options,
- old_loops, bridge,
- metainterp.cpu)
+ old_loop, newboxlist, storage = optimize.optimize_bridge(metainterp.options,
+ old_loops, bridge,
+ metainterp.cpu)
if old_loop is None:
return None
bridge.jump_to = old_loop
if newboxlist:
# recompile loop
- update_loop(metainterp, old_loop, guard_op, newboxlist)
+ optimize.update_loop(metainterp, old_loop, newboxlist, storage)
finish_loop_or_bridge(metainterp, bridge, old_loop.operations[0], guard_op)
return bridge
Modified: pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/optimize.py
==============================================================================
--- pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/optimize.py (original)
+++ pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/optimize.py Fri Mar 20 09:49:34 2009
@@ -27,6 +27,9 @@
assert isinstance(other, FixedClass)
return True
+ def _getrepr_(self):
+ return "FixedClass"
+
class CancelInefficientLoop(Exception):
pass
@@ -48,6 +51,8 @@
# the same as above, but for lists and for running setitem
self.list_allocations = []
self.setitems = []
+ # used for merging
+ self.extras = []
def deal_with_box(self, box, nodes, liveboxes, memo):
if isinstance(box, Const) or box not in nodes:
@@ -281,13 +286,13 @@
for old_loop in old_loops:
if perfect_specializer.match(old_loop.operations):
num = len(old_loop.extensions)
- newlist, newspecnodes = perfect_specializer.adapt_for_match(
+ newlist, newspecnodes, s = perfect_specializer.adapt_for_match(
old_loop.operations, num)
if newlist:
old_loop.extensions.append(newspecnodes)
perfect_specializer.loop.operations[0].args.extend(newlist)
perfect_specializer.optimize_loop()
- return old_loop, newlist
+ return old_loop, newlist, s
return None # no loop matches
class PerfectSpecializer(object):
@@ -831,12 +836,14 @@
jump_op = self.loop.operations[-1]
self.specnodes = old_mp.specnodes
newboxlist = BoxRetriever()
+ storage = AllocationStorage()
extensions = []
for i in range(len(old_mp.specnodes)):
old_specnode = old_mp.specnodes[i]
new_instnode = self.nodes[jump_op.args[i]]
- old_specnode.adapt_to(new_instnode, newboxlist, extensions, num)
- return newboxlist.flatten(), extensions
+ old_specnode.adapt_to(new_instnode, newboxlist, extensions, num,
+ storage)
+ return newboxlist.flatten(), extensions, storage
class Chooser(object):
def __init__(self, boxes_from_frame, allocated_boxes, allocated_lists):
@@ -895,6 +902,19 @@
return newboxes
+def update_loop(metainterp, loop, newboxlist, add_storage):
+ mp = loop.operations[0]
+ mp.args += newboxlist
+ jump = loop.operations[-1]
+ jump.args += newboxlist
+ for op in loop.operations:
+ if op.is_guard():
+ import pdb
+ pdb.set_trace()
+ metainterp.cpu.update_loop(loop, mp, newboxlist)
+
+# ----------------------------------------------------------------------
+
def partition(array, left, right):
last_item = array[right]
pivot = last_item.sort_key()
Modified: pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/specnode.py
==============================================================================
--- pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/specnode.py (original)
+++ pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/specnode.py Fri Mar 20 09:49:34 2009
@@ -38,7 +38,7 @@
def extract_runtime_data(self, cpu, valuebox, resultlist):
resultlist.append(valuebox)
- def adapt_to(self, instnode, newboxlist, newspecnodes, num):
+ def adapt_to(self, instnode, newboxlist, newspecnodes, num, storage):
instnode.escaped = True
def mutate_nodes(self, instnode):
@@ -50,6 +50,9 @@
def matches(self, other):
raise NotImplementedError
+ def create_extra_storage(self, storage):
+ pass
+
class RedirectingSpecNode(SpecNode):
def __init__(self, specnode, group):
self.redirect_to = specnode
@@ -181,10 +184,10 @@
[valuebox], ofs)
subspecnode.extract_runtime_data(cpu, fieldbox, resultlist)
- def adapt_to(self, instnode, newboxlist, newspecnodes, num):
+ def adapt_to(self, instnode, newboxlist, newspecnodes, num, storage):
for ofs, subspecnode in self.fields:
subspecnode.adapt_to(instnode.curfields[ofs], newboxlist,
- newspecnodes, num)
+ newspecnodes, num, storage)
class VirtualizedOrDelayedSpecNode(SpecNodeWithFields):
@@ -196,10 +199,10 @@
resultlist.append(valuebox)
SpecNodeWithFields.extract_runtime_data(self, cpu, valuebox, resultlist)
- def adapt_to(self, instnode, newboxlist, newspecnodes, num):
+ def adapt_to(self, instnode, newboxlist, newspecnodes, num, storage):
instnode.escaped = True
SpecNodeWithFields.adapt_to(self, instnode, newboxlist, newspecnodes,
- num)
+ num, storage)
class DelayedSpecNode(VirtualizedOrDelayedSpecNode):
@@ -276,7 +279,7 @@
return False
return True
- def adapt_to(self, instnode, newboxlist, newspecnodes, num):
+ def adapt_to(self, instnode, newboxlist, newspecnodes, num, storage):
instnode.virtualized = True
fields = []
for ofs, subspecnode in self.fields:
@@ -286,13 +289,15 @@
node = instnode.curfields[ofs]
subspecnode = orignode.intersect(node, {})
subspecnode.mutate_nodes(orignode)
+ res = subspecnode.create_extra_storage(storage)
+ self.add_to_storage(ofs, res, storage)
subspecnode = RedirectingSpecNode(subspecnode, num)
subspecnode.expand_boxlist(orignode, newboxlist, None)
newspecnodes.append(subspecnode)
# otherwise we simply ignore unused field
else:
subspecnode.adapt_to(instnode.curfields[ofs], newboxlist,
- newspecnodes, num)
+ newspecnodes, num, storage)
fields.append((ofs, subspecnode))
self.fields = fields
@@ -303,6 +308,9 @@
return False
return VirtualizedSpecNode.equals(self, other)
+ def create_extra_storage(self, storage):
+ raise NotImplementedError
+
class VirtualizableListSpecNode(VirtualizedSpecNode):
def equals(self, other):
@@ -328,10 +336,10 @@
class VirtualSpecNode(SpecNodeWithFields):
- def adapt_to(self, instnode, newboxlist, newspecnodes, num):
+ def adapt_to(self, instnode, newboxlist, newspecnodes, num, storage):
instnode.virtual = True
return SpecNodeWithFields.adapt_to(self, instnode, newboxlist,
- newspecnodes, num)
+ newspecnodes, num, storage)
def mutate_nodes(self, instnode):
SpecNodeWithFields.mutate_nodes(self, instnode)
@@ -344,30 +352,37 @@
return False
return SpecNodeWithFields.equals(self, other)
+ def create_extra_storage(self, storage):
+ xxx
+
class VirtualFixedListSpecNode(VirtualSpecNode):
- def __init__(self, known_class, fields, known_length):
- VirtualSpecNode.__init__(self, known_class, fields)
- self.known_length = known_length
-
- def mutate_nodes(self, instnode):
- VirtualSpecNode.mutate_nodes(self, instnode)
- instnode.cursize = self.known_length
-
- def equals(self, other):
- if not isinstance(other, VirtualFixedListSpecNode):
- return False
- return SpecNodeWithFields.equals(self, other)
+ def __init__(self, known_class, fields, known_length):
+ VirtualSpecNode.__init__(self, known_class, fields)
+ self.known_length = known_length
+
+ def mutate_nodes(self, instnode):
+ VirtualSpecNode.mutate_nodes(self, instnode)
+ instnode.cursize = self.known_length
+
+ def equals(self, other):
+ if not isinstance(other, VirtualFixedListSpecNode):
+ return False
+ return SpecNodeWithFields.equals(self, other)
- def extract_runtime_data(self, cpu, valuebox, resultlist):
- from pypy.jit.metainterp.resoperation import rop
- from pypy.jit.metainterp.optimize import FixedList
- from pypy.jit.metainterp.history import check_descr
- cls = self.known_class
- assert isinstance(cls, FixedList)
- arraydescr = cls.arraydescr
- check_descr(arraydescr)
- for ofs, subspecnode in self.fields:
- fieldbox = executor.execute(cpu, rop.GETARRAYITEM_GC,
- [valuebox, ofs], arraydescr)
- subspecnode.extract_runtime_data(cpu, fieldbox, resultlist)
+ def extract_runtime_data(self, cpu, valuebox, resultlist):
+ from pypy.jit.metainterp.resoperation import rop
+ from pypy.jit.metainterp.optimize import FixedList
+ from pypy.jit.metainterp.history import check_descr
+ cls = self.known_class
+ assert isinstance(cls, FixedList)
+ arraydescr = cls.arraydescr
+ check_descr(arraydescr)
+ for ofs, subspecnode in self.fields:
+ fieldbox = executor.execute(cpu, rop.GETARRAYITEM_GC,
+ [valuebox, ofs], arraydescr)
+ subspecnode.extract_runtime_data(cpu, fieldbox, resultlist)
+
+ def create_extra_storage(self, storage):
+ xxx
+
Modified: pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/test/test_tl.py
==============================================================================
--- pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/test/test_tl.py (original)
+++ pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/test/test_tl.py Fri Mar 20 09:49:34 2009
@@ -107,6 +107,96 @@
'int_is_true':1, 'guard_false':1, 'jump':1,
'guard_value':1})
+ def test_example(self):
+ jitdriver = JitDriver(greens = ['code', 'i'], reds = ['v1', 'v2', 'v3'])
+
+ class IntObject(object):
+ def __init__(self, value):
+ self.value = value
+
+ def add(self, other):
+ return IntObject(self.value + other.value)
+
+ def gt(self, other):
+ return self.value > other.value
+
+ def store_into_variable(num, v1, v2, v3, value_to_store):
+ if num == 0:
+ return value_to_store, v2, v3
+ elif num == 1:
+ return v1, value_to_store, v3
+ elif num == 2:
+ return v1, v2, value_to_store
+ else:
+ raise Exception("Wrong num")
+
+ def load_variable(num, v1, v2, v3):
+ if num == 0:
+ return v1
+ elif num == 1:
+ return v2
+ elif num == 2:
+ return v3
+ else:
+ raise Exception("Wrong num")
+
+ def interpret(code, i0, i1, i2):
+ v1 = IntObject(i0)
+ v2 = IntObject(i1)
+ v3 = IntObject(i2)
+ i = 0
+ while i < len(code):
+ jitdriver.jit_merge_point(code=code, i=i, v1=v1, v2=v2, v3=v3)
+ if code[i] == ADD:
+ a = load_variable(code[i + 1], v1, v2, v3)
+ b = load_variable(code[i + 2], v1, v2, v3)
+ res_num = code[i + 3]
+ res = a.add(b)
+ v1, v2, v3 = store_into_variable(res_num, v1, v2, v3,
+ res)
+ i += 4
+ elif code[i] == JUMP_IF_GT:
+ a = load_variable(code[i + 1], v1, v2, v3)
+ b = load_variable(code[i + 2], v1, v2, v3)
+ where = code[i + 3]
+ if a.gt(b):
+ i = where
+ jitdriver.can_enter_jit(code=code, i=i, v1=v1, v2=v2,
+ v3=v3)
+ else:
+ i += 4
+ elif code[i] == JUMP:
+ i = code[i + 1]
+ jitdriver.can_enter_jit(code=code, i=i, v1=v1, v2=v2, v3=v3)
+ else:
+ raise Exception("bytecode corruption")
+ return v1.value
+
+ ADD = 0
+ JUMP = 1
+ JUMP_IF_GT = 2
+
+ code = [
+ ADD, 0, 1, 0,
+ ADD, 0, 1, 0,
+ ADD, 0, 1, 0,
+ JUMP_IF_GT, 0, 2, 18,
+ JUMP, 0
+ ]
+
+ # v0 += v1
+ # v0 += v1
+ # v0 += v1
+ # if v1 > v2: jump 18 (after the end of the loop)
+ # jump 0
+
+ def runner(num, i0, i1, i2):
+ return interpret([code, []][num], i0, i1, i2)
+
+ assert interpret(code, 0, 1, 20) == 21
+ res = self.meta_interp(runner, [0, 0, 1, 20])
+ assert res == 21
+
class TestOOtype(ToyLanguageTests, OOJitMixin):
pass
More information about the Pypy-commit
mailing list