Author: Richard Plangger <r...@pasra.at>
Branch: vecopt-merge
Changeset: r79204:9e571b42712d
Date: 2015-08-24 15:27 +0200
http://bitbucket.org/pypy/pypy/changeset/9e571b42712d/

Log:    memory error does not happen anymore on vecopt-merge

diff --git a/rpython/jit/backend/x86/assembler.py 
b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -591,14 +591,14 @@
                                                        rawstart, fullsize)
         return AsmInfo(ops_offset, startpos + rawstart, codeendpos - startpos, 
rawstart)
 
-    def stitch_bridge(self, faildescr, version):
+    def stitch_bridge(self, faildescr, target):
         """ Stitching means that one can enter a bridge with a complete 
different register
             allocation. This needs remapping which is done here for both 
normal registers
             and accumulation registers.
             Why? Because this only generates a very small junk of memory, 
instead of
             duplicating the loop assembler for each faildescr!
         """
-        asminfo, bridge_faildescr, compiled_version, looptoken = 
version._compiled
+        asminfo, bridge_faildescr, version, looptoken = target
         assert isinstance(bridge_faildescr, ResumeGuardDescr)
         assert isinstance(faildescr, ResumeGuardDescr)
         assert asminfo.rawstart != 0
@@ -612,7 +612,7 @@
         self.mc.force_frame_size(DEFAULT_FRAME_BYTES)
         # if accumulation is saved at the guard, we need to update it here!
         guard_locs = self.rebuild_faillocs_from_descr(faildescr, 
version.inputargs)
-        bridge_locs = self.rebuild_faillocs_from_descr(bridge_faildescr, 
compiled_version.inputargs)
+        bridge_locs = self.rebuild_faillocs_from_descr(bridge_faildescr, 
version.inputargs)
         guard_accum_info = faildescr.rd_accum_list
         # O(n^2), but usually you only have at most 1 fail argument
         while guard_accum_info:
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[1:]:
+        for version in loop.versions:
             version.update_token(jitcell_token, all_target_tokens)
 
     if not loop.quasi_immutable_deps:
@@ -194,12 +194,12 @@
     if loop.versions:
         # compile each version once for the first fail descr!
         # this assumes that the root trace (= loop) is already compiled
-        root = loop.versions[0]
-        for faildescr in root.faildescrs:
-            assert isinstance(faildescr, CompileLoopVersionDescr)
-            version = faildescr.version
-            if not version or version.compiled():
+        to_stitch = []
+        for version in loop.versions:
+            if not version.faildescrs:
                 continue
+            faildescr = version.faildescrs[0]
+            assert isinstance(faildescr, ResumeGuardDescr)
             vl = create_empty_loop(metainterp)
             vl.inputargs = version.inputargs
             vl.operations = version.operations
@@ -209,20 +209,14 @@
                                    version.operations, jitcell_token)
             record_loop_or_bridge(metainterp_sd, vl)
             assert asminfo is not None
-            version._compiled = (asminfo, faildescr, faildescr.version, 
jitcell_token)
-            faildescr.version = None
+
+            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 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:
-                assert isinstance(faildescr, CompileLoopVersionDescr)
-                version = faildescr.version
-                if version and version.compiled():
-                    cpu.stitch_bridge(faildescr, version)
-                faildescr.version = None
+        for fd, param in to_stitch:
+            cpu.stitch_bridge(fd, param)
     loop.versions = None
 
 def compile_retrace(metainterp, greenkey, start,
@@ -531,7 +525,7 @@
 class ResumeGuardDescr(ResumeDescr):
     _attrs_ = ('rd_numb', 'rd_count', 'rd_consts', 'rd_virtuals',
                'rd_frame_info_list', 'rd_pendingfields', 'rd_accum_list',
-               'status')
+               'status', 'version')
     
     rd_numb = lltype.nullptr(NUMBERING)
     rd_count = 0
@@ -542,6 +536,7 @@
     rd_accum_list = None
 
     status = r_uint(0)
+    version = None
 
     def copy_all_attributes_from(self, other):
         assert isinstance(other, ResumeGuardDescr)
@@ -746,11 +741,6 @@
 class CompileLoopVersionDescr(ResumeGuardDescr):
     guard_opnum = rop.GUARD_EARLY_EXIT
 
-    operations = None
-    inputargs = None
-    faillocs = None
-    version = None
-
     def handle_fail(self, deadframe, metainterp_sd, jitdriver_sd):
         assert 0, "this guard must never fail"
 
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
@@ -744,60 +744,31 @@
         create one instance and attach it to a guard descr.
         If not attached to a descriptor, it will not be compiled.
     """
-    def __init__(self, loop):
-        self.faildescrs = []
-        self._compiled = (None,None,None,None)
-        if loop:
-            self.operations = self.copy_operations(loop.operations) 
+    _compiled = (None,None,None,None)
+    inputargs = None
+    renamed_inputargs = None
+
+    def __init__(self, operations):
+        self.faildescrs = None
+        self.stitchdescr = {}
+        self.operations = operations
+
+    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()
-        else:
-            self.operations = None
-            self.inputargs = None
-            self.renamed_inputargs = None
+            # 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 compiled(self):
-        if self.operations is None:
-            # root version must always be compiled
-            return True
-
-        return self._compiled[0] is not None
-
-    def copy_operations(self, operations):
-        from rpython.jit.metainterp.compile import (ResumeGuardDescr,
-                CompileLoopVersionDescr)
-        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
-                    assert isinstance(olddescr, CompileLoopVersionDescr)
-                    assert isinstance(descr, CompileLoopVersionDescr)
-                    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
+    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
@@ -903,12 +874,9 @@
             return self.operations[index]
         return None
 
-    def snapshot(self):
-        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)
+    def snapshot(self, operations):
+        version = LoopVersion(operations)
+        version.setup_once()
         self.versions.append(version)
         return version
 
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
@@ -151,10 +151,10 @@
     def set_to_none(self, operations):
         assert operations[self.index] is self.op
         operations[self.index] = None
-        descr = self.op.getdescr()
-        if descr and descr.loop_version():
-            assert isinstance(descr, CompileLoopVersionDescr)
-            descr.version = None
+        #descr = self.op.getdescr()
+        #if descr and descr.loop_version():
+        #    assert isinstance(descr, CompileLoopVersionDescr)
+        #    descr.version = None
         if operations[self.index-1] is self.cmp_op:
             operations[self.index-1] = None
 
@@ -276,10 +276,11 @@
                     continue
                 descr = op.getdescr()
                 if descr.loop_version():
-                    root_version.register_guard(op, version)
+                    assert isinstance(descr, ResumeGuardDescr)
+                    root_version.register_guard(op, descr, version)
 
             if user_code:
-                version = loop.snapshot()
+                version = loop.snapshot(copy_operations(loop.operations))
                 self.eliminate_array_bound_checks(loop, root_version, version)
 
     def emit_operation(self, op):
@@ -302,7 +303,9 @@
                 transitive_guard = one.transitive_imply(other, self, loop)
                 if transitive_guard:
                     other.set_to_none(loop.operations)
-                    root_version.register_guard(transitive_guard, version)
+                    descr = transitive_guard.getdescr()
+                    assert isinstance(descr, ResumeGuardDescr)
+                    root_version.register_guard(transitive_guard, descr, 
version)
 
         if self.has_two_labels:
             oplist = [loop.operations[0]] + self._newoperations + \
@@ -312,3 +315,23 @@
             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
+from rpython.jit.metainterp.optimizeopt.guard import GuardStrengthenOpt, 
copy_operations
 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()
+    version = loop.snapshot(copy_operations(loop.operations))
     try:
         debug_start("vec-opt-loop")
         metainterp_sd.logger_noopt.log_loop(loop.inputargs, loop.operations, 
-2, None, None, "pre vectorize")
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to