Author: Richard Plangger <r...@pasra.at> Branch: vecopt-merge Changeset: r79108:90d4590adf3c Date: 2015-08-21 14:10 +0200 http://bitbucket.org/pypy/pypy/changeset/90d4590adf3c/
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,12 +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:]: - 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 *") _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit