[pypy-svn] r36628 - pypy/dist/pypy/jit/codegen/ppc

niko at codespeak.net niko at codespeak.net
Sat Jan 13 00:10:21 CET 2007


Author: niko
Date: Sat Jan 13 00:10:11 2007
New Revision: 36628

Modified:
   pypy/dist/pypy/jit/codegen/ppc/instruction.py
   pypy/dist/pypy/jit/codegen/ppc/regalloc.py
   pypy/dist/pypy/jit/codegen/ppc/rgenop.py
Log:
purge crfinfo, and instead store the information about which
bits etc we need from the condition registers in the CRF object




Modified: pypy/dist/pypy/jit/codegen/ppc/instruction.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/instruction.py	(original)
+++ pypy/dist/pypy/jit/codegen/ppc/instruction.py	Sat Jan 13 00:10:11 2007
@@ -6,11 +6,24 @@
 rFP = r2 # the ABI doesn't specify a frame pointer.  however, we want one
 
 class AllocationSlot(object):
-    pass
+    def __init__(self):
+        # The field alloc points to a singleton used by the register
+        # allocator to detect conflicts.  No two AllocationSlot
+        # instances with the same value in self.alloc can be used at
+        # once.
+        self.alloc = self
+        
+    def make_loc(self):
+        """ When we assign a variable to one of these registers, we
+        call make_loc() to get the actual location instance; that
+        instance will have its alloc field set to self.  For
+        everything but condition registers, this is self."""
+        return self
 
 class _StackSlot(AllocationSlot):
     is_register = False
     def __init__(self, offset):
+        AllocationSlot.__init__(self)
         self.offset = offset
     def __repr__(self):
         return "stack@%s"%(self.offset,)
@@ -34,10 +47,13 @@
 
 class Register(AllocationSlot):
     is_register = True
+    def __init__(self):
+        AllocationSlot.__init__(self)        
 
 class GPR(Register):
     regclass = GP_REGISTER
     def __init__(self, number):
+        Register.__init__(self)
         self.number = number
     def __repr__(self):
         return 'r' + str(self.number)
@@ -46,23 +62,47 @@
 class FPR(Register):
     regclass = FP_REGISTER
     def __init__(self, number):
+        Register.__init__(self)
         self.number = number
 
 fprs = map(GPR, range(32))
 
-class CRF(Register):
+class BaseCRF(Register):
+    """ These represent condition registers; however, we never actually
+    use these as the location of something in the register allocator.
+    Instead, we place it in an instance of CRF which indicates which
+    bits are required to extract the value.  Note that CRF().alloc will
+    always be an instance of this. """
     regclass = CR_FIELD
     def __init__(self, number):
         self.number = number
+        self.alloc = self
+    def make_loc(self):
+        return CRF(self)
+
+crfs = map(BaseCRF, range(8))
+
+class CRF(Register):
+    regclass = CR_FIELD
+    def __init__(self, crf):
+        Register.__init__(self)
+        self.alloc = crf
+        self.number = crf.number
+        self.info = (-1,-1) # (bit, negated) 
+    def set_info(self, info):
+        assert len(info) == 2
+        self.info = info
+    def make_loc(self):
+        # should never call this on a CRF, only a BaseCRF
+        raise NotImplementedError
     def move_to_gpr(self, allocator, gpr):
-        bit, negated = allocator.crfinfo[self.number]
-        return _CRF2GPR(gpr, self.number*4 + bit, negated)
+        bit, negated = self.info
+        return _CRF2GPR(gpr, self.alloc.number*4 + bit, negated)
     def move_from_gpr(self, allocator, gpr):
-        allocator.crfinfo[self.number] = (2, 1) # cmp2info['ne']
+        # cmp2info['ne']
+        self.set_info((2, 1))
         return _GPR2CRF(self, gpr)
 
-crfs = map(CRF, range(8))
-
 class CTR(Register):
     regclass = CT_REGISTER
     def move_from_gpr(self, allocator, gpr):
@@ -182,12 +222,12 @@
     def allocate(self, allocator):
         self.targetreg = allocator.loc_of(self.result)
         self.crf = allocator.loc_of(self.reg_args[0])
-        self.bit, self.negated = allocator.crfinfo[self.crf.number]
-        assert self.bit != -1 and self.negated != -1, "uninitialized crfinfo!"
     def emit(self, asm):
+        assert isinstance(self.crf, CRF)
+        bit, negated = self.crf.info
         asm.mfcr(self.targetreg.number)
-        asm.extrwi(self.targetreg.number, self.targetreg.number, 1, self.crf.number*4+self.bit)
-        if self.negated:
+        asm.extrwi(self.targetreg.number, self.targetreg.number, 1, self.crf.number*4+bit)
+        if negated:
             asm.xori(self.targetreg.number, self.targetreg.number, 1)
 
 class Insn_None__GPR_GPR_IMM(Insn):
@@ -235,22 +275,25 @@
                      self.reg3.number)
 
 class CMPInsn(Insn):
-    info = (0,0) # please the annotator for tests that don't use CMPW/CMPWI
-    pass
-
-class CMPW(CMPInsn):
-    def __init__(self, info, result, args):
+    def __init__(self, info, result):
         Insn.__init__(self)
         self.info = info
-
         self.result = result
-        self.result_regclass = CR_FIELD
 
+    def allocate(self, allocator):
+        self.result_reg = allocator.loc_of(self.result)
+        assert isinstance(self.result_reg, CRF)
+        self.result_reg.set_info(self.info)
+
+class CMPW(CMPInsn):
+    def __init__(self, info, result, args):
+        CMPInsn.__init__(self, info, result)
+        self.result_regclass = CR_FIELD
         self.reg_args = args
         self.reg_arg_regclasses = [GP_REGISTER, GP_REGISTER]
 
     def allocate(self, allocator):
-        self.result_reg = allocator.loc_of(self.result)
+        CMPInsn.allocate(self, allocator)
         self.arg_reg1 = allocator.loc_of(self.reg_args[0])
         self.arg_reg2 = allocator.loc_of(self.reg_args[1])
 
@@ -263,18 +306,14 @@
 
 class CMPWI(CMPInsn):
     def __init__(self, info, result, args):
-        Insn.__init__(self)
-        self.info = info
+        CMPInsn.__init__(self, info, result)
         self.imm = args[1]
-
-        self.result = result
         self.result_regclass = CR_FIELD
-
         self.reg_args = [args[0]]
         self.reg_arg_regclasses = [GP_REGISTER]
 
     def allocate(self, allocator):
-        self.result_reg = allocator.loc_of(self.result)
+        CMPInsn.allocate(self, allocator)
         self.arg_reg = allocator.loc_of(self.reg_args[0])
 
     def emit(self, asm):
@@ -316,14 +355,11 @@
         self.targetbuilder = targetbuilder
     def allocate(self, allocator):
         self.crf = allocator.loc_of(self.reg_args[0])
-        self.bit, self.negated = allocator.crfinfo[self.crf.number]
-        assert self.bit != -1 and self.negated != -1, "uninitialized crfinfo!"
 
         assert self.targetbuilder.initial_var2loc is None
         self.targetbuilder.initial_var2loc = {}
         for gv_arg in self.jump_args_gv:
             self.targetbuilder.initial_var2loc[gv_arg] = allocator.var2loc[gv_arg]
-        self.targetbuilder.initial_crfinfo = allocator.crfinfo[:]
         allocator.builders_to_tell_spill_offset_to.append(self.targetbuilder)
     def emit(self, asm):
         if self.targetbuilder.start:
@@ -332,11 +368,12 @@
             self.targetbuilder.patch_start_here = asm.mc.tell()
             asm.load_word(rSCRATCH, 0)
         asm.mtctr(rSCRATCH)
-        if self.negated ^ self.jump_if_true:
+        bit, negated = self.crf.info
+        if negated ^ self.jump_if_true:
             BO = 12 # jump if relavent bit is set in the CR
         else:
             BO = 4  # jump if relavent bit is NOT set in the CR
-        asm.bcctr(BO, self.crf.number*4 + self.bit)
+        asm.bcctr(BO, self.crf.number*4 + bit)
 
 class SpillCalleeSaves(Insn):
     def __init__(self):

Modified: pypy/dist/pypy/jit/codegen/ppc/regalloc.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/regalloc.py	(original)
+++ pypy/dist/pypy/jit/codegen/ppc/regalloc.py	Sat Jan 13 00:10:11 2007
@@ -9,8 +9,7 @@
 DEBUG_PRINT = option.debug_print
 
 class RegisterAllocation:
-    def __init__(self, freeregs, initial_mapping,
-                 initial_spill_offset, initial_crfinfo):
+    def __init__(self, freeregs, initial_mapping, initial_spill_offset):
         if DEBUG_PRINT:
             print
             print "RegisterAllocation __init__", initial_mapping.items()
@@ -34,13 +33,10 @@
         # go through the initial mapping and initialize the data structures
         for var, loc in initial_mapping.iteritems():
             self.set(var, loc)
-            if loc.is_register and loc in self.freeregs[loc.regclass]:
-                self.freeregs[loc.regclass].remove(loc)
+            if loc.is_register and loc.alloc in self.freeregs[loc.regclass]:
+                self.freeregs[loc.regclass].remove(loc.alloc)
                 self.lru.append(var)
 
-        # crfinfo is a bit of a hack used to transmit which bit a compare
-        # instruction set to the branch instruction
-        self.crfinfo = initial_crfinfo[:]
         self.builders_to_tell_spill_offset_to = []
 
     def set(self, var, loc):
@@ -79,7 +75,7 @@
         freeregs = self.freeregs[regclass]
 
         if freeregs:
-            reg = freeregs.pop()
+            reg = freeregs.pop().make_loc()
             self.set(newarg, reg)
             if DEBUG_PRINT:
                 print "allocate_reg: Putting %r into fresh register %r" % (newarg, reg)
@@ -105,7 +101,7 @@
             print "allocate_reg: Spilled %r to %r." % (argtospill, self.loc_of(argtospill))
 
         # update data structures to put newarg into the register
-        self.set(newarg, reg)
+        self.set(newarg, reg.alloc.make_loc())
         if DEBUG_PRINT:
             print "allocate_reg: Put %r in stolen reg %r." % (newarg, reg)
         return reg
@@ -174,7 +170,7 @@
                     # it's in the wrong kind of register
                     # (this code is excessively confusing)
                     self.forget(arg, argloc)
-                    self.freeregs[argloc.regclass].append(argloc)
+                    self.freeregs[argloc.regclass].append(argloc.alloc)
                     if argloc.regclass != GP_REGISTER:
                         if argcls == GP_REGISTER:
                             gpr = self._allocate_reg(GP_REGISTER, arg).number
@@ -199,8 +195,6 @@
                 if DEBUG_PRINT:
                     print "Allocating register for result %r..." % (insn.result,)
                 resultreg = self._allocate_reg(insn.result_regclass, insn.result)
-                if isinstance(insn, CMPInsn):
-                    self.crfinfo[resultreg.number] = insn.info
             insn.allocate(self)
             self.insns.append(insn)
         return self.insns

Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/rgenop.py	(original)
+++ pypy/dist/pypy/jit/codegen/ppc/rgenop.py	Sat Jan 13 00:10:11 2007
@@ -29,6 +29,7 @@
 
 _var_index = [0]
 class Var(GenVar):
+    conditional = False
     def __init__(self):
         self.__magic_index = _var_index[0]
         _var_index[0] += 1
@@ -37,11 +38,16 @@
     def fits_in_immediate(self):
         return False
 
+class ConditionVar(Var):
+    """ Used for vars that originated as the result of a conditional
+    operation, like a == b """
+    conditional = True
+
 class IntConst(GenConst):
 
     def __init__(self, value):
         self.value = value
-
+        
     @specialize.arg(1)
     def revealconst(self, T):
         if isinstance(T, lltype.Ptr):
@@ -204,7 +210,6 @@
         self.stack_adj_addr = 0
         self.initial_spill_offset = 0
         self.initial_var2loc = None
-        self.initial_crfinfo = [(-1, -1)] * 8
         self.max_param_space = -1
         self.final_jump_addr = 0
 
@@ -348,7 +353,6 @@
         #print 'initial_var2loc.keys():', [id(v) for v in self.initial_var2loc.keys()]
         #print 'initial_var2loc.values():', [id(v) for v in self.initial_var2loc.values()]
         allocator = self.allocate_and_emit(vars_gv)
-        self.initial_crfinfo = allocator.crfinfo
         var2loc = allocator.var2loc
 
         #print '!!!!', args_gv, var2loc
@@ -366,7 +370,6 @@
         self.initial_var2loc = var2loc
         if reallocate:
             allocator = self.allocate_and_emit([v for v in args_gv if isinstance(v, Var)])
-            self.initial_crfinfo = allocator.crfinfo
             var2loc = allocator.var2loc
             self.insns = []
 
@@ -603,8 +606,7 @@
         allocator = RegisterAllocation(
             self.rgenop.freeregs,
             self.initial_var2loc,
-            self.initial_spill_offset,
-            self.initial_crfinfo)
+            self.initial_spill_offset)
         self.insns = allocator.allocate_for_insns(self.insns)
         return allocator
 
@@ -710,7 +712,7 @@
 
     def _compare(self, op, gv_x, gv_y):
         #print "op", op
-        gv_result = Var()
+        gv_result = ConditionVar()
         if gv_y.fits_in_immediate():
             self.insns.append(
                 insn.CMPWI(self.cmp2info[op], gv_result, [gv_x, gv_y]))
@@ -723,7 +725,7 @@
         return gv_result
 
     def _compare_u(self, op, gv_x, gv_y):
-        gv_result = Var()
+        gv_result = ConditionVar()
         if gv_y.fits_in_immediate():
             self.insns.append(
                 insn.CMPWLI(self.cmp2info[op], gv_result, [gv_x, gv_y]))



More information about the Pypy-commit mailing list