[pypy-svn] r63585 - pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86

fijal at codespeak.net fijal at codespeak.net
Fri Apr 3 22:41:40 CEST 2009


Author: fijal
Date: Fri Apr  3 22:41:37 2009
New Revision: 63585

Modified:
   pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/assembler.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/regalloc.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/runner.py
Log:
a bit of progress. mostly removing/commenting out unnecessary code


Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/assembler.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/assembler.py	Fri Apr  3 22:41:37 2009
@@ -60,7 +60,6 @@
         self.counter -= 1
 
 class Assembler386(object):
-    generic_return_addr = 0
     log_fd = -1
     mc = None
     mc2 = None
@@ -108,7 +107,6 @@
                 self._exception_bck)
             self.mc = self.mcstack.next_mc()
             self.mc2 = self.mcstack.next_mc()
-            self.generic_return_addr = self.assemble_generic_return()
             # the address of the function called by 'new': directly use
             # Boehm's GC_malloc function.
             if self.malloc_func_addr == 0:
@@ -149,7 +147,7 @@
                                                ",".join(reprs)))
         os.write(self._log_fd, 'xxxxxxxxxx\n')
 
-    def log_call(self, name, valueboxes):
+    def log_call(self, valueboxes):
         if self._log_fd == -1:
             return
         return # XXX
@@ -158,10 +156,25 @@
         os.write(self._log_fd, "CALL\n")
         os.write(self._log_fd, "%s %s\n" % (name, args_s))
 
+    def _compute_longest_fail_op(self, ops):
+        max_so_far = 0
+        for op in ops:
+            if op.opnum == rop.FAIL:
+                max_so_far = max(max_so_far, len(op.args))
+            if op.is_guard():
+                max_so_far = max(max_so_far, self._compute_longest_fail_op(
+                    op.suboperations))
+        return max_so_far
+
     def assemble(self, tree):
         # the last operation can be 'jump', 'return' or 'guard_pause';
         # a 'jump' can either close a loop, or end a bridge to some
         # previously-compiled code.
+        num = self._compute_longest_fail_op(tree.operations)
+        fail_boxes = lltype.malloc(rffi.CArray(lltype.Signed), num,
+                                   flavor='raw')
+        self.fail_box_addr = self.cpu.cast_ptr_to_int(fail_boxes)
+        tree.fail_boxes = fail_boxes
         self.make_sure_mc_exists()
         inputargs = tree.inputargs
         op0 = tree.operations[0]
@@ -209,29 +222,30 @@
         finally:
             Box._extended_display = _prev
 
-    def assemble_comeback_bootstrap(self, position, arglocs, stacklocs):
-        entry_point_addr = self.mc2.tell()
-        for i in range(len(arglocs)):
-            argloc = arglocs[i]
-            if isinstance(argloc, REG):
-                self.mc2.MOV(argloc, stack_pos(stacklocs[i]))
-            elif not we_are_translated():
-                # debug checks
-                if not isinstance(argloc, (IMM8, IMM32)):
-                    assert repr(argloc) == repr(stack_pos(stacklocs[i]))
-        self.mc2.JMP(rel32(position))
-        self.mc2.done()
-        return entry_point_addr
-
-    def assemble_generic_return(self):
-        # generate a generic stub that just returns, taking the
-        # return value from *esp (i.e. stack position 0).
-        addr = self.mc.tell()
-        self.mc.MOV(eax, mem(esp, 0))
-        self.mc.ADD(esp, imm(FRAMESIZE))
-        self.mc.RET()
-        self.mc.done()
-        return addr
+#     def assemble_comeback_bootstrap(self, position, arglocs, stacklocs):
+#         return
+#         entry_point_addr = self.mc2.tell()
+#         for i in range(len(arglocs)):
+#             argloc = arglocs[i]
+#             if isinstance(argloc, REG):
+#                 self.mc2.MOV(argloc, stack_pos(stacklocs[i]))
+#             elif not we_are_translated():
+#                 # debug checks
+#                 if not isinstance(argloc, (IMM8, IMM32)):
+#                     assert repr(argloc) == repr(stack_pos(stacklocs[i]))
+#         self.mc2.JMP(rel32(position))
+#         self.mc2.done()
+#         return entry_point_addr
+
+#     def assemble_generic_return(self):
+#         # generate a generic stub that just returns, taking the
+#         # return value from *esp (i.e. stack position 0).
+#         addr = self.mc.tell()
+#         self.mc.MOV(eax, mem(esp, 0))
+#         self.mc.ADD(esp, imm(FRAMESIZE))
+#         self.mc.RET()
+#         self.mc.done()
+#         return addr
 
     def regalloc_load(self, from_loc, to_loc):
         self.mc.MOV(to_loc, from_loc)
@@ -520,8 +534,8 @@
     def make_merge_point(self, tree, locs, stacklocs):
         pos = self.mc.tell()
         tree.position = pos
-        tree.comeback_bootstrap_addr = self.assemble_comeback_bootstrap(pos,
-                                                        locs, stacklocs)
+        #tree.comeback_bootstrap_addr = self.assemble_comeback_bootstrap(pos,
+        #                                                locs, stacklocs)
 
     def genop_discard_return(self, op, locs):
         if op.args:
@@ -601,8 +615,18 @@
         self.mc = oldmc
         return addr
 
-    def genop_discard_fail(self, op, arglocs):
+    def genop_fail(self, op, locs, guard_index):
+        for i in range(len(locs)):
+            loc = locs[i]
+            if isinstance(loc, REG):
+                self.mc.MOV(addr_add(imm(self.fail_box_addr), imm(i)), loc)
+        for i in range(len(locs)):
+            loc = locs[i]
+            if not isinstance(loc, REG):
+                self.mc.MOV(eax, loc)
+                self.mc.MOV(addr_add(imm(self.fail_box_addr), imm(i)), eax)
         self.mc.ADD(esp, imm(FRAMESIZE))
+        self.mc.MOV(eax, imm(guard_index))
         self.mc.RET()
 
     @specialize.arg(2)
@@ -673,7 +697,7 @@
         print "not implemented operation with res: %s" % op.getopname()
         raise NotImplementedError
 
-    def not_implemented_op_guard(self, op, arglocs, resloc, descr):
+    def not_implemented_op_guard(self, op, regalloc, arglocs, resloc, descr):
         print "not implemented operation (guard): %s" % op.getopname()
         raise NotImplementedError
 

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/regalloc.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/regalloc.py	Fri Apr  3 22:41:37 2009
@@ -47,8 +47,10 @@
         raise ValueError("convert_to_imm: got a %s" % c)
 
 class RegAlloc(object):
+    guard_index = -1
+    
     def __init__(self, assembler, tree, translate_support_code=False,
-                 regalloc=None, suboperations=None):
+                 regalloc=None, guard_op=None):
         # variables that have place in register
         self.assembler = assembler
         self.translate_support_code = translate_support_code
@@ -68,7 +70,7 @@
             self.loop_consts = loop_consts
             self.current_stack_depth = sd
         else:
-            inp = self._compute_vars_longevity_backwards(suboperations)
+            inp = guard_op.inputargs
             self.reg_bindings = {}
             self.stack_bindings = {}
             self.dirty_stack = {}
@@ -83,16 +85,17 @@
             self.free_regs = [v for v in REGS if v not in allocated_regs]
             self.loop_consts = regalloc.loop_consts # should never change
             self.current_stack_depth = regalloc.current_stack_depth
-            # XXXX think about this, since we might jump somewhere else
-            #      entirely
-            self.jump_reg_candidates = regalloc.jump_reg_candidates
-            self.inputargs = inp
+            # XXX think what to do if there is actually a jump
+            self.jump_reg_candidates = {}
+            self.longevity = guard_op.longevity
+            #self.jump_reg_candidates = regalloc.jump_reg_candidates
 
-    def copy(self, suboperations):
+    def copy(self, guard_op):
         return RegAlloc(self.assembler, None, self.translate_support_code,
-                        self, suboperations)
+                        self, guard_op)
 
     def _start_from_guard_op(self, guard_op, mp, jump):
+        xxx
         rev_stack_binds = {}
         self.jump_reg_candidates = {}
         j = 0
@@ -220,7 +223,7 @@
         # first pass - walk along the operations in order to find
         # load/store places
         operations = tree.operations
-        self.position = 0
+        self.position = -1
         self.process_inputargs(tree)
         self._walk_operations(operations)
 
@@ -267,16 +270,25 @@
                 if isinstance(arg, Box):
                     longevity[arg] = (start_live[arg], i)
             if op.is_guard():
-                for arg in op.suboperations[-1].args:
-                    assert isinstance(arg, Box)
-                    longevity[arg] = (start_live[arg], i)
+                self._compute_inpargs(op)
+                for arg in op.inputargs:
+                    if isinstance(arg, Box):
+                        longevity[arg] = (start_live[arg], i)
         self.longevity = longevity
 
-    def _compute_vars_longevity_backwards(self, operations):
+    def _compute_inpargs(self, guard):
+        if guard.inputargs is not None:
+            return
+        operations = guard.suboperations
         longevity = {}
         end = {}
         for i in range(len(operations)-1, -1, -1):
             op = operations[i]
+            if op.is_guard():
+                self._compute_inpargs()
+                for arg in op.inputargs:
+                    if arg not in longevity:
+                        end[arg] = i
             for arg in op.args:
                 if arg not in longevity:
                     end[arg] = i
@@ -285,8 +297,8 @@
                 del end[op.result]
         for v, e in end.items():
             longevity[v] = (0, e)
-        self.longevity = longevity
-        return end.keys()
+        guard.longevity = longevity
+        guard.inputargs = end.keys()
 
     def try_allocate_reg(self, v, selected_reg=None):
         if isinstance(v, Const):
@@ -378,10 +390,10 @@
             self.Store(v_to_spill, loc, newloc)
         return loc
 
-    def _locs_from_liveboxes(self, guard_op, inpargs):
+    def _locs_from_liveboxes(self, guard_op):
         stacklocs = []
         locs = []
-        for arg in inpargs:
+        for arg in guard_op.inputargs:
             assert isinstance(arg, Box)
             if arg not in self.stack_bindings:
                 self.dirty_stack[arg] = True
@@ -548,8 +560,8 @@
 
     def consider_fail(self, op, ignored):
         # make sure all vars are on stack
-        locs = [self.make_sure_var_on_stack(arg) for arg in op.args]
-        self.PerformDiscard(op, locs)
+        locs = [self.loc(arg) for arg in op.args]
+        self.assembler.genop_fail(op, locs, self.guard_index)
         self.eventually_free_vars(op.args)
 
     def consider_guard_nonvirtualized(self, op, ignored):
@@ -727,13 +739,16 @@
             loc = self.force_allocate_reg(op.result, op.args)
             self.Perform(op, arglocs, loc)
         else:
-            regalloc = self.copy(guard_op.suboperations)
-            locs = self._locs_from_liveboxes(guard_op, regalloc.inputargs)
+            regalloc = self.copy(guard_op)
+            fop = guard_op.suboperations[-1]
+            assert fop.opnum == rop.FAIL # XXX also JUMP
+            regalloc.guard_index = self.assembler.cpu.make_guard_index(fop)
+            locs = self._locs_from_liveboxes(guard_op)
             self.position += 1
-            self.eventually_free_var(op.result)
-            self.eventually_free_vars(regalloc.inputargs)
             self.perform_with_guard(op, guard_op, regalloc, arglocs + locs,
                                     None)
+            self.eventually_free_var(op.result)
+            self.eventually_free_vars(guard_op.inputargs)
 
     consider_int_lt = _consider_compop
     consider_int_gt = _consider_compop

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/runner.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/runner.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/runner.py	Fri Apr  3 22:41:37 2009
@@ -183,13 +183,13 @@
     def compile_operations(self, tree):
         self.assembler.assemble(tree)
 
-    def get_bootstrap_code(self, startmp):
+    def get_bootstrap_code(self, loop):
         # key is locations of arguments
-        key = ','.join([str(i) for i in startmp.arglocs])
+        key = ','.join([str(i) for i in loop.arglocs])
         try:
             func = self._bootstrap_cache[key]
         except KeyError:
-            arglocs = startmp.arglocs
+            arglocs = loop.arglocs
             addr = self.assembler.assemble_bootstrap_code(arglocs)
             # arguments are as follows - address to jump to,
             # and a list of args
@@ -213,13 +213,11 @@
         else:
             raise ValueError('get_box_value_as_int, wrong arg')
 
-    def get_valuebox_from_int(self, type, x):
-        if type == INT:
-            return history.BoxInt(x)
-        elif type == PTR:
-            return history.BoxPtr(self.cast_int_to_gcref(x))
-        else:
-            raise ValueError('get_valuebox_from_int: %s' % (type,))
+    def set_value_of_box(self, box, index, fail_boxes):
+        if isinstance(box, BoxInt):
+            box.value = fail_boxes[index]
+        elif isinstance(box, BoxPtr):
+            xxx
 
     def _get_mp_for_call(self, argnum, calldescr):
         try:
@@ -238,9 +236,6 @@
 
     def execute_operations(self, loop, valueboxes):
         func = self.get_bootstrap_code(loop)
-        import pdb
-        pdb.set_trace()
-        startmp = operations[0]
         # turn all the values into integers
         TP = rffi.CArray(lltype.Signed)
         oldindex = self.keepalives_index
@@ -254,22 +249,19 @@
         #    values_repr = ", ".join([str(values_as_int[i]) for i in
         #                             range(len(valueboxes))])
         #    llop.debug_print(lltype.Void, 'exec:', name, values_repr)
-        self.assembler.log_call(name, valueboxes)
-
+        self.assembler.log_call(valueboxes)
         self.keepalives_index = len(self.keepalives)
-        res = self.execute_call(startmp, func, values_as_int)
-        if self.return_value_type == VOID:
-            #self.assembler.log_void_result()
-            res = None
-        else:
-            #self.assembler.log_result(res)
-            res = self.get_valuebox_from_int(self.return_value_type, res)
+        guard_index = self.execute_call(loop, func, values_as_int)
         keepalive_until_here(valueboxes)
         self.keepalives_index = oldindex
         del self.keepalives[oldindex:]
-        return res
+        op = self._guard_list[guard_index]
+        for i in range(len(op.args)):
+            box = op.args[i]
+            self.set_value_of_box(box, i, loop.fail_boxes)
+        return op
 
-    def execute_call(self, startmp, func, values_as_int):
+    def execute_call(self, loop, func, values_as_int):
         # help flow objspace
         prev_interpreter = None
         if not self.translate_support_code:
@@ -278,7 +270,7 @@
         res = 0
         try:
             self.caught_exception = None
-            res = func(startmp.position, values_as_int)
+            res = func(loop.position, values_as_int)
             self.reraise_caught_exception()
         finally:
             if not self.translate_support_code:
@@ -319,22 +311,22 @@
         else:
             raise ValueError(valuebox.type)
 
-    def getvaluebox(self, frameadr, guard_op, argindex):
-        # XXX that's plain stupid, do we care about the return value???
-        box = guard_op.liveboxes[argindex]
-        frame = getframe(frameadr)
-        pos = guard_op.stacklocs[argindex]
-        intvalue = frame[pos]
-        if isinstance(box, history.BoxInt):
-            return history.BoxInt(intvalue)
-        elif isinstance(box, history.BoxPtr):
-            return history.BoxPtr(self.cast_int_to_gcref(intvalue))
-        else:
-            raise AssertionError('getvalue: box = %s' % (box,))
-
-    def setvaluebox(self, frameadr, mp, argindex, valuebox):
-        frame = getframe(frameadr)
-        frame[mp.stacklocs[argindex]] = self.convert_box_to_int(valuebox)
+#     def getvaluebox(self, frameadr, guard_op, argindex):
+#         # XXX that's plain stupid, do we care about the return value???
+#         box = guard_op.liveboxes[argindex]
+#         frame = getframe(frameadr)
+#         pos = guard_op.stacklocs[argindex]
+#         intvalue = frame[pos]
+#         if isinstance(box, history.BoxInt):
+#             return history.BoxInt(intvalue)
+#         elif isinstance(box, history.BoxPtr):
+#             return history.BoxPtr(self.cast_int_to_gcref(intvalue))
+#         else:
+#             raise AssertionError('getvalue: box = %s' % (box,))
+
+#     def setvaluebox(self, frameadr, mp, argindex, valuebox):
+#         frame = getframe(frameadr)
+#         frame[mp.stacklocs[argindex]] = self.convert_box_to_int(valuebox)
 
     def sizeof(self, S):
         size = symbolic.get_size(S, self.translate_support_code)
@@ -591,32 +583,32 @@
             x += 0x100000000
         return hex(x)
 
-class GuardFailed(object):
-    return_value_type = 0
+# class GuardFailed(object):
+#     return_value_type = 0
     
-    def __init__(self, cpu, frame, guard_op):
-        self.cpu = cpu
-        self.frame = frame
-        self.guard_op = guard_op
-
-    def make_ready_for_return(self, return_value_box):
-        self.cpu.assembler.make_sure_mc_exists()
-        if return_value_box is not None:
-            frame = getframe(self.frame)
-            frame[0] = self.cpu.convert_box_to_int(return_value_box)
-            if (isinstance(return_value_box, ConstInt) or
-                isinstance(return_value_box, BoxInt)):
-                self.return_value_type = INT
-            else:
-                self.return_value_type = PTR
-        else:
-            self.return_value_type = VOID
-        self.return_addr = self.cpu.assembler.generic_return_addr
-
-    def make_ready_for_continuing_at(self, merge_point):
-        # we need to make sure here that return_addr points to a code
-        # that is ready to grab coorect values
-        self.return_addr = merge_point.comeback_bootstrap_addr
+#     def __init__(self, cpu, frame, guard_op):
+#         self.cpu = cpu
+#         self.frame = frame
+#         self.guard_op = guard_op
+
+#     def make_ready_for_return(self, return_value_box):
+#         self.cpu.assembler.make_sure_mc_exists()
+#         if return_value_box is not None:
+#             frame = getframe(self.frame)
+#             frame[0] = self.cpu.convert_box_to_int(return_value_box)
+#             if (isinstance(return_value_box, ConstInt) or
+#                 isinstance(return_value_box, BoxInt)):
+#                 self.return_value_type = INT
+#             else:
+#                 self.return_value_type = PTR
+#         else:
+#             self.return_value_type = VOID
+#         self.return_addr = self.cpu.assembler.generic_return_addr
+
+#     def make_ready_for_continuing_at(self, merge_point):
+#         # we need to make sure here that return_addr points to a code
+#         # that is ready to grab coorect values
+#         self.return_addr = merge_point.comeback_bootstrap_addr
 
 def getframe(frameadr):
     return rffi.cast(rffi.CArrayPtr(lltype.Signed), frameadr)



More information about the Pypy-commit mailing list