Author: Maciej Fijalkowski <[email protected]>
Branch: resume-refactor
Changeset: r68601:95b2f5879a2a
Date: 2014-01-12 11:25 +0100
http://bitbucket.org/pypy/pypy/changeset/95b2f5879a2a/

Log:    (fijal, rguillebert) fix test_resumebuilder for removal of
        backend_attach

diff --git a/rpython/jit/backend/llsupport/regalloc.py 
b/rpython/jit/backend/llsupport/regalloc.py
--- a/rpython/jit/backend/llsupport/regalloc.py
+++ b/rpython/jit/backend/llsupport/regalloc.py
@@ -11,7 +11,7 @@
 
 class TempBox(Box):
     type = 't' # none of the types
-    
+
     def __init__(self):
         pass
 
@@ -688,8 +688,18 @@
         else:
             return [self.loc(op.getarg(0))]
 
+def flatten(inputframes):
+    count = 0
+    for frame in inputframes:
+        count += len(frame)
+    inputargs = [None] * count
+    i = 0
+    for frame in inputframes:
+        inputargs[i:i + len(frame)] = frame
+        i += len(frame)
+    return inputargs
 
-def compute_vars_longevity(inputargs, operations, descr=None):
+def compute_vars_longevity(inputframes, operations, descr=None):
     # compute a dictionary that maps variables to index in
     # operations that is a "last-time-seen"
 
@@ -701,7 +711,12 @@
     last_used = {}
     last_real_usage = {}
     frontend_alive = {}
-    liveness_analyzer = LivenessAnalyzer()
+    if descr is None:
+        inputargs = inputframes[0]
+        liveness_analyzer = LivenessAnalyzer()
+    else:
+        inputargs = flatten(inputframes)
+        liveness_analyzer = LivenessAnalyzer(inputframes)
     start_pos = 0
     for position, op in enumerate(operations):
         if op.is_guard():
diff --git a/rpython/jit/backend/llsupport/resumebuilder.py 
b/rpython/jit/backend/llsupport/resumebuilder.py
--- a/rpython/jit/backend/llsupport/resumebuilder.py
+++ b/rpython/jit/backend/llsupport/resumebuilder.py
@@ -4,11 +4,15 @@
 from rpython.jit.metainterp.resume2 import ResumeBytecode, AbstractResumeReader
 
 class LivenessAnalyzer(AbstractResumeReader):
-    def __init__(self):
+    def __init__(self, inputframes=None):
         self.liveness = {}
         self.frame_starts = [0]
         self.framestack = []
         self.deps = {}
+        if inputframes is not None:
+            for frame in inputframes:
+                self.frame_starts.append(self.frame_starts[-1] + len(frame))
+                self.framestack.append(frame)
 
     def enter_frame(self, pc, jitcode):
         self.frame_starts.append(self.frame_starts[-1] + jitcode.num_regs())
@@ -47,19 +51,33 @@
         self.regalloc = regalloc
         self.current_attachment = {}
         self.frontend_liveness = frontend_liveness
+        self.frontend_pos = {}
 
     def process(self, op):
-        self.newops.append(op)
+        if op.getopnum() == rop.RESUME_PUT:
+            box = op.getarg(0)
+            args = op.getarglist()
+            pos = self.regalloc.loc(box).get_jitframe_position()
+            self.current_attachment[box] = pos
+            self.frontend_pos[box] = (args[1], args[2])
+            args[0] = ConstInt(pos)
+            newop = op.copy_and_change(rop.RESUME_PUT, args=args)
+        else:
+            newop = op
+        self.newops.append(newop)
 
     def _mark_visited(self, v, loc):
         pos = loc.get_jitframe_position()
         if (v not in self.frontend_liveness or
             self.frontend_liveness[v] < self.regalloc.rm.position):
             return
-        if (v not in self.current_attachment or
-            self.current_attachment[v] != pos):
-            self.newops.append(ResOperation(rop.BACKEND_ATTACH, [
-                v, ConstInt(pos)], None))
+        if v not in self.current_attachment:
+            return
+        if self.current_attachment[v] != pos:
+            frame_index, frame_pos = self.frontend_pos[v]
+            self.newops.append(ResOperation(rop.RESUME_PUT, [
+                ConstInt(pos), frame_index, frame_pos],
+                None))
         self.current_attachment[v] = pos
 
     def mark_resumable_position(self):
diff --git a/rpython/jit/backend/llsupport/test/test_resumebuilder.py 
b/rpython/jit/backend/llsupport/test/test_resumebuilder.py
--- a/rpython/jit/backend/llsupport/test/test_resumebuilder.py
+++ b/rpython/jit/backend/llsupport/test/test_resumebuilder.py
@@ -35,19 +35,15 @@
         self.cpu.compile_loop(None, loop.inputargs, loop.operations,
                               looptoken)
         descr = loop.operations[2].getdescr()
-        assert descr.rd_bytecode_position == 3
+        assert descr.rd_bytecode_position == 2
         expected_resume = parse("""
-        [i0]
+        []
         enter_frame(-1, descr=jitcode)
-        resume_put(i0, 0, 2)
-        backend_attach(i0, 28)
+        resume_put(28, 0, 2)
         leave_frame()
         """, namespace={'jitcode': jitcode})
-        i0 = descr.rd_resume_bytecode.opcodes[1].getarg(0)
-        i0b = expected_resume.inputargs[0]
         equaloplists(descr.rd_resume_bytecode.opcodes,
-                     expected_resume.operations,
-                     remap={i0b:i0})
+                     expected_resume.operations)
 
     def test_resume_new(self):
         jitcode = JitCode("name")
@@ -76,17 +72,13 @@
         enter_frame(-1, descr=jitcode)
         p0 = resume_new(descr=structdescr)
         resume_setfield_gc(p0, i0, descr=fielddescr)
-        resume_put(p0, 0, 0)
-        backend_attach(i0, 28)
+        resume_put(30, 0, 0)
         leave_frame()
         """, namespace=namespace)
         descr = loop.operations[-3].getdescr()
-        assert descr.rd_bytecode_position == 5
-        i0 = descr.rd_resume_bytecode.opcodes[2].getarg(1)
-        i0b = expected_resume.inputargs[0]
+        assert descr.rd_bytecode_position == 4
         equaloplists(descr.rd_resume_bytecode.opcodes,
-                     expected_resume.operations,
-                     remap={i0b:i0})
+                     expected_resume.operations)
 
     def test_spill(self):
         jitcode = JitCode("name")
@@ -111,17 +103,13 @@
         expected_resume = parse("""
         [i2]
         enter_frame(-1, descr=jitcode)
-        resume_put(i2, 0, 1)
-        backend_attach(i2, 1)
-        backend_attach(i2, 29)
+        resume_put(1, 0, 1)
+        resume_put(29, 0, 1)
         leave_frame()
         """, namespace={'jitcode':jitcode})
         descr1 = loop.operations[3].getdescr()
         descr2 = loop.operations[5].getdescr()
-        assert descr1.rd_bytecode_position == 3
-        assert descr2.rd_bytecode_position == 4
-        i0 = descr1.rd_resume_bytecode.opcodes[1].getarg(0)
-        i0b = expected_resume.inputargs[0]
+        assert descr1.rd_bytecode_position == 2
+        assert descr2.rd_bytecode_position == 3
         equaloplists(descr1.rd_resume_bytecode.opcodes,
-                     expected_resume.operations,
-                     remap={i0b:i0})
+                     expected_resume.operations)
diff --git a/rpython/jit/backend/model.py b/rpython/jit/backend/model.py
--- a/rpython/jit/backend/model.py
+++ b/rpython/jit/backend/model.py
@@ -68,7 +68,7 @@
         """
         raise NotImplementedError
 
-    def compile_bridge(self, logger, faildescr, inputargs, backend_positions,
+    def compile_bridge(self, logger, faildescr, inputframes, backend_positions,
                        operations, original_loop_token, log=True):
         """Assemble the bridge.
         The FailDescr is the descr of the original guard that failed.
diff --git a/rpython/jit/backend/test/runner_test.py 
b/rpython/jit/backend/test/runner_test.py
--- a/rpython/jit/backend/test/runner_test.py
+++ b/rpython/jit/backend/test/runner_test.py
@@ -248,7 +248,7 @@
         ]
 
         locs = rebuild_locs_from_resumedata(faildescr1)
-        self.cpu.compile_bridge(None, faildescr1, [i1b], locs, bridge, 
looptoken)
+        self.cpu.compile_bridge(None, faildescr1, [[i1b]], locs, bridge, 
looptoken)
 
         deadframe = self.cpu.execute_token(looptoken, 2)
         fail = self.cpu.get_latest_descr(deadframe)
@@ -294,7 +294,7 @@
                                    descr=BasicFinalDescr(4)))
 
         faillocs = rebuild_locs_from_resumedata(faildescr1)
-        self.cpu.compile_bridge(None, faildescr1, [i0], faillocs, bridge, 
looptoken)
+        self.cpu.compile_bridge(None, faildescr1, [[i0]], faillocs, bridge, 
looptoken)
 
         deadframe = self.cpu.execute_token(looptoken, 1)
         fail = self.cpu.get_latest_descr(deadframe)
@@ -1426,7 +1426,7 @@
             ResOperation(rop.JUMP, [f3]+fboxes2[1:], None, descr=targettoken),
         ]
 
-        self.cpu.compile_bridge(None, faildescr1, fboxes2,
+        self.cpu.compile_bridge(None, faildescr1, [fboxes2],
                                 rebuild_locs_from_resumedata(faildescr1),
                                 bridge, looptoken)
 
@@ -1491,7 +1491,7 @@
             ResOperation(rop.LEAVE_FRAME, [], None),
             ResOperation(rop.FINISH, [], None, descr=faildescr2),
             ]
-        self.cpu.compile_bridge(None, faildescr1, fboxes,
+        self.cpu.compile_bridge(None, faildescr1, [fboxes],
                                 locs, bridgeops, looptoken)
         args = [1,
                 longlong.getfloatstorage(132.25),
@@ -2953,7 +2953,7 @@
             ResOperation(rop.GUARD_NOT_INVALIDATED, [],None, descr=faildescr2),
             ResOperation(rop.FINISH, [i2], None, descr=BasicFinalDescr(3))
         ]
-        self.cpu.compile_bridge(None, faildescr, [i2], locs, ops, looptoken)
+        self.cpu.compile_bridge(None, faildescr, [[i2]], locs, ops, looptoken)
 
         deadframe = self.cpu.execute_token(looptoken, -42, 9)
         fail = self.cpu.get_latest_descr(deadframe)
@@ -2993,7 +2993,7 @@
         ops2 = [
             ResOperation(rop.JUMP, [ConstInt(333)], None, descr=labeldescr),
         ]
-        self.cpu.compile_bridge(None, faildescr, [], [], ops2, looptoken)
+        self.cpu.compile_bridge(None, faildescr, [[]], [], ops2, looptoken)
         # run: must not be caught in an infinite loop
         deadframe = self.cpu.execute_token(looptoken, 16)
         fail = self.cpu.get_latest_descr(deadframe)
@@ -3872,7 +3872,7 @@
             ResOperation(rop.INT_SUB, [i0, ConstInt(20)], i2),
             ResOperation(rop.JUMP, [i2], None, descr=targettoken2),
             ]
-        self.cpu.compile_bridge(None, faildescr, inputargs2, locs, 
operations2, looptoken)
+        self.cpu.compile_bridge(None, faildescr, [inputargs2], locs, 
operations2, looptoken)
 
         deadframe = self.cpu.execute_token(looptoken, 2)
         fail = self.cpu.get_latest_descr(deadframe)
@@ -3925,7 +3925,7 @@
         self.cpu.assembler.set_debug(False)
         info = self.cpu.compile_loop(None, loop.inputargs, loop.operations, 
looptoken)
         locs = rebuild_locs_from_resumedata(faildescr)
-        bridge_info = self.cpu.compile_bridge(None, faildescr, 
bridge.inputargs,
+        bridge_info = self.cpu.compile_bridge(None, faildescr, 
[bridge.inputargs],
                                               locs, bridge.operations,
                                               looptoken)
         self.cpu.assembler.set_debug(True) # always on untranslated
@@ -4027,7 +4027,7 @@
             ResOperation(rop.JUMP, [i19], None, descr=targettoken1),
             ]
         locs = rebuild_locs_from_resumedata(faildescr1)
-        self.cpu.compile_bridge(None, faildescr1, inputargs, locs, 
operations2, looptoken1)
+        self.cpu.compile_bridge(None, faildescr1, [inputargs], locs, 
operations2, looptoken1)
 
         looptoken2 = JitCellToken()
         inputargs = [BoxInt()]
@@ -4054,7 +4054,7 @@
         operations = [
             ResOperation(rop.FINISH, [], None, descr=BasicFinalDescr(99))
         ]
-        self.cpu.compile_bridge(None, faildescr, [], [], operations, looptoken)
+        self.cpu.compile_bridge(None, faildescr, [[]], [], operations, 
looptoken)
         deadframe = self.cpu.execute_token(looptoken, null_box.getref_base())
         fail = self.cpu.get_latest_descr(deadframe)
         assert fail.identifier == 99
@@ -4291,8 +4291,6 @@
         assert values[0] == 0
 
     def test_compile_bridge_while_running(self):
-        XXX # it crashes because the regalloc does not inherit liveness
-        # rules from the parent, while it shoul
 
         def func():
             jitcode2 = JitCode('name2')
@@ -4333,7 +4331,7 @@
                             'guarddescr': guarddescr, 'func2_ptr': func2_ptr,
                             'jitcode2': jitcode2})
             locs = rebuild_locs_from_resumedata(faildescr)
-            self.cpu.compile_bridge(None, faildescr, bridge.inputargs, locs,
+            self.cpu.compile_bridge(None, faildescr, [bridge.inputargs], locs,
                                     bridge.operations, looptoken)
 
         cpu = self.cpu
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
@@ -3,14 +3,14 @@
 
 from rpython.jit.backend.llsupport import symbolic, jitframe, rewrite
 from rpython.jit.backend.llsupport.assembler import (GuardToken, BaseAssembler,
-                                                DEBUG_COUNTER, debug_bridge)
+                                                     debug_bridge)
 from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper
-from rpython.jit.backend.llsupport.gcmap import allocate_gcmap
+from rpython.jit.backend.llsupport.regalloc import flatten
 from rpython.jit.metainterp.history import Const, Box, VOID
 from rpython.jit.metainterp.history import AbstractFailDescr, INT, REF, FLOAT
 from rpython.rtyper.lltypesystem import lltype, rffi, rstr, llmemory
 from rpython.rtyper.lltypesystem.lloperation import llop
-from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref
+from rpython.rtyper.annlowlevel import cast_instance_to_gcref
 from rpython.rlib.jit import AsmInfo
 from rpython.jit.backend.model import CompiledLoopToken
 from rpython.jit.backend.x86.regalloc import (RegAlloc, get_ebp_ofs,
@@ -29,7 +29,6 @@
 from rpython.jit.metainterp.resoperation import rop
 from rpython.jit.backend.x86 import support
 from rpython.rlib.debug import debug_print, debug_start, debug_stop
-from rpython.rlib import rgc
 from rpython.jit.codewriter.effectinfo import EffectInfo
 from rpython.jit.codewriter import longlong
 from rpython.rlib.rarithmetic import intmask, r_uint
@@ -514,11 +513,8 @@
         return AsmInfo(ops_offset, rawstart + looppos,
                        size_excluding_failure_stuff - looppos)
 
-    def assemble_bridge(self, logger, faildescr, inputargs, backend_positions,
+    def assemble_bridge(self, logger, faildescr, inputframes, 
backend_positions,
                         operations, original_loop_token, log):
-        if not we_are_translated():
-            # Arguments should be unique
-            assert len(set(inputargs)) == len(inputargs)
 
         self.setup(original_loop_token)
         descr_number = compute_unique_id(faildescr)
@@ -526,10 +522,11 @@
             operations = self._inject_debugging_code(faildescr, operations,
                                                      'b', descr_number)
 
+        inputargs = flatten(inputframes)
         arglocs = self.rebuild_faillocs_from_descr(faildescr, inputargs, 
backend_positions)
         regalloc = RegAlloc(self, self.cpu.translate_support_code)
         startpos = self.mc.get_relative_pos()
-        operations = regalloc.prepare_bridge(inputargs, arglocs,
+        operations = regalloc.prepare_bridge(inputframes, arglocs,
                                              operations,
                                              self.current_clt.allgcrefs,
                                              self.current_clt.frame_info,
diff --git a/rpython/jit/backend/x86/regalloc.py 
b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -9,7 +9,8 @@
 from rpython.jit.backend.llsupport.gcmap import allocate_gcmap
 from rpython.jit.backend.llsupport.resumebuilder import ResumeBuilder
 from rpython.jit.backend.llsupport.regalloc import (FrameManager, BaseRegalloc,
-     RegisterManager, TempBox, compute_vars_longevity, is_comparison_or_ovf_op)
+     RegisterManager, TempBox, compute_vars_longevity, is_comparison_or_ovf_op,
+    flatten)
 from rpython.jit.backend.x86 import rx86
 from rpython.jit.backend.x86.arch import (WORD, JITFRAME_FIXED_SIZE, IS_X86_32,
     IS_X86_64)
@@ -132,13 +133,13 @@
         self.jump_target_descr = None
         self.final_jump_op = None
 
-    def _prepare(self, inputargs, operations, allgcrefs, descr=None):
+    def _prepare(self, inputframes, operations, allgcrefs, descr=None):
         cpu = self.assembler.cpu
         self.fm = X86FrameManager(cpu.get_baseofs_of_frame_field())
         operations = cpu.gc_ll_descr.rewrite_assembler(cpu, operations,
                                                        allgcrefs)
         # compute longevity of variables
-        x = compute_vars_longevity(inputargs, operations, descr)
+        x = compute_vars_longevity(inputframes, operations, descr)
         longevity, last_real_usage, frontend_liveness = x
         self.resumebuilder = ResumeBuilder(self, frontend_liveness, descr)
         self.longevity = longevity
@@ -151,7 +152,7 @@
         return operations
 
     def prepare_loop(self, inputargs, operations, looptoken, allgcrefs):
-        operations = self._prepare(inputargs, operations, allgcrefs)
+        operations = self._prepare([inputargs], operations, allgcrefs)
         self._set_initial_bindings(inputargs, looptoken)
         # note: we need to make a copy of inputargs because possibly_free_vars
         # is also used on op args, which is a non-resizable list
@@ -162,10 +163,10 @@
             self.min_bytes_before_label = 13
         return operations
 
-    def prepare_bridge(self, inputargs, arglocs, operations, allgcrefs,
+    def prepare_bridge(self, inputframes, arglocs, operations, allgcrefs,
                        frame_info, descr):
-        operations = self._prepare(inputargs, operations, allgcrefs, descr)
-        self._update_bindings(arglocs, inputargs)
+        operations = self._prepare(inputframes, operations, allgcrefs, descr)
+        self._update_bindings(arglocs, inputframes)
         self.min_bytes_before_label = 0
         return operations
 
@@ -229,10 +230,11 @@
         else:
             return self.xrm.make_sure_var_in_reg(var, forbidden_vars)
 
-    def _update_bindings(self, locs, inputargs):
+    def _update_bindings(self, locs, inputframes):
         # XXX this should probably go to llsupport/regalloc.py
         used = {}
         i = 0
+        inputargs = flatten(inputframes)
         for loc in locs:
             if loc is None: # xxx bit kludgy
                 loc = ebp
diff --git a/rpython/jit/backend/x86/runner.py 
b/rpython/jit/backend/x86/runner.py
--- a/rpython/jit/backend/x86/runner.py
+++ b/rpython/jit/backend/x86/runner.py
@@ -93,11 +93,11 @@
         return self.assembler.assemble_loop(logger, name, inputargs, 
operations,
                                             looptoken, log=log)
 
-    def compile_bridge(self, logger, faildescr, inputargs, backend_positions,
+    def compile_bridge(self, logger, faildescr, inputframes, backend_positions,
                        operations, original_loop_token, log=True):
         clt = original_loop_token.compiled_loop_token
         clt.compiling_a_bridge()
-        return self.assembler.assemble_bridge(logger, faildescr, inputargs,
+        return self.assembler.assemble_bridge(logger, faildescr, inputframes,
                                               backend_positions, operations,
                                               original_loop_token, log=log)
 
diff --git a/rpython/jit/metainterp/resoperation.py 
b/rpython/jit/metainterp/resoperation.py
--- a/rpython/jit/metainterp/resoperation.py
+++ b/rpython/jit/metainterp/resoperation.py
@@ -472,10 +472,11 @@
     # resume-only operations that never make it to the real assembler
     'ENTER_FRAME/1d',
     'LEAVE_FRAME/0',
-    'RESUME_PUT/3',
+    'RESUME_PUT/3', # arguments are as follows - box or position in the 
backend,
+                    # the frame index (counting from top) and position in the
+                    # frontend
     'RESUME_NEW/0d',
     'RESUME_SETFIELD_GC/2d',
-    'BACKEND_ATTACH/2',
     '_RESUME_LAST', # ----- end of resume only operations ------
     '_NOSIDEEFFECT_LAST', # ----- end of no_side_effect operations -----
 
diff --git a/rpython/jit/metainterp/resume2.py 
b/rpython/jit/metainterp/resume2.py
--- a/rpython/jit/metainterp/resume2.py
+++ b/rpython/jit/metainterp/resume2.py
@@ -41,8 +41,6 @@
             elif op.getopnum() == rop.RESUME_SETFIELD_GC:
                 self.resume_setfield_gc(op.getarg(0), op.getarg(1),
                                         op.getdescr())
-            elif op.getopnum() == rop.BACKEND_ATTACH:
-                self.resume_backend_attach(op.getarg(0), op.getarg(1).getint())
             elif not op.is_resume():
                 pos += 1
                 continue
@@ -72,9 +70,6 @@
         self.deadframe = deadframe
         self.backend_values = {}
 
-    def resume_backend_attach(self, box, position):
-        self.backend_values[box] = position
-
     def enter_frame(self, pc, jitcode):
         if pc != -1:
             self.metainterp.framestack[-1].pc = pc
diff --git a/rpython/jit/metainterp/test/test_resume2.py 
b/rpython/jit/metainterp/test/test_resume2.py
--- a/rpython/jit/metainterp/test/test_resume2.py
+++ b/rpython/jit/metainterp/test/test_resume2.py
@@ -26,7 +26,7 @@
     def dump_registers(self, lst, backend_values):
         lst += [backend_values[x] for x in self.registers_i]
         lst += [backend_values[x] for x in self.registers_r]
-        lst += [backend_values[x] for x in self.registers_f]        
+        lst += [backend_values[x] for x in self.registers_f]
 
 class MockMetaInterp(object):
     def __init__(self):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to