[pypy-svn] r63431 - in pypy/branch/pyjitpl5-loop/pypy/jit: backend/llgraph metainterp
arigo at codespeak.net
arigo at codespeak.net
Mon Mar 30 12:05:30 CEST 2009
Author: arigo
Date: Mon Mar 30 12:05:28 2009
New Revision: 63431
Modified:
pypy/branch/pyjitpl5-loop/pypy/jit/backend/llgraph/runner.py
pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/compile.py
pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/history.py
pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/optimize.py
pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/resoperation.py
Log:
Check this in for now. I am going to look more at the pyjitpl5-simplify
branch instead.
Modified: pypy/branch/pyjitpl5-loop/pypy/jit/backend/llgraph/runner.py
==============================================================================
--- pypy/branch/pyjitpl5-loop/pypy/jit/backend/llgraph/runner.py (original)
+++ pypy/branch/pyjitpl5-loop/pypy/jit/backend/llgraph/runner.py Mon Mar 30 12:05:28 2009
@@ -98,6 +98,20 @@
return c
def _get_loop_args(self, c, loop):
+ var2index = self._get_loop_args(c, loop)
+ self._compile_branch(c, loop.operations, var2index, rop.JUMP)
+
+ def compile_bridge(self, fail_op, bridge):
+ """Like compile_loop, but produce the bridge operations going from
+ the guard that precedes the given FAIL operation. It should patch
+ the conditional jump on this guard to now execute the given bridge.
+ """
+ c = llimpl.compile_restart(fail_op._fail_position)
+ bridge._compiled_version = c
+ var2index = self._get_loop_args(c, bridge)
+ self._compile_branch(c, bridge.operations, var2index, rop.JUMP)
+
+ def _get_loop_args(self, c, loop):
var2index = {}
for box in loop.inputargs:
if isinstance(box, history.BoxInt):
Modified: pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/compile.py
==============================================================================
--- pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/compile.py (original)
+++ pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/compile.py Mon Mar 30 12:05:28 2009
@@ -113,7 +113,7 @@
loop.operations = history.operations
loop.operations[-1].jump_target = loop
mark_keys_in_loop(loop, loop.operations)
- send_loop_to_backend(metainterp, loop, True)
+ send_loop_to_backend(metainterp, loop)
metainterp.stats.loops.append(loop)
old_loops.append(loop)
return loop
@@ -126,14 +126,11 @@
if op.opnum == rop.FAIL:
op.key.loop = loop
-def send_loop_to_backend(metainterp, loop, is_loop):
- metainterp.cpu.compile_operations(loop)
+def send_loop_to_backend(metainterp, loop):
+ metainterp.cpu.compile_loop(loop)
metainterp.stats.compiled_count += 1
if not we_are_translated():
- if is_loop:
- log.info("compiling new loop")
- else:
- log.info("compiling new bridge")
+ log.info("compiling new loop")
# ____________________________________________________________
@@ -153,3 +150,8 @@
mark_keys_in_loop(source_loop, guard_op.suboperations)
send_loop_to_backend(metainterp, source_loop, False)
return target_loop
+
+def send_bridge_to_backend(metainterp, bridge):
+ xxx
+ if not we_are_translated():
+ log.info("compiling new bridge")
Modified: pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/history.py
==============================================================================
--- pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/history.py (original)
+++ pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/history.py Mon Mar 30 12:05:28 2009
@@ -338,7 +338,7 @@
# self.inputargs = list of distinct Boxes
# self.operations = list of ResOperations
# ops of the kind 'guard_xxx' contain a further list of operations,
- # which may itself contain 'guard_xxx' and so on, making a tree.
+ # which must end with a FAIL.
def _all_operations(self, omit_fails=False):
"NOT_RPYTHON"
Modified: pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/optimize.py
==============================================================================
--- pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/optimize.py (original)
+++ pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/optimize.py Mon Mar 30 12:05:28 2009
@@ -209,18 +209,6 @@
perfect_specializer.optimize_loop()
return None
-def optimize_bridge(options, old_loops, history, cpu=None):
- if not options.specialize: # for tests only
- return old_loops[0]
-
- perfect_specializer = PerfectSpecializer(history, options, cpu)
- perfect_specializer.find_nodes()
- for old_loop in old_loops:
- if perfect_specializer.match(old_loop):
- perfect_specializer.adapt_for_match(old_loop)
- perfect_specializer.optimize_loop()
- return old_loop
- return None # no loop matches
class PerfectSpecializer(object):
_allow_automatic_node_creation = False
@@ -507,7 +495,7 @@
assert len(op.suboperations) == 1
op_fail = op.suboperations[0]
assert op_fail.opnum == rop.FAIL
- old_boxes = op.suboperations[0].args
+ old_boxes = op_fail.args
unoptboxes = []
for box in old_boxes:
if isinstance(box, Const):
@@ -547,8 +535,10 @@
# rebuild_ops.append(op1)
# # end of code for dirtyfields support
+ op_fail = op_fail.clone()
op_fail.args = unoptboxes
rebuild_ops.append(op_fail)
+ op = op.clone()
op.suboperations = rebuild_ops
return op
@@ -622,6 +612,7 @@
if arg in self.nodes:
assert not self.nodes[arg].virtual
#self.cleanup_field_caches(newoperations)
+ op = op.clone()
op.args = args
newoperations.append(op)
break
@@ -746,6 +737,7 @@
self.nodes[box] = instnode
continue
# default handling of arguments and return value
+ op = op.clone()
op.args = self.new_arguments(op)
if op.is_always_pure():
for box in op.args:
@@ -806,25 +798,58 @@
return False
return True
- def match(self, old_loop):
- jump_op = self.history.operations[-1]
- assert jump_op.opnum == rop.JUMP
- assert len(old_loop.specnodes) == len(jump_op.args)
- for i in range(len(old_loop.specnodes)):
- old_specnode = old_loop.specnodes[i]
- new_instnode = self.getnode(jump_op.args[i])
- if not old_specnode.matches(new_instnode):
- return False
- return True
+ def _patch(self, origargs, newargs):
+ i = 0
+ res = []
+ for arg in newargs:
+ if arg is None:
+ res.append(origargs[i])
+ i += 1
+ else:
+ res.append(arg)
+ return res
- def adapt_for_match(self, old_loop):
- jump_op = self.history.operations[-1]
- assert jump_op.opnum == rop.JUMP
- self.specnodes = old_loop.specnodes
- 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)
+ def _patch_loop(self, operations, inpargs, rebuild_ops, loop):
+ for op in operations:
+ if op.is_guard():
+ if op.suboperations[-1].opnum == rop.FAIL:
+ op.suboperations = (op.suboperations[:-1] + rebuild_ops +
+ [op.suboperations[-1]])
+ else:
+ self._patch_loop(op.suboperations, inpargs, rebuild_ops,
+ loop)
+ jump = operations[-1]
+ if jump.opnum == rop.JUMP and jump.jump_target is loop:
+ jump.args = self._patch(jump.args, inpargs)
+
+ def update_loop(self, offsets, loop):
+ j = 0
+ new_inputargs = []
+ 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([None] * (ofs - prev_ofs))
+ prev_ofs = ofs
+ boxlist = []
+ specnode.expand_boxlist(node, boxlist)
+ new_inputargs.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([None] * (len(loop.inputargs) - prev_ofs))
+ loop.inputargs = self._patch(loop.inputargs, new_inputargs)
+ self._patch_loop(loop.operations, new_inputargs, rebuild_ops, loop)
def get_in_list(dict, boxes_or_consts):
result = []
Modified: pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/resoperation.py
==============================================================================
--- pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/resoperation.py (original)
+++ pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/resoperation.py Mon Mar 30 12:05:28 2009
@@ -32,13 +32,10 @@
self.descr = descr
def clone(self):
- "NOT_RPYTHON" # for tests only
res = ResOperation(self.opnum, self.args, self.result, self.descr)
res.jump_target = self.jump_target
res.key = self.key
res.vdesc = self.vdesc
- if self.suboperations is not None:
- res.suboperations = [op.clone() for op in self.suboperations]
return res
def __repr__(self):
More information about the Pypy-commit
mailing list