[pypy-svn] r67931 - pypy/branch/refactor-x86/pypy/jit/backend/x86

fijal at codespeak.net fijal at codespeak.net
Mon Sep 28 15:02:41 CEST 2009


Author: fijal
Date: Mon Sep 28 15:02:35 2009
New Revision: 67931

Modified:
   pypy/branch/refactor-x86/pypy/jit/backend/x86/regalloc.py
Log:
Progress, now got stopped by cond_gc_call_wb, which directly
uses weird hacks


Modified: pypy/branch/refactor-x86/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/branch/refactor-x86/pypy/jit/backend/x86/regalloc.py	(original)
+++ pypy/branch/refactor-x86/pypy/jit/backend/x86/regalloc.py	Mon Sep 28 15:02:35 2009
@@ -31,6 +31,13 @@
     return checkdict()
 
 class X86RegisterManager(RegisterManager):
+
+    no_lower_byte_regs = [esi, edi]
+    save_around_call_regs = [eax, edx, ecx]
+
+    def result_stored_in_reg(self, v):
+        return eax
+
     def convert_to_imm(self, c):
         if isinstance(c, ConstInt):
             return imm(c.value)
@@ -66,13 +73,12 @@
         self.jump_target = None
 
     def prepare_loop(self, inputargs, operations):
+        self.sm = X86StackManager()
         cpu = self.assembler.cpu
         cpu.gc_ll_descr.rewrite_assembler(cpu, operations)
         # compute longevity of variables
         longevity = self._compute_vars_longevity(inputargs, operations)
-        self.sm = X86StackManager()
         self.rm = X86RegisterManager(REGS, longevity,
-                                     no_lower_byte_regs = [esi, edi],
                                      stack_manager = self.sm,
                                      assembler = self.assembler)
         jump = operations[-1]
@@ -81,14 +87,17 @@
         return self._process_inputargs(inputargs)
 
     def prepare_bridge(self, prev_stack_depth, inputargs, arglocs, operations):
-        xxxx
+        self.sm = X86StackManager()
         cpu = self.assembler.cpu        
         cpu.gc_ll_descr.rewrite_assembler(cpu, operations)
         # compute longevity of variables
-        self._compute_vars_longevity(inputargs, operations)
+        longevity = self._compute_vars_longevity(inputargs, operations)
+        self.rm = X86RegisterManager(REGS, longevity,
+                                     stack_manager = self.sm,
+                                     assembler = self.assembler)
         self.loop_consts = {}
         self._update_bindings(arglocs, inputargs)
-        self.current_stack_depth = prev_stack_depth
+        self.sm.stack_depth = prev_stack_depth
 
     def _process_inputargs(self, inputargs):
         # XXX we can sort out here by longevity if we need something
@@ -126,6 +135,7 @@
         return loop_consts
 
     def _update_bindings(self, locs, args):
+        # XXX this should probably go to llsupport/regalloc.py
         newlocs = []
         for loc in locs:
             if not isinstance(loc, IMM8) and not isinstance(loc, IMM32):
@@ -136,16 +146,16 @@
         for i in range(len(locs)):
             v = args[i]
             loc = locs[i]
-            if isinstance(loc, REG) and self.longevity[v][1] > -1:
-                self.reg_bindings[v] = loc
+            if isinstance(loc, REG) and self.rm.longevity[v][1] > -1:
+                self.rm.reg_bindings[v] = loc
                 used[loc] = None
             else:
                 self.stack_bindings[v] = loc
-        self.free_regs = []
+        self.rm.free_regs = []
         for reg in REGS:
             if reg not in used:
-                self.free_regs.append(reg)
-        self._check_invariants()
+                self.rm.free_regs.append(reg)
+        self.rm._check_invariants()
 
     def Perform(self, op, arglocs, result_loc):
         if not we_are_translated():
@@ -168,7 +178,6 @@
         self.rm.possibly_free_vars(guard_op.suboperations[0].args)
 
     def perform_guard(self, guard_op, arglocs, result_loc):
-        xxx
         faillocs = self.locs_for_fail(guard_op)
         if not we_are_translated():
             if result_loc is not None:
@@ -178,8 +187,8 @@
                 self.assembler.dump('%s(%s)' % (guard_op, arglocs))
         self.assembler.regalloc_perform_guard(guard_op, faillocs, arglocs,
                                               result_loc,
-                                              self.current_stack_depth)
-        self.eventually_free_vars(guard_op.suboperations[0].args)        
+                                              self.sm.stack_depth)
+        self.rm.possibly_free_vars(guard_op.suboperations[0].args)        
 
     def PerformDiscard(self, op, arglocs):
         if not we_are_translated():
@@ -255,9 +264,9 @@
         return self.rm.loc(v)
 
     def _consider_guard(self, op, ignored):
-        loc = self.make_sure_var_in_reg(op.args[0], [])
+        loc = self.rm.make_sure_var_in_reg(op.args[0])
         self.perform_guard(op, [loc], None)
-        self.eventually_free_var(op.args[0])
+        self.rm.possibly_free_var(op.args[0])
 
     consider_guard_true = _consider_guard
     consider_guard_false = _consider_guard
@@ -274,33 +283,33 @@
         self.perform_guard(op, [], None)
 
     def consider_guard_exception(self, op, ignored):
-        loc = self.make_sure_var_in_reg(op.args[0], [])
+        loc = self.rm.make_sure_var_in_reg(op.args[0])
         box = TempBox()
-        loc1 = self.force_allocate_reg(box, op.args)
-        if op.result in self.longevity:
+        loc1 = self.rm.force_allocate_reg(box, op.args)
+        if op.result in self.rm.longevity:
             # this means, is it ever used
-            resloc = self.force_allocate_reg(op.result, op.args + [box])
+            resloc = self.rm.force_allocate_reg(op.result, op.args + [box])
         else:
             resloc = None
         self.perform_guard(op, [loc, loc1], resloc)
-        self.eventually_free_vars(op.args)
-        self.eventually_free_var(box)
+        self.rm.possibly_free_vars(op.args)
+        self.rm.possibly_free_var(box)
 
     consider_guard_no_overflow = consider_guard_no_exception
     consider_guard_overflow    = consider_guard_no_exception
 
     def consider_guard_value(self, op, ignored):
-        x = self.make_sure_var_in_reg(op.args[0], [])
+        x = self.rm.make_sure_var_in_reg(op.args[0])
         y = self.loc(op.args[1])
         self.perform_guard(op, [x, y], None)
-        self.eventually_free_vars(op.args)
+        self.rm.possibly_free_vars(op.args)
 
     def consider_guard_class(self, op, ignored):
         assert isinstance(op.args[0], Box)
-        x = self.make_sure_var_in_reg(op.args[0], [])
+        x = self.rm.make_sure_var_in_reg(op.args[0])
         y = self.loc(op.args[1])
         self.perform_guard(op, [x, y], None)
-        self.eventually_free_vars(op.args)
+        self.rm.possibly_free_vars(op.args)
     
     def _consider_binop_part(self, op, ignored):
         x = op.args[0]
@@ -325,7 +334,7 @@
     consider_int_add_ovf = _consider_binop
 
     def consider_int_neg(self, op, ignored):
-        res = self.force_result_in_reg(op.result, op.args[0], [])
+        res = self.rm.force_result_in_reg(op.result, op.args[0])
         self.Perform(op, [res], res)
 
     consider_int_invert = consider_int_neg
@@ -335,24 +344,26 @@
         if isinstance(op.args[1], Const):
             loc2 = convert_to_imm(op.args[1])
         else:
-            loc2 = self.make_sure_var_in_reg(op.args[1], [], ecx)
-        loc1 = self.force_result_in_reg(op.result, op.args[0], op.args)
+            loc2 = self.rm.make_sure_var_in_reg(op.args[1], selected_reg=ecx)
+        loc1 = self.rm.force_result_in_reg(op.result, op.args[0], op.args)
         self.Perform(op, [loc1, loc2], loc1)
-        self.eventually_free_vars(op.args)
+        self.rm.possibly_free_vars(op.args)
 
     consider_int_rshift  = consider_int_lshift
     consider_uint_rshift = consider_int_lshift
 
     def _consider_int_div_or_mod(self, op, resultreg, trashreg):
-        l0 = self.make_sure_var_in_reg(op.args[0], [], eax)
-        l1 = self.make_sure_var_in_reg(op.args[1], [], ecx)
-        l2 = self.force_allocate_reg(op.result, [], resultreg)
+        l0 = self.rm.make_sure_var_in_reg(op.args[0], selected_reg=eax)
+        l1 = self.rm.make_sure_var_in_reg(op.args[1], selected_reg=ecx)
+        l2 = self.rm.force_allocate_reg(op.result, selected_reg=resultreg)
         # the register (eax or edx) not holding what we are looking for
         # will be just trash after that operation
         tmpvar = TempBox()
-        self.force_allocate_reg(tmpvar, [], trashreg)
-        assert (l0, l1, l2) == (eax, ecx, resultreg)
-        self.eventually_free_vars(op.args + [tmpvar])
+        self.rm.force_allocate_reg(tmpvar, selected_reg=trashreg)
+        assert l0 is eax
+        assert l1 is ecx
+        assert l2 is resultreg
+        self.rm.possibly_free_vars(op.args + [tmpvar])
 
     def consider_int_mod(self, op, ignored):
         self._consider_int_div_or_mod(op, edx, eax)
@@ -370,11 +381,11 @@
             isinstance(vx, Const) or isinstance(vy, Const)):
             pass
         else:
-            arglocs[0] = self.make_sure_var_in_reg(vx, [])
+            arglocs[0] = self.rm.make_sure_var_in_reg(vx)
         self.rm.possibly_free_vars(op.args)
         if guard_op is None:
-            loc = self.force_allocate_reg(op.result, op.args,
-                                          need_lower_byte=True)
+            loc = self.rm.force_allocate_reg(op.result, op.args,
+                                             need_lower_byte=True)
             self.Perform(op, arglocs, loc)
         else:
             self.perform_with_guard(op, guard_op, arglocs, None)
@@ -399,24 +410,9 @@
         # otherwise it's clean
 
     def _call(self, op, arglocs, force_store=[]):
-        # we need to store all variables which are now
-        # in registers eax, ecx and edx
-        for v, reg in self.reg_bindings.items():
-            if v not in force_store and self.longevity[v][1] <= self.position:
-                # variable dies
-                del self.reg_bindings[v]
-                self.free_regs.append(reg)
-                continue
-            if reg is ebx or reg is esi or reg is edi:
-                # we don't need to
-                continue
-            self.sync_var(v)
-            del self.reg_bindings[v]
-            self.free_regs.append(reg)
-        if op.result is not None:
-            self.reg_bindings[op.result] = eax
-            self.free_regs = [reg for reg in self.free_regs if reg is not eax]
+        self.rm.before_call(force_store)
         self.Perform(op, arglocs, eax)
+        self.rm.after_call(op.result)
 
     def consider_call(self, op, ignored):
         calldescr = op.descr
@@ -485,17 +481,17 @@
     def _malloc_varsize(self, ofs_items, ofs_length, scale, v, res_v):
         # XXX kill this function at some point
         if isinstance(v, Box):
-            loc = self.make_sure_var_in_reg(v, [v])
-            other_loc = self.force_allocate_reg(TempBox(), [v])
+            loc = self.rm.make_sure_var_in_reg(v, [v])
+            other_loc = self.rm.force_allocate_reg(TempBox(), [v])
             self.assembler.load_effective_addr(loc, ofs_items,scale, other_loc)
         else:
             other_loc = imm(ofs_items + (v.getint() << scale))
         self._call(ResOperation(rop.NEW, [v], res_v),
                    [other_loc], [v])
-        loc = self.make_sure_var_in_reg(v, [res_v])
+        loc = self.rm.make_sure_var_in_reg(v, [res_v])
         assert self.loc(res_v) == eax
         # now we have to reload length to some reasonable place
-        self.eventually_free_var(v)
+        self.rm.possibly_free_var(v)
         self.PerformDiscard(ResOperation(rop.SETFIELD_GC, [], None),
                             [eax, imm(ofs_length), imm(WORD), loc])
 
@@ -537,35 +533,35 @@
             need_lower_byte = True
         else:
             need_lower_byte = False
-        base_loc = self.make_sure_var_in_reg(op.args[0], op.args)
-        value_loc = self.make_sure_var_in_reg(op.args[1], op.args,
+        base_loc = self.rm.make_sure_var_in_reg(op.args[0], op.args)
+        value_loc = self.rm.make_sure_var_in_reg(op.args[1], op.args,
                                               need_lower_byte=need_lower_byte)
-        self.eventually_free_vars(op.args)
+        self.rm.possibly_free_vars(op.args)
         self.PerformDiscard(op, [base_loc, ofs_loc, size_loc, value_loc])
 
     consider_setfield_raw = consider_setfield_gc
 
     def consider_strsetitem(self, op, ignored):
-        base_loc = self.make_sure_var_in_reg(op.args[0], op.args)
-        ofs_loc = self.make_sure_var_in_reg(op.args[1], op.args)
-        value_loc = self.make_sure_var_in_reg(op.args[2], op.args,
-                                              need_lower_byte=True)
-        self.eventually_free_vars([op.args[0], op.args[1], op.args[2]])
+        base_loc = self.rm.make_sure_var_in_reg(op.args[0], op.args)
+        ofs_loc = self.rm.make_sure_var_in_reg(op.args[1], op.args)
+        value_loc = self.rm.make_sure_var_in_reg(op.args[2], op.args,
+                                                 need_lower_byte=True)
+        self.rm.possibly_free_vars(op.args)
         self.PerformDiscard(op, [base_loc, ofs_loc, value_loc])
 
     consider_unicodesetitem = consider_strsetitem
 
     def consider_setarrayitem_gc(self, op, ignored):
         scale, ofs, ptr = self._unpack_arraydescr(op.descr)
-        base_loc  = self.make_sure_var_in_reg(op.args[0], op.args)
+        base_loc  = self.rm.make_sure_var_in_reg(op.args[0], op.args)
         if scale == 0:
             need_lower_byte = True
         else:
             need_lower_byte = False
-        value_loc = self.make_sure_var_in_reg(op.args[2], op.args,
+        value_loc = self.rm.make_sure_var_in_reg(op.args[2], op.args,
                                               need_lower_byte=need_lower_byte)
-        ofs_loc = self.make_sure_var_in_reg(op.args[1], op.args)
-        self.eventually_free_vars(op.args)
+        ofs_loc = self.rm.make_sure_var_in_reg(op.args[1], op.args)
+        self.rm.possibly_free_vars(op.args)
         self.PerformDiscard(op, [base_loc, ofs_loc, value_loc,
                                  imm(scale), imm(ofs)])
 
@@ -573,19 +569,19 @@
 
     def consider_getfield_gc(self, op, ignored):
         ofs_loc, size_loc, _ = self._unpack_fielddescr(op.descr)
-        base_loc = self.make_sure_var_in_reg(op.args[0], op.args)
-        self.eventually_free_vars(op.args)
-        result_loc = self.force_allocate_reg(op.result, [])
+        base_loc = self.rm.make_sure_var_in_reg(op.args[0], op.args)
+        self.rm.possibly_free_vars(op.args)
+        result_loc = self.rm.force_allocate_reg(op.result)
         self.Perform(op, [base_loc, ofs_loc, size_loc], result_loc)
 
     consider_getfield_gc_pure = consider_getfield_gc
 
     def consider_getarrayitem_gc(self, op, ignored):
         scale, ofs, _ = self._unpack_arraydescr(op.descr)
-        base_loc = self.make_sure_var_in_reg(op.args[0], op.args)
-        ofs_loc = self.make_sure_var_in_reg(op.args[1], op.args)
-        self.eventually_free_vars(op.args)
-        result_loc = self.force_allocate_reg(op.result, [])
+        base_loc = self.rm.make_sure_var_in_reg(op.args[0], op.args)
+        ofs_loc = self.rm.make_sure_var_in_reg(op.args[1], op.args)
+        self.rm.possibly_free_vars(op.args)
+        result_loc = self.rm.force_allocate_reg(op.result)
         self.Perform(op, [base_loc, ofs_loc, imm(scale), imm(ofs)], result_loc)
 
     consider_getfield_raw = consider_getfield_gc
@@ -595,14 +591,13 @@
     def _consider_nullity(self, op, guard_op):
         # doesn't need a register in arg
         if guard_op is not None:
-            argloc = self.make_sure_var_in_reg(op.args[0], [])
-            self.eventually_free_var(op.args[0])
+            argloc = self.rm.make_sure_var_in_reg(op.args[0])
+            self.rm.possibly_free_var(op.args[0])
             self.perform_with_guard(op, guard_op, [argloc], None)
         else:
             argloc = self.loc(op.args[0])
-            self.eventually_free_var(op.args[0])
-            resloc = self.force_allocate_reg(op.result, [],
-                                             need_lower_byte=True)
+            self.rm.possibly_free_var(op.args[0])
+            resloc = self.rm.force_allocate_reg(op.result, need_lower_byte=True)
             self.Perform(op, [argloc], resloc)
 
     consider_int_is_true = _consider_nullity
@@ -611,15 +606,15 @@
 
     def consider_same_as(self, op, ignored):
         argloc = self.loc(op.args[0])
-        self.eventually_free_var(op.args[0])
-        resloc = self.force_allocate_reg(op.result, [])
+        self.rm.possibly_free_var(op.args[0])
+        resloc = self.rm.force_allocate_reg(op.result)
         self.Perform(op, [argloc], resloc)
     consider_cast_ptr_to_int = consider_same_as
 
     def consider_strlen(self, op, ignored):
-        base_loc = self.make_sure_var_in_reg(op.args[0], op.args)
-        self.eventually_free_vars(op.args)
-        result_loc = self.force_allocate_reg(op.result, [])
+        base_loc = self.rm.make_sure_var_in_reg(op.args[0], op.args)
+        self.rm.possibly_free_vars(op.args)
+        result_loc = self.rm.force_allocate_reg(op.result)
         self.Perform(op, [base_loc], result_loc)
 
     consider_unicodelen = consider_strlen
@@ -628,16 +623,16 @@
         arraydescr = op.descr
         assert isinstance(arraydescr, BaseArrayDescr)
         ofs = arraydescr.get_ofs_length(self.translate_support_code)
-        base_loc = self.make_sure_var_in_reg(op.args[0], op.args)
-        self.eventually_free_vars(op.args)
-        result_loc = self.force_allocate_reg(op.result, [])
+        base_loc = self.rm.make_sure_var_in_reg(op.args[0], op.args)
+        self.rm.possibly_free_vars(op.args)
+        result_loc = self.rm.force_allocate_reg(op.result, [])
         self.Perform(op, [base_loc, imm(ofs)], result_loc)
 
     def consider_strgetitem(self, op, ignored):
-        base_loc = self.make_sure_var_in_reg(op.args[0], op.args)
-        ofs_loc = self.make_sure_var_in_reg(op.args[1], op.args)
-        self.eventually_free_vars([op.args[0], op.args[1]])
-        result_loc = self.force_allocate_reg(op.result, [])
+        base_loc = self.rm.make_sure_var_in_reg(op.args[0], op.args)
+        ofs_loc = self.rm.make_sure_var_in_reg(op.args[1], op.args)
+        self.rm.possibly_free_vars(op.args)
+        result_loc = self.rm.force_allocate_reg(op.result)
         self.Perform(op, [base_loc, ofs_loc], result_loc)
 
     consider_unicodegetitem = consider_strgetitem



More information about the Pypy-commit mailing list