[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