[pypy-svn] r63066 - in pypy/branch/pyjitpl5/pypy/jit/backend/x86: . test

arigo at codespeak.net arigo at codespeak.net
Thu Mar 19 13:06:14 CET 2009


Author: arigo
Date: Thu Mar 19 13:06:12 2009
New Revision: 63066

Modified:
   pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py
   pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py
   pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py
Log:
Get rid of these intermediate classes Load, Store, Perform, etc.
It's easy enough that I wonder why they have been introduced in
the first place.


Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py	Thu Mar 19 13:06:12 2009
@@ -9,8 +9,7 @@
 from pypy.annotation import model as annmodel
 from pypy.tool.uid import fixid
 from pypy.jit.backend.x86.regalloc import (RegAlloc, FRAMESIZE, WORD, REGS,
-                                      arg_pos, lower_byte, stack_pos, Perform,
-                                      RETURN)
+                                      arg_pos, lower_byte, stack_pos, RETURN)
 from pypy.rlib.objectmodel import we_are_translated, specialize
 from pypy.jit.backend.x86 import codebuf
 from pypy.jit.backend.x86.support import gc_malloc_fnaddr
@@ -43,7 +42,6 @@
 class Assembler386(object):
     MC_SIZE = 1024*1024     # 1MB, but assumed infinite for now
     generic_return_addr = 0
-    position = -1
     log_fd = -1
 
     def __init__(self, cpu, translate_support_code=False):
@@ -149,10 +147,10 @@
         op0 = operations[0]
         op0.position = self.mc.tell()
         self.eventually_log_operations(operations, guard_op)
-        regalloc = RegAlloc(operations, guard_op, self.cpu.translate_support_code)
+        regalloc = RegAlloc(self, operations, guard_op,
+                            self.cpu.translate_support_code)
         if not we_are_translated():
             self._regalloc = regalloc # for debugging
-        computed_ops = regalloc.computed_ops
         if guard_op is not None:
             new_rel_addr = self.mc.tell() - guard_op._jmp_from
             TP = rffi.CArrayPtr(lltype.Signed)
@@ -164,29 +162,9 @@
             print
             pprint.pprint(operations)
             print
-            pprint.pprint(computed_ops)
-            print
-        for i in range(len(computed_ops)):
-            op = computed_ops[i]
-            if not we_are_translated():
-                self.dump_op(op)
-            self.position = i
-            # XXX eventually change to numbers or kill
-            #     alltogether
-            if op.opname == 'load':
-                self.regalloc_load(op)
-            elif op.opname == 'store':
-                self.regalloc_store(op)
-            elif op.opname == 'perform_discard':
-                self.regalloc_perform_discard(op)
-            elif op.opname == 'perform':
-                self.regalloc_perform(op)
-            elif op.opname == 'perform_with_guard':
-                self.regalloc_perform_with_guard(op)
-            else:
-                raise NotImplementedError(op.opname)
-        if not we_are_translated():
-            self.dump_op('')
+            #pprint.pprint(computed_ops)
+            #print
+        regalloc.walk_operations(operations)
         self.mc.done()
         self.mc2.done()
 
@@ -208,13 +186,13 @@
         self.mc.done()
         return addr
 
-    def dump_op(self, op):
+    def dump(self, text):
         if not self.verbose:
             return
         _prev = Box._extended_display
         try:
             Box._extended_display = False
-            print >> sys.stderr, ' 0x%x  %s' % (fixid(self.mc.tell()), op)
+            print >> sys.stderr, ' 0x%x  %s' % (fixid(self.mc.tell()), text)
         finally:
             Box._extended_display = _prev
 
@@ -242,42 +220,19 @@
         self.mc.done()
         return addr
 
-    def copy_var_if_used(self, v, to_v):
-        """ Gives new loc
-        """
-        loc = self.loc(v)
-        if isinstance(loc, REG):
-            if self.regalloc.used(v) > self.regalloc.position:
-                newloc = self.regalloc.allocate_loc(v)
-                self.regalloc.move(loc, newloc)
-            self.regalloc.force_loc(to_v, loc)
-        else:
-            newloc = self.regalloc.allocate_loc(to_v, force_reg=True)
-            self.mc.MOV(newloc, loc)
-            loc = newloc
-        return loc
-            
-    def next_stack_position(self):
-        position = self.current_stack_depth
-        self.current_stack_depth += 1
-        return position
-
-    def regalloc_load(self, op):
-        self.mc.MOV(op.to_loc, op.from_loc)
+    def regalloc_load(self, from_loc, to_loc):
+        self.mc.MOV(to_loc, from_loc)
 
     regalloc_store = regalloc_load
 
-    def regalloc_perform(self, op):
-        assert isinstance(op, Perform)
-        resloc = op.result_loc
-        genop_list[op.op.opnum](self, op.op, op.arglocs, resloc)
-
-    def regalloc_perform_discard(self, op):
-        genop_discard_list[op.op.opnum](self, op.op, op.arglocs)
-
-    def regalloc_perform_with_guard(self, op):
-        genop_guard_list[op.op.opnum](self, op.op, op.guard_op, op.arglocs,
-                                      op.result_loc)
+    def regalloc_perform(self, op, arglocs, resloc):
+        genop_list[op.opnum](self, op, arglocs, resloc)
+
+    def regalloc_perform_discard(self, op, arglocs):
+        genop_discard_list[op.opnum](self, op, arglocs)
+
+    def regalloc_perform_with_guard(self, op, guard_op, arglocs, resloc):
+        genop_guard_list[op.opnum](self, op, guard_op, arglocs, resloc)
 
     def _unaryop(asmop):
         def genop_unary(self, op, arglocs, resloc):

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py	Thu Mar 19 13:06:12 2009
@@ -1,5 +1,5 @@
 
-""" Register allocation scheme. The idea is as follows:
+""" Register allocation scheme.
 """
 
 from pypy.jit.metainterp.history import (Box, Const, ConstInt, ConstPtr,
@@ -26,58 +26,6 @@
     def __repr__(self):
         return "<TempVar at %s>" % (id(self),)
 
-class PseudoOperation(object):
-    def __init__(self, v, from_loc, to_loc):
-        self.from_loc = from_loc
-        self.to_loc = to_loc
-        self.v = v
-
-# pseudo operations for loading/saving reg/mem
-class Load(PseudoOperation):
-    opname = 'load'
-
-    def __repr__(self):
-        return '%s <- %s(%s)' % (self.to_loc, self.v, self.from_loc)
-
-class Store(PseudoOperation):
-    opname = 'store'
-
-    def __repr__(self):
-        return '%s(%s) -> %s' % (self.v, self.from_loc, self.to_loc)
-
-class Perform(PseudoOperation):
-    opname = 'perform'
-
-    def __init__(self, op, arglocs, result_loc):
-        self.op = op
-        self.result_loc = result_loc
-        self.arglocs = arglocs
-
-    def __repr__(self):
-        return '%s <- %s(%s)' % (self.result_loc, self.op, self.arglocs)
-
-class PerformWithGuard(PseudoOperation):
-    opname = 'perform_with_guard'
-
-    def __init__(self, op, guard_op, arglocs, result_loc):
-        self.op = op
-        self.guard_op = guard_op
-        self.result_loc = result_loc
-        self.arglocs = arglocs
-
-    def __repr__(self):
-        return '%s <- %s(%s) [GUARDED]' % (self.result_loc, self.op, self.arglocs)
-
-class PerformDiscard(PseudoOperation):
-    opname = 'perform_discard'
-
-    def __init__(self, op, arglocs):
-        self.op = op
-        self.arglocs = arglocs
-
-    def __repr__(self):
-        return '%s(%s)' % (self.op, self.arglocs)
-
 class checkdict(dict):
     def __setitem__(self, key, value):
         assert isinstance(key, Box)
@@ -99,8 +47,10 @@
         raise ValueError("convert_to_imm: got a %s" % c)
 
 class RegAlloc(object):
-    def __init__(self, operations, guard_op=None, translate_support_code=False):
+    def __init__(self, assembler, operations, guard_op=None,
+                 translate_support_code=False):
         # variables that have place in register
+        self.assembler = assembler
         self.translate_support_code = translate_support_code
         self.reg_bindings = newcheckdict()
         self.stack_bindings = {}
@@ -116,9 +66,8 @@
             loop_consts, sd = self._start_from_guard_op(guard_op, mp, jump)
         else:
             loop_consts, sd = self._compute_loop_consts(mp, jump)
+        self.loop_consts = loop_consts
         self.current_stack_depth = sd
-        self.computed_ops = self.walk_operations(operations, loop_consts)
-        assert not self.reg_bindings
 
     def _start_from_guard_op(self, guard_op, mp, jump):
         rev_stack_binds = {}
@@ -206,6 +155,33 @@
                     self.longevity[v][0] <= self.position):
                     assert not v in self.dirty_stack
 
+    def Load(self, v, from_loc, to_loc):
+        if not we_are_translated():
+            self.assembler.dump('%s <- %s(%s)' % (to_loc, v, from_loc))
+        self.assembler.regalloc_load(from_loc, to_loc)
+
+    def Store(self, v, from_loc, to_loc):
+        if not we_are_translated():
+            self.assembler.dump('%s(%s) -> %s' % (v, from_loc, to_loc))
+        self.assembler.regalloc_store(from_loc, to_loc)
+
+    def Perform(self, op, arglocs, result_loc):
+        if not we_are_translated():
+            self.assembler.dump('%s <- %s(%s)' % (result_loc, op, arglocs))
+        self.assembler.regalloc_perform(op, arglocs, result_loc)
+
+    def PerformWithGuard(self, op, guard_op, arglocs, result_loc):
+        if not we_are_translated():
+            self.assembler.dump('%s <- %s(%s) [GUARDED]' % (result_loc, op,
+                                                            arglocs))
+        self.assembler.regalloc_perform_with_guard(op, guard_op, arglocs,
+                                                   result_loc)
+
+    def PerformDiscard(self, op, arglocs):
+        if not we_are_translated():
+            self.assembler.dump('%s(%s)' % (op, arglocs))
+        self.assembler.regalloc_perform_discard(op, arglocs)
+
     def can_optimize_cmp_op(self, op, i, operations):
         if not op.is_comparison():
             return False
@@ -218,11 +194,9 @@
             return False
         return True
 
-    def walk_operations(self, operations, loop_consts):
+    def walk_operations(self, operations):
         # first pass - walk along the operations in order to find
         # load/store places
-        new_ops = []
-        self.loop_consts = loop_consts
         i = 0
         while i < len(operations):
             op = operations[i]
@@ -235,19 +209,20 @@
                 # detect overflow ops
                 if op.is_ovf():
                     assert operations[i + 1].opnum == rop.GUARD_NO_EXCEPTION
-                    new_ops += oplist[op.opnum](self, op, operations[i + 1])
+                    nothing = oplist[op.opnum](self, op, operations[i + 1])
                     i += 1
                 elif self.can_optimize_cmp_op(op, i, operations):
-                    new_ops += oplist[op.opnum](self, op, operations[i + 1])
+                    nothing = oplist[op.opnum](self, op, operations[i + 1])
                     i += 1
                 else:
-                    new_ops += oplist[op.opnum](self, op, None)
+                    nothing = oplist[op.opnum](self, op, None)
+                assert nothing is None     # temporary, remove me
                 self.eventually_free_var(op.result)
                 self._check_invariants()
             else:
                 self.eventually_free_vars(op.args)
             i += 1
-        return new_ops
+        assert not self.reg_bindings
 
     def _compute_vars_longevity(self, operations):
         # compute a dictionary that maps variables to index in
@@ -314,10 +289,12 @@
         if selected_reg or not imm_fine:
             # this means we cannot have it in IMM, eh
             if selected_reg in self.free_regs:
-                return selected_reg, [Load(v, convert_to_imm(v), selected_reg)]
+                self.Load(v, convert_to_imm(v), selected_reg)
+                return selected_reg
             if selected_reg is None and self.free_regs:
                 loc = self.free_regs.pop()
-                return loc, [Load(v, convert_to_imm(v), loc)]
+                self.Load(v, convert_to_imm(v), loc)
+                return loc
             v_to_spill = self.pick_variable_to_spill(v, forbidden_vars, selected_reg)
             loc = self.loc(v_to_spill)
             if v_to_spill not in self.stack_bindings or v_to_spill in self.dirty_stack:
@@ -326,13 +303,12 @@
                     del self.dirty_stack[v_to_spill]
                 except KeyError:
                     pass
-                ops = [Store(v_to_spill, loc, newloc)]
-            else:
-                ops = []
+                self.Store(v_to_spill, loc, newloc)
             del self.reg_bindings[v_to_spill]
             self.free_regs.append(loc)
-            return loc, ops+[Load(v, convert_to_imm(v), loc)]
-        return convert_to_imm(v), []
+            self.Load(v, convert_to_imm(v), loc)
+            return loc
+        return convert_to_imm(v)
 
     def force_allocate_reg(self, v, forbidden_vars, selected_reg=None):
         if isinstance(v, Const):
@@ -341,7 +317,7 @@
             self.longevity[v] = (self.position, self.position)
         loc = self.try_allocate_reg(v, selected_reg)
         if loc:
-            return loc, []
+            return loc
         return self._spill_var(v, forbidden_vars, selected_reg)
 
     def _spill_var(self, v, forbidden_vars, selected_reg):
@@ -355,8 +331,8 @@
                 del self.dirty_stack[v_to_spill]
             except KeyError:
                 pass
-            return loc, [Store(v_to_spill, loc, newloc)]
-        return loc, []
+            self.Store(v_to_spill, loc, newloc)
+        return loc
 
     def _locs_from_liveboxes(self, guard_op):
         stacklocs = []
@@ -391,10 +367,10 @@
             return self.return_constant(v, forbidden_vars, selected_reg,
                                         imm_fine)
         prev_loc = self.loc(v)
-        loc, ops = self.force_allocate_reg(v, forbidden_vars, selected_reg)
-        if prev_loc is loc:
-            return loc, ops
-        return loc, ops + [Load(v, prev_loc, loc)]
+        loc = self.force_allocate_reg(v, forbidden_vars, selected_reg)
+        if prev_loc is not loc:
+            self.Load(v, prev_loc, loc)
+        return loc
 
     def reallocate_from_to(self, from_v, to_v):
         reg = self.reg_bindings[from_v]
@@ -441,7 +417,7 @@
             del self.dirty_stack[v]
         except KeyError:
             pass
-        return Store(v, prev_loc, loc)
+        self.Store(v, prev_loc, loc)
 
     def force_result_in_reg(self, result_v, v, forbidden_vars,
                             selected_reg=None):
@@ -449,22 +425,20 @@
         and v is copied away if it's further used
         """
         if isinstance(v, Const):
-            loc, ops = self.make_sure_var_in_reg(v, forbidden_vars,
-                                                 selected_reg,
-                                                 imm_fine=False)
+            loc = self.make_sure_var_in_reg(v, forbidden_vars,
+                                            selected_reg,
+                                            imm_fine=False)
             assert not isinstance(loc, IMM8)
             self.reg_bindings[result_v] = loc
             self.free_regs = [reg for reg in self.free_regs if reg is not loc]
-            return loc, ops
-        ops = []
+            return loc
         if v in self.reg_bindings and selected_reg:
-            _, ops = self.make_sure_var_in_reg(v, forbidden_vars, selected_reg)
+            self.make_sure_var_in_reg(v, forbidden_vars, selected_reg)
         elif v not in self.reg_bindings:
             assert v not in self.dirty_stack
             prev_loc = self.stack_bindings[v]
-            loc, o = self.force_allocate_reg(v, forbidden_vars, selected_reg)
-            ops += o
-            ops.append(Load(v, prev_loc, loc))
+            loc = self.force_allocate_reg(v, forbidden_vars, selected_reg)
+            self.Load(v, prev_loc, loc)
         assert v in self.reg_bindings
         if self.longevity[v][1] > self.position:
             # we need to find a new place for variable x and
@@ -472,18 +446,17 @@
             loc = self.reg_bindings[v]
             del self.reg_bindings[v]
             if v not in self.stack_bindings or v in self.dirty_stack:
-                ops.append(self.move_variable_away(v, loc))
+                self.move_variable_away(v, loc)
             self.reg_bindings[result_v] = loc
         else:
             self.reallocate_from_to(v, result_v)
             loc = self.reg_bindings[result_v]
-        return loc, ops
+        return loc
 
     def consider_merge_point(self, op, ignored):
         # XXX we can sort out here by longevity if we need something
         # more optimal
 
-        ops = [PerformDiscard(op, [])]
         locs = [None] * len(op.args)
         for i in range(len(op.args)):
             arg = op.args[i]
@@ -502,11 +475,10 @@
                 locs[i] = loc
             # otherwise we have it saved on stack, so no worry
         op.arglocs = locs
-        ops[-1].arglocs = op.arglocs
-        op.stacklocs = [i for i in range(len(op.args))]
+        op.stacklocs = range(len(op.args))
+        self.PerformDiscard(op, locs)
         # XXX be a bit smarter and completely ignore such vars
         self.eventually_free_vars(op.args)
-        return ops
 
     def consider_catch(self, op, ignored):
         locs = []
@@ -519,14 +491,14 @@
         op.arglocs = locs
         op.stacklocs = [self.stack_loc(arg).position for arg in op.args]
         self.eventually_free_vars(op.args)
-        return [PerformDiscard(op, [])]
+        self.PerformDiscard(op, [])
 
     def _consider_guard(self, op, ignored):
-        loc, ops = self.make_sure_var_in_reg(op.args[0], [])
+        loc = self.make_sure_var_in_reg(op.args[0], [])
         locs = self._locs_from_liveboxes(op)
         self.eventually_free_var(op.args[0])
         self.eventually_free_vars(op.liveboxes)
-        return ops + [PerformDiscard(op, [loc] + locs)]
+        self.PerformDiscard(op, [loc] + locs)
 
     consider_guard_true = _consider_guard
     consider_guard_false = _consider_guard
@@ -536,31 +508,30 @@
         locs = self._locs_from_liveboxes(op)
         self.eventually_free_var(op.args[0])
         self.eventually_free_vars(op.liveboxes)
-        return []
 
     def consider_guard_no_exception(self, op, ignored):
         box = TempBox()
-        loc, ops = self.force_allocate_reg(box, [])
+        loc = self.force_allocate_reg(box, [])
         locs = self._locs_from_liveboxes(op)
         self.eventually_free_vars(op.liveboxes)
         self.eventually_free_var(box)
-        return ops + [PerformDiscard(op, [loc] + locs)]
+        self.PerformDiscard(op, [loc] + locs)
 
     def consider_guard_exception(self, op, ignored):
-        loc, ops = self.make_sure_var_in_reg(op.args[0], [])
+        loc = self.make_sure_var_in_reg(op.args[0], [])
         box = TempBox()
-        loc1, ops1 = self.force_allocate_reg(box, op.args)
+        loc1 = self.force_allocate_reg(box, op.args)
         if op.result in self.longevity:
             # this means, is it ever used
-            resloc, ops2 = self.force_allocate_reg(op.result,
+            resloc = self.force_allocate_reg(op.result,
                                                    op.args + [box])
         else:
-            resloc, ops2 = None, []
+            resloc = None
         locs = self._locs_from_liveboxes(op)
         self.eventually_free_vars(op.liveboxes)
         self.eventually_free_vars(op.args)
         self.eventually_free_var(box)
-        return ops + ops1 + ops2 + [Perform(op, [loc, loc1] + locs, resloc)]
+        self.Perform(op, [loc, loc1] + locs, resloc)
 
     #def consider_guard2(self, op, ignored):
     #    loc1, ops1 = self.make_sure_var_in_reg(op.args[0], [])
@@ -581,20 +552,18 @@
     def consider_guard_value(self, op, ignored):
         x = self.loc(op.args[0])
         if not (isinstance(x, REG) or isinstance(op.args[1], Const)):
-            x, ops = self.make_sure_var_in_reg(op.args[0], [], imm_fine=False)
-        else:
-            ops = []
+            x = self.make_sure_var_in_reg(op.args[0], [], imm_fine=False)
         y = self.loc(op.args[1])
         locs = self._locs_from_liveboxes(op)
         self.eventually_free_vars(op.liveboxes + op.args)
-        return ops + [PerformDiscard(op, [x, y] + locs)]
+        self.PerformDiscard(op, [x, y] + locs)
 
     def consider_guard_class(self, op, ignored):
-        x, ops = self.make_sure_var_in_reg(op.args[0], [], imm_fine=False)
+        x = self.make_sure_var_in_reg(op.args[0], [], imm_fine=False)
         y = self.loc(op.args[1])
         locs = self._locs_from_liveboxes(op)
         self.eventually_free_vars(op.liveboxes + op.args)
-        return ops + [PerformDiscard(op, [x, y] + locs)]
+        self.PerformDiscard(op, [x, y] + locs)
 
     def consider_return(self, op, ignored):
         if op.args:
@@ -602,25 +571,24 @@
             self.eventually_free_var(op.args[0])
         else:
             arglocs = []
-        return [PerformDiscard(op, arglocs)]
+        self.PerformDiscard(op, arglocs)
     
     def _consider_binop_part(self, op, ignored):
         x = op.args[0]
-        ops = []
         if isinstance(x, Const):
-            res, ops = self.force_allocate_reg(op.result, [])
+            res = self.force_allocate_reg(op.result, [])
             argloc = self.loc(op.args[1])
             self.eventually_free_var(op.args[1])
-            load_op = Load(x, self.loc(x), res)
-            return res, argloc, ops + [load_op]
-        loc, ops = self.force_result_in_reg(op.result, x, op.args)
+            self.Load(x, self.loc(x), res)
+            return res, argloc
+        loc = self.force_result_in_reg(op.result, x, op.args)
         argloc = self.loc(op.args[1])
         self.eventually_free_var(op.args[1])
-        return loc, argloc, ops
+        return loc, argloc
 
     def _consider_binop(self, op, ignored):
-        loc, argloc, ops = self._consider_binop_part(op, ignored)
-        return ops + [Perform(op, [loc, argloc], loc)]
+        loc, argloc = self._consider_binop_part(op, ignored)
+        self.Perform(op, [loc, argloc], loc)
 
     consider_int_add = _consider_binop
     consider_int_mul = _consider_binop
@@ -634,12 +602,12 @@
     #consider_uint_and = _consider_binop
     
     def _consider_binop_ovf(self, op, guard_op):
-        loc, argloc, ops = self._consider_binop_part(op, None)
+        loc, argloc = self._consider_binop_part(op, None)
         locs = self._locs_from_liveboxes(guard_op)
         self.position += 1
         self.eventually_free_vars(guard_op.liveboxes)
         self.eventually_free_var(guard_op.result)
-        return ops + [PerformWithGuard(op, guard_op, [loc, argloc] + locs, loc)]
+        self.PerformWithGuard(op, guard_op, [loc, argloc] + locs, loc)
 
     consider_int_mul_ovf = _consider_binop_ovf
     consider_int_sub_ovf = _consider_binop_ovf
@@ -647,54 +615,53 @@
     # XXX ovf_neg op
 
     def consider_int_neg(self, op, ignored):
-        res, ops = self.force_result_in_reg(op.result, op.args[0], [])
-        return ops + [Perform(op, [res], res)]
+        res = self.force_result_in_reg(op.result, op.args[0], [])
+        self.Perform(op, [res], res)
 
     consider_bool_not = consider_int_neg
 
     def consider_int_rshift(self, op, ignored):
         tmpvar = TempBox()
-        reg, ops = self.force_allocate_reg(tmpvar, [], ecx)
+        reg = self.force_allocate_reg(tmpvar, [], ecx)
         y = self.loc(op.args[1])
-        x, more_ops = self.force_result_in_reg(op.result, op.args[0],
-                                               op.args + [tmpvar])
+        x = self.force_result_in_reg(op.result, op.args[0],
+                                     op.args + [tmpvar])
         self.eventually_free_vars(op.args + [tmpvar])
-        return ops + more_ops + [Perform(op, [x, y, reg], x)]
+        self.Perform(op, [x, y, reg], x)
 
     def consider_int_mod(self, op, ignored):
-        l0, ops0 = self.make_sure_var_in_reg(op.args[0], [], eax)
-        l1, ops1 = self.make_sure_var_in_reg(op.args[1], [], ecx)
-        l2, ops2 = self.force_allocate_reg(op.result, [], edx)
+        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, [], edx)
         # eax is trashed after that operation
         tmpvar = TempBox()
-        _, ops3 = self.force_allocate_reg(tmpvar, [], eax)
+        self.force_allocate_reg(tmpvar, [], eax)
         assert (l0, l1, l2) == (eax, ecx, edx)
         self.eventually_free_vars(op.args + [tmpvar])
-        return ops0 + ops1 + ops2 + ops3 + [Perform(op, [eax, ecx], edx)]
+        self.Perform(op, [eax, ecx], edx)
 
     def consider_int_mod_ovf(self, op, guard_op):
-        l0, ops0 = self.make_sure_var_in_reg(op.args[0], [], eax)
-        l1, ops1 = self.make_sure_var_in_reg(op.args[1], [], ecx)
-        l2, ops2 = self.force_allocate_reg(op.result, [], edx)
+        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, [], edx)
         tmpvar = TempBox()
-        _, ops3 = self.force_allocate_reg(tmpvar, [], eax)
+        self.force_allocate_reg(tmpvar, [], eax)
         assert (l0, l1, l2) == (eax, ecx, edx)
         locs = self._locs_from_liveboxes(guard_op)
         self.eventually_free_vars(op.args + [tmpvar])
         self.position += 1
         self.eventually_free_vars(guard_op.liveboxes)
-        return (ops0 + ops1 + ops2 + ops3 +
-                [PerformWithGuard(op, guard_op, [eax, ecx] + locs, edx)])
+        self.PerformWithGuard(op, guard_op, [eax, ecx] + locs, edx)
 
     def consider_int_floordiv(self, op, ignored):
         tmpvar = TempBox()
-        l0, ops0 = self.force_result_in_reg(op.result, op.args[0], [], eax)
-        l1, ops1 = self.make_sure_var_in_reg(op.args[1], [], ecx)
+        l0 = self.force_result_in_reg(op.result, op.args[0], [], eax)
+        l1 = self.make_sure_var_in_reg(op.args[1], [], ecx)
         # we need to make sure edx is empty, since we're going to use it
-        l2, ops2 = self.force_allocate_reg(tmpvar, [], edx)
+        l2 = self.force_allocate_reg(tmpvar, [], edx)
         assert (l0, l1, l2) == (eax, ecx, edx)
         self.eventually_free_vars(op.args + [tmpvar])
-        return ops0 + ops1 + ops2 + [Perform(op, [eax, ecx], eax)]
+        self.Perform(op, [eax, ecx], eax)
 
     def _consider_compop(self, op, guard_op):
         vx = op.args[0]
@@ -702,20 +669,20 @@
         arglocs = [self.loc(vx), self.loc(vy)]
         if (vx in self.reg_bindings or vy in self.reg_bindings or
             isinstance(vx, Const) or isinstance(vy, Const)):
-            ops0 = []
+            pass
         else:
-            arglocs[0], ops0 = self.make_sure_var_in_reg(vx, [])
+            arglocs[0] = self.make_sure_var_in_reg(vx, [])
         self.eventually_free_var(vx)
         self.eventually_free_var(vy)
         if guard_op is None:
-            loc, ops = self.force_allocate_reg(op.result, op.args)
-            return ops0 + ops + [Perform(op, arglocs, loc)]
+            loc = self.force_allocate_reg(op.result, op.args)
+            self.Perform(op, arglocs, loc)
         else:
             locs = self._locs_from_liveboxes(guard_op)
             self.position += 1
             self.eventually_free_var(op.result)
             self.eventually_free_vars(guard_op.liveboxes)
-            return ops0 + [PerformWithGuard(op, guard_op, arglocs + locs, None)]
+            self.PerformWithGuard(op, guard_op, arglocs + locs, None)
 
     consider_int_lt = _consider_compop
     consider_int_gt = _consider_compop
@@ -730,36 +697,31 @@
     consider_uint_ge = _consider_compop
 
     def sync_var(self, v):
-        ops = []
         if v in self.dirty_stack or v not in self.stack_bindings:
             reg = self.reg_bindings[v]
-            ops.append(Store(v, reg, self.stack_loc(v)))
+            self.Store(v, reg, self.stack_loc(v))
             try:
                 del self.dirty_stack[v]
             except KeyError:
                 pass
         # otherwise it's clean
-        return ops
 
     def sync_var_if_survives(self, v):
         if self.longevity[v][1] > self.position:
-            return self.sync_var(v)
-        return []
+            self.sync_var(v)
 
     def _call(self, op, arglocs, force_store=[]):
-        ops = []
         # we need to store all variables which are now in registers
         for v, reg in self.reg_bindings.items():
             if self.longevity[v][1] > self.position or v in force_store:
-                ops += self.sync_var(v)
+                self.sync_var(v)
         self.reg_bindings = newcheckdict()
         if op.result is not None:
             self.reg_bindings[op.result] = eax
             self.free_regs = [reg for reg in REGS if reg is not eax]
-            return ops + [Perform(op, arglocs, eax)]
         else:
             self.free_regs = REGS[:]
-            return ops + [Perform(op, arglocs, eax)]
+        self.Perform(op, arglocs, eax)
 
     def consider_call(self, op, ignored):
         from pypy.jit.backend.x86.runner import CPU386
@@ -784,41 +746,30 @@
 
     def _malloc_varsize(self, ofs, ofs_items, ofs_length, size, v, res_v):
         if isinstance(v, Box):
-            loc, ops0 = self.make_sure_var_in_reg(v, [v])
-            ops0 += self.sync_var(v)
+            loc = self.make_sure_var_in_reg(v, [v])
+            self.sync_var(v)
             if size != 0:
                 # XXX lshift?
-                ops0.append(Perform(ResOperation(rop.INT_MUL, [], None),
-                                [loc, imm(1 << size)], loc))
-            ops0.append(Perform(ResOperation(rop.INT_ADD, [], None),
-                                [loc, imm(ofs + ofs_items)], loc))
+                self.Perform(ResOperation(rop.INT_MUL, [], None),
+                             [loc, imm(1 << size)], loc)
+            self.Perform(ResOperation(rop.INT_ADD, [], None),
+                         [loc, imm(ofs + ofs_items)], loc)
         else:
-            ops0 = []
             loc = imm(ofs + ofs_items + (v.getint() << size))
-        ops = self._call(ResOperation(rop.NEW, [v], res_v)
-                         , [loc], [v])
-        loc, ops1 = self.make_sure_var_in_reg(v, [res_v])
+        self._call(ResOperation(rop.NEW, [v], res_v),
+                   [loc], [v])
+        loc = self.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)
-        res = (ops0 + ops + ops1 +
-               [PerformDiscard(ResOperation(rop.SETFIELD_GC, [], None),
-                               [eax, imm(ofs + ofs_length), imm(WORD), loc])])
-        return res
+        self.PerformDiscard(ResOperation(rop.SETFIELD_GC, [], None),
+                            [eax, imm(ofs + ofs_length), imm(WORD), loc])
 
     def consider_new_array(self, op, ignored):
         size_of_field, basesize, _ = self._unpack_arraydescr(op.descr)
         return self._malloc_varsize(0, basesize, 0, size_of_field, op.args[0],
                                     op.result)
 
-    def consider_oononnull(self, op, ignored):
-        XXX   # "consider_oononnull = _consider_nullity" below
-        argloc = self.loc(op.args[0])
-        self.eventually_free_var(op.args[0])
-        reg = self.try_allocate_reg(op.result)
-        assert reg
-        return [Perform(op, [argloc], reg)]
-
     def _unpack_arraydescr(self, arraydescr):
         from pypy.jit.backend.x86.runner import CPU386
         return CPU386.unpack_arraydescr(arraydescr)
@@ -829,50 +780,44 @@
         return imm(ofs), imm(size)
 
     def consider_setfield_gc(self, op, ignored):
-        base_loc, ops0  = self.make_sure_var_in_reg(op.args[0], op.args)
+        base_loc = self.make_sure_var_in_reg(op.args[0], op.args)
         ofs_loc, size_loc = self._unpack_fielddescr(op.descr)
-        value_loc, ops2 = self.make_sure_var_in_reg(op.args[1], op.args)
+        value_loc = self.make_sure_var_in_reg(op.args[1], op.args)
         self.eventually_free_vars(op.args)
-        return (ops0 + ops2 +
-                [PerformDiscard(op, [base_loc, ofs_loc, size_loc, value_loc])])
+        self.PerformDiscard(op, [base_loc, ofs_loc, size_loc, value_loc])
 
     def consider_strsetitem(self, op, ignored):
-        base_loc, ops0  = self.make_sure_var_in_reg(op.args[0], op.args)
-        ofs_loc, ops1 = self.make_sure_var_in_reg(op.args[1], op.args)
-        value_loc, ops2 = self.make_sure_var_in_reg(op.args[2], op.args)
+        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)
         self.eventually_free_vars([op.args[0], op.args[1], op.args[2]])
-        return (ops0 + ops1 + ops2 +
-                [PerformDiscard(op, [base_loc, ofs_loc, value_loc])])
+        self.PerformDiscard(op, [base_loc, ofs_loc, value_loc])
 
     def consider_setarrayitem_gc(self, op, ignored):
         scale, ofs, _ = self._unpack_arraydescr(op.descr)
-        base_loc, ops0  = self.make_sure_var_in_reg(op.args[0], op.args)
-        ofs_loc, ops1 = self.make_sure_var_in_reg(op.args[1], op.args)
-        value_loc, ops2 = self.make_sure_var_in_reg(op.args[2], op.args)
+        base_loc  = self.make_sure_var_in_reg(op.args[0], op.args)
+        value_loc = self.make_sure_var_in_reg(op.args[2], op.args)
+        ofs_loc = self.make_sure_var_in_reg(op.args[1], op.args)
         self.eventually_free_vars(op.args)
-        return (ops0 + ops2 + ops1 +
-                [PerformDiscard(op, [base_loc, ofs_loc, value_loc,
-                                     imm(scale), imm(ofs)])])
+        self.PerformDiscard(op, [base_loc, ofs_loc, value_loc,
+                                 imm(scale), imm(ofs)])
 
     def consider_getfield_gc(self, op, ignored):
         ofs_loc, size_loc = self._unpack_fielddescr(op.descr)
-        base_loc, ops0 = self.make_sure_var_in_reg(op.args[0], op.args)
+        base_loc = self.make_sure_var_in_reg(op.args[0], op.args)
         self.eventually_free_vars(op.args)
-        result_loc, more_ops = self.force_allocate_reg(op.result, [])
-        return (ops0 + more_ops +
-                [Perform(op, [base_loc, ofs_loc, size_loc], result_loc)])
+        result_loc = self.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, ops0  = self.make_sure_var_in_reg(op.args[0], op.args)
-        ofs_loc, ops1 = self.make_sure_var_in_reg(op.args[1], op.args)
+        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, more_ops = self.force_allocate_reg(op.result, [])
-        return (ops0 + ops1 + more_ops +
-                [Perform(op, [base_loc, ofs_loc, imm(scale), imm(ofs)],
-                         result_loc)])
+        result_loc = self.force_allocate_reg(op.result, [])
+        self.Perform(op, [base_loc, ofs_loc, imm(scale), imm(ofs)], result_loc)
 
     consider_getfield_raw = consider_getfield_gc
     consider_getarrayitem_gc_pure = consider_getarrayitem_gc
@@ -909,47 +854,43 @@
 #    xxx_consider_cast_int_to_ptr  = consider_same_as
 
     def consider_int_is_true(self, op, ignored):
-        argloc, ops = self.force_allocate_reg(op.args[0], [])
+        argloc = self.force_allocate_reg(op.args[0], [])
         self.eventually_free_var(op.args[0])
-        resloc, more_ops = self.force_allocate_reg(op.result, [])
-        return ops + more_ops + [Perform(op, [argloc], resloc)]
+        resloc = self.force_allocate_reg(op.result, [])
+        self.Perform(op, [argloc], resloc)
 
     def _consider_nullity(self, op, ignored):
         # doesn't need a register in arg
         argloc = self.loc(op.args[0])
         self.eventually_free_var(op.args[0])
-        resloc, ops = self.force_allocate_reg(op.result, [])
-        return ops + [Perform(op, [argloc], resloc)]
+        resloc = self.force_allocate_reg(op.result, [])
+        self.Perform(op, [argloc], resloc)
     
     consider_ooisnull = _consider_nullity
     consider_oononnull = _consider_nullity
 
     def consider_strlen(self, op, ignored):
-        base_loc, ops0 = self.make_sure_var_in_reg(op.args[0], op.args)
+        base_loc = self.make_sure_var_in_reg(op.args[0], op.args)
         self.eventually_free_vars(op.args)
-        result_loc, more_ops = self.force_allocate_reg(op.result, [])
-        return ops0 + more_ops + [Perform(op, [base_loc], result_loc)]
+        result_loc = self.force_allocate_reg(op.result, [])
+        self.Perform(op, [base_loc], result_loc)
 
     def consider_arraylen_gc(self, op, ignored):
         _, ofs, _ = self._unpack_arraydescr(op.descr)
-        base_loc, ops0 = self.make_sure_var_in_reg(op.args[0], op.args)
+        base_loc = self.make_sure_var_in_reg(op.args[0], op.args)
         self.eventually_free_vars(op.args)
-        result_loc, more_ops = self.force_allocate_reg(op.result, [])
-        return ops0 + more_ops + [Perform(op, [base_loc, imm(ofs)],
-                                          result_loc)]
+        result_loc = self.force_allocate_reg(op.result, [])
+        self.Perform(op, [base_loc, imm(ofs)], result_loc)
 
     def consider_strgetitem(self, op, ignored):
-        base_loc, ops0 = self.make_sure_var_in_reg(op.args[0], op.args)
-        ofs_loc, ops1 = self.make_sure_var_in_reg(op.args[1], op.args)
+        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, more_ops = self.force_allocate_reg(op.result, [])
-        return (ops0 + ops1 + more_ops +
-                [Perform(op, [base_loc, ofs_loc], result_loc)])
+        result_loc = self.force_allocate_reg(op.result, [])
+        self.Perform(op, [base_loc, ofs_loc], result_loc)
 
     def consider_jump(self, op, ignored):
-        ops = []
-        laterops = []
-        middle_ops = []
+        later_loads = []
         reloaded = []
         middle_busy_regs = []
         for i in range(len(op.args)):
@@ -961,7 +902,8 @@
                 assert mp.opnum == rop.MERGE_POINT
                 if arg in self.reg_bindings:
                     if not isinstance(res, REG):
-                        ops.append(Store(arg, self.loc(arg), self.stack_bindings[arg]))
+                        self.Store(arg, self.loc(arg),
+                                   self.stack_bindings[arg])
                     elif res is self.reg_bindings[arg]:
                         middle_busy_regs.append(res)
                     else:
@@ -971,21 +913,23 @@
                         # if our register is free, easy
                         for v, reg in self.reg_bindings.items():
                             if reg is res:
-                                ops.append(Store(arg, self.loc(arg), self.stack_loc(arg)))
-                                laterops.append(Load(arg, self.stack_loc(arg), res))
+                                self.Store(arg, self.loc(arg),
+                                           self.stack_loc(arg))
+                                later_loads.append((arg, self.stack_loc(arg),
+                                                    res))
                                 break
                         else:
-                            ops.append(Load(arg, self.loc(arg), res))
+                            self.Load(arg, self.loc(arg), res)
                 else:
                     if arg not in self.stack_bindings:
                         # we can load it correctly, because we don't care
                         # any more about the previous var staying there
                         assert not isinstance(res, REG)
-                        ops.append(Store(arg, self.loc(arg), res))
+                        self.Store(arg, self.loc(arg), res)
                     else:
                         assert arg not in self.dirty_stack
                         if isinstance(res, REG):
-                            laterops.append(Load(arg, self.loc(arg), res))
+                            later_loads.append((arg, self.loc(arg), res))
                         else:
                             arg0 = self.loc(arg)
                             assert isinstance(arg0, MODRM)
@@ -993,13 +937,11 @@
                             if arg0.position != res.position:
                                 reloaded.append((arg, self.loc(arg), res))
             elif isinstance(arg, Const):
-                laterops.append(Load(arg, self.loc(arg), res))
+                later_loads.append((arg, self.loc(arg), res))
+        self.eventually_free_vars(op.args)
         if reloaded:
-            self.eventually_free_vars(op.args)
-            middleops = []
             # XXX performance
             free_reg = None
-            last_middle_op = None
             for reg in REGS:
                 if reg not in middle_busy_regs:
                     free_reg = reg
@@ -1008,16 +950,14 @@
                 # a very rare case
                 v = self.reg_bindings.keys()[0]
                 free_reg = self.reg_bindings[v]
-                ops.append(Store(v, self.loc(v), self.stack_loc(v)))
-                last_middle_op = Load(v, self.stack_loc(v), self.loc(v))
+                self.Store(v, self.loc(v), self.stack_loc(v))
+                later_loads.insert(0, (v, self.stack_loc(v), self.loc(v)))
             for v, from_l, to_l in reloaded:
-                middleops.append(Load(v, from_l, free_reg))
-                middleops.append(Store(v, free_reg, to_l))
-            if last_middle_op is not None:
-                middleops.append(last_middle_op)
-            return ops + middleops + laterops + [PerformDiscard(op, [])]
-        self.eventually_free_vars(op.args)
-        return ops + laterops + [PerformDiscard(op, [])]
+                self.Load(v, from_l, free_reg)
+                self.Store(v, free_reg, to_l)
+        for v, from_l, to_l in later_loads:
+            self.Load(v, from_l, to_l)
+        self.PerformDiscard(op, [])
 
     def not_implemented_op(self, op, ignored):
         print "[regalloc] Not implemented operation: %s" % op.getopname()

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py	Thu Mar 19 13:06:12 2009
@@ -148,7 +148,7 @@
     res = cpu.execute_operations_in_new_frame('foo', ops,
                                                [arg0, arg1])
 
-    assert len(cpu.assembler._regalloc.computed_ops) == 2
+    #assert len(cpu.assembler._regalloc.computed_ops) == 2
     assert meta_interp.gf
     # er, what to check here, assembler???
 
@@ -174,7 +174,7 @@
     res = cpu.execute_operations_in_new_frame('foo', ops,
                                                [arg0, arg1])
 
-    assert len(cpu.assembler._regalloc.computed_ops) == 5
+    #assert len(cpu.assembler._regalloc.computed_ops) == 5
     assert meta_interp.gf
     # er, what to check here, assembler???
 



More information about the Pypy-commit mailing list