Author: Richard Plangger <r...@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) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit