[pypy-commit] pypy vecopt-merge: do not store the version on the descr anymore, but on an external data structure just for this purpose
plan_rich
noreply at buildbot.pypy.org
Mon Aug 24 17:51:08 CEST 2015
Author: Richard Plangger <rich at pasra.at>
Branch: vecopt-merge
Changeset: r79207:89a3655d9226
Date: 2015-08-24 17:34 +0200
http://bitbucket.org/pypy/pypy/changeset/89a3655d9226/
Log: do not store the version on the descr anymore, but on an external
data structure just for this purpose
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
@@ -194,30 +194,34 @@
if loop.versions:
# compile each version once for the first fail descr!
# this assumes that the root trace (= loop) is already compiled
- to_stitch = []
- for version in loop.versions:
- if not version.faildescrs:
+ compiled = {}
+ info = loop.version_info
+ for descr in info.descrs:
+ print "$>", descr
+ version = info.get(descr)
+ if not version:
+ # the guard might have been removed from the trace
continue
- faildescr = version.faildescrs[0]
- assert isinstance(faildescr, ResumeGuardDescr)
- vl = create_empty_loop(metainterp)
- vl.inputargs = version.inputargs
- vl.operations = version.operations
- vl.original_jitcell_token = jitcell_token
- asminfo = send_bridge_to_backend(jitdriver_sd, metainterp_sd,
- faildescr, version.inputargs,
- version.operations, jitcell_token)
- record_loop_or_bridge(metainterp_sd, vl)
- assert asminfo is not None
+ if version not in compiled:
+ print " +COMPILE", version
+ assert isinstance(descr, ResumeGuardDescr)
+ vl = create_empty_loop(metainterp)
+ vl.inputargs = version.inputargs
+ vl.operations = version.operations
+ vl.original_jitcell_token = jitcell_token
+ asminfo = send_bridge_to_backend(jitdriver_sd, metainterp_sd,
+ descr, version.inputargs,
+ version.operations, jitcell_token)
+ record_loop_or_bridge(metainterp_sd, vl)
+ assert asminfo is not None
+ compiled[version] = (asminfo, descr, version, jitcell_token)
+ else:
+ print " +stitch", version
+ param = compiled[version]
+ cpu.stitch_bridge(descr, param)
- for i,fd in enumerate(version.faildescrs):
- if i == 0:
- continue
- to_stitch.append((fd, (asminfo, faildescr, version, jitcell_token)))
- # stitch to the trace loop
- for fd, param in to_stitch:
- cpu.stitch_bridge(fd, param)
loop.versions = None
+ loop.version_info = None
def compile_retrace(metainterp, greenkey, start,
inputargs, jumpargs,
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
@@ -739,41 +739,72 @@
pass_by -= 1
return -1
+class VersionInfo(object):
+ def __init__(self):
+ self.descrs = []
+ self.leads_to = {}
+ self.insert_index = -1
+
+ def mark(self):
+ self.insert_index = len(self.descrs)
+
+ def clear(self):
+ self.insert_index = -1
+
+ def track(self, op, descr, version):
+ #print "+++", descr, "=>", version
+ assert descr.loop_version()
+ if self.insert_index >= 0:
+ assert self.insert_index >= 0
+ self.descrs.insert(self.insert_index, descr)
+ else:
+ self.descrs.append(descr)
+ self.leads_to[descr] = version
+ # note: stitching a guard must resemble the order of the label
+ # otherwise a wrong mapping is handed to the register allocator
+ op.setfailargs(version.renamed_inputargs)
+ assert version.renamed_inputargs is not None
+
+ def remove(self, descr):
+ if descr in self.leads_to:
+ #print "---", descr, "=>", self.leads_to[descr]
+ del self.leads_to[descr]
+ else:
+ assert 0, "could not remove %s" % descr
+
+ def get(self, descr):
+ return self.leads_to.get(descr, None)
+
class LoopVersion(object):
""" A special version of a trace loop. Use loop.snaphost() to
create one instance and attach it to a guard descr.
If not attached to a descriptor, it will not be compiled.
"""
- _compiled = (None,None,None,None)
inputargs = None
renamed_inputargs = None
def __init__(self, operations):
- self.faildescrs = None
- self.stitchdescr = {}
self.operations = 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()
- def setup_once(self):
- if self.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()
- # register the faildescr for later stitching
- for op in self.operations:
- if op.is_guard():
- descr = op.getdescr()
- if descr.loop_version():
- self.faildescrs.append(descr)
-
- def register_guard(self, op, descr, version):
- assert descr.loop_version()
- self.faildescrs.append(descr)
- # note: stitching a guard must resemble the order of the label
- # otherwise a wrong mapping is handed to the register allocator
- op.setfailargs(version.renamed_inputargs)
- assert version.renamed_inputargs is not None
+ def setup_once(self, info):
+ for op in self.operations:
+ if op.is_guard():
+ olddescr = op.getdescr()
+ if not olddescr:
+ continue
+ descr = olddescr.clone()
+ op.setdescr(descr)
+ if descr.loop_version():
+ toversion = info.leads_to.get(olddescr,None)
+ if toversion:
+ info.track(op, descr, toversion)
+ else:
+ assert 0, "olddescr must be found"
def update_token(self, jitcell_token, all_target_tokens):
# this is only invoked for versioned loops!
@@ -821,6 +852,7 @@
def __init__(self, name):
self.name = name
self.versions = []
+ self.version_info = VersionInfo()
# 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.
@@ -858,6 +890,9 @@
#
self.operations = self.operations[:-1] + loop.operations
self.versions = loop.versions
+ loop.versions = None
+ self.version_info = loop.version_info
+ loop.version_info = None
if loop.quasi_immutable_deps:
self.quasi_immutable_deps.update(loop.quasi_immutable_deps)
@@ -874,12 +909,24 @@
return self.operations[index]
return None
- def snapshot(self, operations):
- version = LoopVersion(operations)
- version.setup_once()
+ def snapshot(self):
+ oplist = self.copy_operations(self.operations)
+ version = LoopVersion(oplist)
+ version.setup_once(self.version_info)
+ # register the faildescr for later stitching
self.versions.append(version)
return version
+ def copy_operations(self, operations):
+ ignore = (rop.DEBUG_MERGE_POINT,)
+ oplist = []
+ for op in operations:
+ if op.getopnum() in ignore:
+ continue
+ cloned = op.clone()
+ oplist.append(cloned)
+ return oplist
+
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
@@ -148,10 +148,12 @@
self.setoperation(guard)
self.setcmp(cmp_op)
- def set_to_none(self, operations):
+ def set_to_none(self, loop):
+ operations = loop.operations
assert operations[self.index] is self.op
operations[self.index] = None
- #descr = self.op.getdescr()
+ descr = self.op.getdescr()
+ loop.version_info.remove(descr)
#if descr and descr.loop_version():
# assert isinstance(descr, CompileLoopVersionDescr)
# descr.version = None
@@ -266,22 +268,19 @@
self.collect_guard_information(loop)
self.eliminate_guards(loop)
#
- if len(loop.versions) >= 2:
- assert len(loop.versions) == 2
- root_version = loop.versions[0]
- version = loop.versions[1]
+ assert len(loop.versions) == 1
+ version = loop.versions[0]
- for op in loop.operations:
- if not op.is_guard():
- continue
- descr = op.getdescr()
- if descr.loop_version():
- assert isinstance(descr, ResumeGuardDescr)
- root_version.register_guard(op, descr, version)
+ for i,op in enumerate(loop.operations):
+ if not op.is_guard():
+ continue
+ descr = op.getdescr()
+ if descr and descr.loop_version():
+ assert isinstance(descr, ResumeGuardDescr)
+ loop.version_info.track(op, descr, version)
- if user_code:
- version = loop.snapshot(copy_operations(loop.operations))
- self.eliminate_array_bound_checks(loop, root_version, version)
+ if user_code:
+ self.eliminate_array_bound_checks(loop)
def emit_operation(self, op):
self.renamer.rename(op)
@@ -290,7 +289,10 @@
def operation_position(self):
return len(self._newoperations)
- def eliminate_array_bound_checks(self, loop, root_version, version):
+ def eliminate_array_bound_checks(self, loop):
+ info = loop.version_info
+ info.mark()
+ version = None
self._newoperations = []
for key, guards in self.strongest_guards.items():
if len(guards) <= 1:
@@ -302,10 +304,13 @@
for other in guards[1:]:
transitive_guard = one.transitive_imply(other, self, loop)
if transitive_guard:
- other.set_to_none(loop.operations)
+ if version is None:
+ version = loop.snapshot()
+ other.set_to_none(loop)
descr = transitive_guard.getdescr()
assert isinstance(descr, ResumeGuardDescr)
- root_version.register_guard(transitive_guard, descr, version)
+ info.track(transitive_guard, descr, version)
+ info.clear()
if self.has_two_labels:
oplist = [loop.operations[0]] + self._newoperations + \
@@ -315,23 +320,3 @@
loop.operations = self._newoperations + \
[op for op in loop.operations if op]
-def copy_operations(operations):
- 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
- assert isinstance(olddescr, ResumeGuardDescr)
- descr = olddescr.clone()
- assert isinstance(descr, ResumeGuardDescr)
- cloned.setdescr(descr)
- if olddescr.loop_version():
- # copy the version
- descr.version = olddescr.version
- return oplist
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
@@ -23,7 +23,7 @@
from rpython.jit.metainterp.optimizeopt.schedule import (VecScheduleData,
Scheduler, Pack, Pair, AccumPair, vectorbox_outof_box, getpackopnum,
getunpackopnum, PackType, determine_input_output_types)
-from rpython.jit.metainterp.optimizeopt.guard import GuardStrengthenOpt, copy_operations
+from rpython.jit.metainterp.optimizeopt.guard import GuardStrengthenOpt
from rpython.jit.metainterp.resoperation import (rop, ResOperation, GuardResOp)
from rpython.rlib import listsort
from rpython.rlib.objectmodel import we_are_translated
@@ -42,7 +42,7 @@
if user_code and user_loop_bail_fast_path(loop, warmstate):
return
# the original loop (output of optimize_unroll)
- version = loop.snapshot(copy_operations(loop.operations))
+ version = loop.snapshot()
try:
debug_start("vec-opt-loop")
metainterp_sd.logger_noopt.log_loop(loop.inputargs, loop.operations, -2, None, None, "pre vectorize")
@@ -505,7 +505,7 @@
return
if vector:
# add accumulation info to the descriptor
- for version in self.loop.versions[1:]:
+ for version in self.loop.versions:
# 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)
More information about the pypy-commit
mailing list