[pypy-commit] pypy memoryerror3: finished the refactoring. the root loop has now it's own version, which makes generate_pending_loop_versions easier to understand. a fail descr now always points to the loop version (field version) it would like to jump to
plan_rich
noreply at buildbot.pypy.org
Mon Aug 24 12:02:25 CEST 2015
Author: Richard Plangger <rich at pasra.at>
Branch: memoryerror3
Changeset: r79187:743dc64b5f8a
Date: 2015-08-21 14:10 +0200
http://bitbucket.org/pypy/pypy/changeset/743dc64b5f8a/
Log: finished the refactoring. the root loop has now it's own version,
which makes generate_pending_loop_versions easier to understand. a
fail descr now always points to the loop version (field version) it
would like to jump to handle not compiled versions (because they are
not needed) gracefully
diff --git a/rpython/jit/metainterp/compile.py b/rpython/jit/metainterp/compile.py
--- a/rpython/jit/metainterp/compile.py
+++ b/rpython/jit/metainterp/compile.py
@@ -162,7 +162,7 @@
if loop.versions is not None:
# every different loop version must update their target tokens
- for version in loop.versions:
+ for version in loop.versions[1:]:
version.update_token(jitcell_token, all_target_tokens)
if not loop.quasi_immutable_deps:
@@ -194,10 +194,11 @@
if loop.versions is not None:
# compile each version once for the first fail descr!
# this assumes that the root trace (= loop) is already compiled
- for version in loop.versions:
- if len(version.faildescrs) == 0:
+ root = loop.versions[0]
+ for faildescr in root.faildescrs:
+ version = faildescr.version
+ if not version or version.compiled():
continue
- faildescr = version.faildescrs[0]
vl = create_empty_loop(metainterp)
vl.inputargs = version.inputargs
vl.operations = version.operations
@@ -207,13 +208,19 @@
version.operations, jitcell_token)
record_loop_or_bridge(metainterp_sd, vl)
assert asminfo is not None
- version.compiled = asminfo
+ version._compiled = asminfo
+ faildescr.version = None
# stitch the rest of the traces
- for version in loop.versions:
- for faildescr in version.faildescrs[1:]:
- assert isinstance(faildescr, CompileLoopVersionDescr)
- if faildescr.version.compiled:
- cpu.stitch_bridge(faildescr, version.compiled)
+ for lv in loop.versions:
+ if not lv.compiled():
+ # the version was never compiled, do not bother
+ # to assign it's fail descr
+ continue
+ for faildescr in lv.faildescrs:
+ version = faildescr.version
+ if version and version.compiled():
+ cpu.stitch_bridge(faildescr, version._compiled)
+ faildescr.version = None
loop.versions = None
def compile_retrace(metainterp, greenkey, start,
diff --git a/rpython/jit/metainterp/history.py b/rpython/jit/metainterp/history.py
--- a/rpython/jit/metainterp/history.py
+++ b/rpython/jit/metainterp/history.py
@@ -748,28 +748,62 @@
class LoopVersion(object):
- def __init__(self, operations):
- self.operations = operations
+ def __init__(self, loop):
self.faildescrs = []
- #
- idx = index_of_first(rop.LABEL, operations)
- assert idx >= 0
- label = operations[idx]
- self.label_pos = idx
- self.inputargs = label.getarglist()
- self.renamed_inputargs = label.getarglist()
- self.compiled = None
+ self._compiled = None
+ if loop:
+ self.operations = self.copy_operations(loop.operations)
+ idx = index_of_first(rop.LABEL, self.operations)
+ assert idx >= 0
+ label = self.operations[idx]
+ self.inputargs = label.getarglist()
+ self.renamed_inputargs = label.getarglist()
+ else:
+ self.operations = None
+ self.inputargs = None
+ self.renamed_inputargs = None
- def register_guard(self, op):
+ def compiled(self):
+ if self.operations is None:
+ # root version must always be compiled
+ return True
+
+ return self._compiled is not None
+
+ def copy_operations(self, operations):
+ from rpython.jit.metainterp.compile import ResumeGuardDescr
+ ignore = (rop.DEBUG_MERGE_POINT,)
+ oplist = []
+ for op in operations:
+ if op.getopnum() in ignore:
+ continue
+ cloned = op.clone()
+ oplist.append(cloned)
+ if cloned.is_guard():
+ olddescr = cloned.getdescr()
+ if not olddescr:
+ continue
+ descr = olddescr.clone()
+ cloned.setdescr(descr)
+ if olddescr.loop_version():
+ # copy the version
+ descr.version = olddescr.version
+ self.faildescrs.append(descr)
+ return oplist
+
+ def register_guard(self, op, version):
from rpython.jit.metainterp.compile import CompileLoopVersionDescr
assert isinstance(op, GuardResOp)
descr = op.getdescr()
+ if not descr.loop_version():
+ assert 0, "cannot register a guard that is not a CompileLoopVersionDescr"
assert isinstance(descr, CompileLoopVersionDescr)
+ descr.version = version
self.faildescrs.append(descr)
- descr.version = self
# note: stitching a guard must resemble the order of the label
# otherwise a wrong mapping is handed to the register allocator
- op.setfailargs(self.renamed_inputargs)
+ op.setfailargs(version.renamed_inputargs)
+ assert version.renamed_inputargs is not None
def update_token(self, jitcell_token, all_target_tokens):
# this is only invoked for versioned loops!
@@ -798,7 +832,6 @@
label.setdescr(token)
jump.setdescr(token)
-
class TreeLoop(object):
inputargs = None
operations = None
@@ -872,9 +905,11 @@
return None
def snapshot(self):
- faildescrs = []
- version = LoopVersion(self.copy_operations(faildescrs))
- version.faildescrs = faildescrs
+ if len(self.versions) == 0:
+ # create a root version, simplyfies the code in compile.py
+ self.versions.append(LoopVersion(None))
+ root_version = self.versions[0]
+ version = LoopVersion(self)
if not we_are_translated():
print "LOOP SNAPSHOT"
for op in version.operations:
@@ -882,23 +917,6 @@
self.versions.append(version)
return version
- def copy_operations(self, faildescrs=None):
- from rpython.jit.metainterp.compile import ResumeGuardDescr
- ignore = (rop.DEBUG_MERGE_POINT,)
- operations = []
- for op in self.operations:
- if op.getopnum() in ignore:
- continue
- cloned = op.clone()
- operations.append(cloned)
- descr = cloned.getdescr()
- if cloned.is_guard() and descr:
- assert isinstance(descr, ResumeGuardDescr)
- cloned.setdescr(descr.clone())
- if faildescrs and descr.loop_version():
- faildescrs.append(cloned.getdescr())
- return operations
-
def get_display_text(self): # for graphpage.py
return self.name + '\n' + repr(self.inputargs)
diff --git a/rpython/jit/metainterp/optimizeopt/guard.py b/rpython/jit/metainterp/optimizeopt/guard.py
--- a/rpython/jit/metainterp/optimizeopt/guard.py
+++ b/rpython/jit/metainterp/optimizeopt/guard.py
@@ -152,8 +152,7 @@
assert operations[self.index] is self.op
operations[self.index] = None
descr = self.op.getdescr()
- if isinstance(descr, CompileLoopVersionDescr) and descr.version:
- descr.version.faildescrs.remove(descr)
+ if descr and descr.loop_version():
descr.version = None
if operations[self.index-1] is self.cmp_op:
operations[self.index-1] = None
@@ -265,19 +264,20 @@
self.collect_guard_information(loop)
self.eliminate_guards(loop)
#
- assert len(loop.versions) == 1, "none or more than one version created"
- version = loop.versions[0]
+ assert len(loop.versions) == 2, "need one orignal loop version (before trans) and the current one"
+ root_version = loop.versions[0]
+ version = loop.versions[1]
for op in loop.operations:
if not op.is_guard():
continue
descr = op.getdescr()
if descr.loop_version():
- version.register_guard(op)
+ root_version.register_guard(op, version)
if user_code:
version = loop.snapshot()
- self.eliminate_array_bound_checks(loop, version)
+ self.eliminate_array_bound_checks(loop, root_version, version)
def emit_operation(self, op):
self.renamer.rename(op)
@@ -286,7 +286,7 @@
def operation_position(self):
return len(self._newoperations)
- def eliminate_array_bound_checks(self, loop, version):
+ def eliminate_array_bound_checks(self, loop, root_version, version):
self._newoperations = []
for key, guards in self.strongest_guards.items():
if len(guards) <= 1:
@@ -299,7 +299,7 @@
transitive_guard = one.transitive_imply(other, self, loop)
if transitive_guard:
other.set_to_none(loop.operations)
- version.register_guard(transitive_guard)
+ root_version.register_guard(transitive_guard, version)
if self.has_two_labels:
oplist = [loop.operations[0]] + self._newoperations + \
diff --git a/rpython/jit/metainterp/optimizeopt/vectorize.py b/rpython/jit/metainterp/optimizeopt/vectorize.py
--- a/rpython/jit/metainterp/optimizeopt/vectorize.py
+++ b/rpython/jit/metainterp/optimizeopt/vectorize.py
@@ -38,6 +38,7 @@
user_code = not jitdriver_sd.vec and warmstate.vec_all
if user_code and user_loop_bail_fast_path(loop, warmstate):
return
+ # the original loop (output of optimize_unroll)
version = loop.snapshot()
try:
debug_start("vec-opt-loop")
@@ -493,7 +494,7 @@
return
if vector:
# add accumulation info to the descriptor
- for version in self.loop.versions:
+ for version in self.loop.versions[1:]:
# this needs to be done for renamed (accum arguments)
version.renamed_inputargs = [ renamer.rename_map.get(arg,arg) for arg in version.inputargs ]
self.appended_arg_count = len(sched_data.invariant_vector_vars)
@@ -874,7 +875,7 @@
box = result
elif accum.operator == Accum.MULTIPLY:
# multiply is only supported by floats
- op = ResOperation(rop.VEC_FLOAT_EXPAND, [ConstFloat(1.0)], box)
+ op = ResOperation(rop.VEC_FLOAT_EXPAND, [ConstFloat(1.0), ConstInt(size)], box)
sched_data.invariant_oplist.append(op)
else:
raise NotImplementedError("can only handle + and *")
More information about the pypy-commit
mailing list