[pypy-svn] r79306 - in pypy/branch/arm-backend/pypy/jit/backend/arm: . helper
david at codespeak.net
david at codespeak.net
Sat Nov 20 18:57:11 CET 2010
Author: david
Date: Sat Nov 20 18:57:08 2010
New Revision: 79306
Modified:
pypy/branch/arm-backend/pypy/jit/backend/arm/assembler.py
pypy/branch/arm-backend/pypy/jit/backend/arm/helper/assembler.py
pypy/branch/arm-backend/pypy/jit/backend/arm/opassembler.py
Log:
Refactor how guards are generated
Now a jump a the head checks the condition and skips the guard if the conditions holds
Fixes an issue with spilling withing a guard which was overwritten when patching the guard code from a bridge
Also free result vars for the case that they are not used.
Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/assembler.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/assembler.py (original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/assembler.py Sat Nov 20 18:57:08 2010
@@ -170,8 +170,7 @@
"""
descr = op.getdescr()
- box = TempBox()
- reg = regalloc.force_allocate_reg(box)
+ reg = r.lr
# XXX free this memory
# XXX allocate correct amount of memory
mem = lltype.malloc(rffi.CArray(lltype.Char), len(args)*6+9, flavor='raw')
@@ -214,14 +213,10 @@
n = self.cpu.get_fail_descr_number(descr)
self.encode32(mem, j+1, n)
+ self.mc.ensure_can_fit(self.mc.size_of_gen_load_int)
self.mc.gen_load_int(r.lr.value, memaddr, cond=fcond) # use lr to pass an argument
- self.mc.B(self._exit_code_addr, fcond, reg)
+ self.mc.B(self._exit_code_addr)
- # This register is used for patching when assembling a bridge
- # guards going to be patched are allways conditional
- if fcond != c.AL:
- descr._arm_guard_reg = reg
- regalloc.possibly_free_var(box)
return memaddr
def align(self):
@@ -367,7 +362,6 @@
i = 0
while i < len(operations):
op = operations[i]
- # XXX consider merging ops with next one if it is an adecuate guard
opnum = op.getopnum()
if self.can_merge_with_next_guard(op, i, operations):
fcond = self.operations_with_guard[opnum](self, op,
@@ -401,7 +395,7 @@
self._walk_operations(operations, regalloc)
print 'Done building bridges'
- self.patch_trace(faildescr, bridge_head)
+ self.patch_trace(faildescr, bridge_head, regalloc)
print 'Done patching trace'
if self._debug_asm:
self._dump_trace('bridge.asm')
@@ -418,11 +412,12 @@
#XXX check ranges for different operations
return isinstance(arg, ConstInt) and arg.getint() <= size and lower_bound
- def patch_trace(self, faildescr, bridge_addr):
- # XXX make sure there is enough space at patch target
- fcond = faildescr._arm_guard_cond
- b = ARMv7InMemoryBuilder(faildescr._arm_guard_code, faildescr._arm_guard_size)
- b.B(bridge_addr, fcond, some_reg=faildescr._arm_guard_reg)
+ def patch_trace(self, faildescr, bridge_addr, regalloc):
+ # The first instruction (word) is not overwritten, because it is the
+ # one that actually checks the condition
+ b = ARMv7InMemoryBuilder(faildescr._arm_guard_code,
+ self.guard_size-WORD)
+ b.B(bridge_addr, some_reg=r.lr)
# regalloc support
def regalloc_mov(self, prev_loc, loc):
Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/helper/assembler.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/helper/assembler.py (original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/helper/assembler.py Sat Nov 20 18:57:08 2010
@@ -12,6 +12,8 @@
self.mc.MOV_ri(res.value, 1, true_cond)
self.mc.MOV_ri(res.value, 0, false_cond)
regalloc.possibly_free_vars_for_op(op)
+ if op.result:
+ regalloc.possibly_free_var(op.result)
return fcond
return f
@@ -41,6 +43,8 @@
res = regalloc.force_allocate_reg(op.result, [arg0, arg1])
rr_op(res.value, l0.value, l1.value)
regalloc.possibly_free_vars_for_op(op)
+ if op.result:
+ regalloc.possibly_free_var(op.result)
return fcond
return f
@@ -56,7 +60,10 @@
regalloc.before_call()
getattr(self.mc, opname)(fcond)
regalloc.after_call(op.result)
+
regalloc.possibly_free_vars_for_op(op)
+ if op.result:
+ regalloc.possibly_free_var(op.result)
return fcond
return f
@@ -87,5 +94,7 @@
self.mc.MOV_ri(res.value, 1, cond=condition)
self.mc.MOV_ri(res.value, 0, cond=inv)
regalloc.possibly_free_vars_for_op(op)
+ if op.result:
+ regalloc.possibly_free_var(op.result)
return fcond
return f
Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/opassembler.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/opassembler.py (original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/opassembler.py Sat Nov 20 18:57:08 2010
@@ -49,6 +49,8 @@
res = regalloc.force_allocate_reg(op.result, forbidden_vars=[a0, a1])
self.mc.ADD_rr(res.value, l0.value, l1.value, s=1)
regalloc.possibly_free_vars_for_op(op)
+ if op.result:
+ regalloc.possibly_free_var(op.result)
return fcond
def emit_op_int_sub(self, op, regalloc, fcond):
@@ -79,6 +81,8 @@
self.mc.SUB_rr(res.value, l0.value, l1.value, s=1)
regalloc.possibly_free_vars_for_op(op)
+ if op.result:
+ regalloc.possibly_free_var(op.result)
return fcond
def emit_op_int_mul(self, op, regalloc, fcond):
@@ -89,6 +93,7 @@
res = regalloc.force_allocate_reg(op.result, [a0, a1])
self.mc.MUL(res.value, reg1.value, reg2.value)
regalloc.possibly_free_vars_for_op(op)
+ regalloc.possibly_free_var(op.result)
return fcond
#ref: http://blogs.arm.com/software-enablement/detecting-overflow-from-mul/
@@ -102,10 +107,12 @@
self.mc.SMULL(res.value, r.ip.value, reg1.value, reg2.value, cond=fcond)
self.mc.CMP_rr(r.ip.value, res.value, shifttype=shift.ASR, imm=31, cond=fcond)
regalloc.possibly_free_vars_for_op(op)
+ if op.result:
+ regalloc.possibly_free_var(op.result)
if guard.getopnum() == rop.GUARD_OVERFLOW:
- return self._emit_guard(guard, regalloc, c.EQ)
- else:
return self._emit_guard(guard, regalloc, c.NE)
+ else:
+ return self._emit_guard(guard, regalloc, c.EQ)
emit_op_int_floordiv = gen_emit_op_by_helper_call('DIV')
emit_op_int_mod = gen_emit_op_by_helper_call('MOD')
@@ -150,6 +157,8 @@
self.mc.MVN_rr(res.value, reg.value)
regalloc.possibly_free_vars_for_op(op)
+ if op.result:
+ regalloc.possibly_free_var(op.result)
return fcond
#XXX check for a better way of doing this
@@ -166,17 +175,19 @@
_mixin_ = True
+ guard_size = ARMv7Builder.size_of_gen_load_int + 2*WORD
def _emit_guard(self, op, regalloc, fcond):
descr = op.getdescr()
assert isinstance(descr, BasicFailDescr)
if hasattr(op, 'getfailargs'):
print 'Failargs: ', op.getfailargs()
+ self.mc.ensure_can_fit(self.guard_size)
+ self.mc.ADD_ri(r.pc.value, r.pc.value, self.guard_size, cond=fcond)
descr._arm_guard_code = self.mc.curraddr()
- memaddr = self._gen_path_to_exit_path(op, op.getfailargs(), regalloc, fcond)
+ memaddr = self._gen_path_to_exit_path(op, op.getfailargs(), regalloc)
descr._failure_recovery_code = memaddr
- descr._arm_guard_cond = fcond
- descr._arm_guard_size = self.mc.curraddr() - descr._arm_guard_code
regalloc.possibly_free_vars_for_op(op)
+ self.mc.NOP()
return c.AL
def emit_op_guard_true(self, op, regalloc, fcond):
@@ -184,14 +195,14 @@
l0 = regalloc.make_sure_var_in_reg(a0, imm_fine=False)
self.mc.CMP_ri(l0.value, 0)
regalloc.possibly_free_var(l0)
- return self._emit_guard(op, regalloc, c.EQ)
+ return self._emit_guard(op, regalloc, c.NE)
def emit_op_guard_false(self, op, regalloc, fcond):
a0 = op.getarg(0)
l0 = regalloc.make_sure_var_in_reg(a0, imm_fine=False)
self.mc.CMP_ri(l0.value, 0)
regalloc.possibly_free_var(l0)
- return self._emit_guard(op, regalloc, c.NE)
+ return self._emit_guard(op, regalloc, c.EQ)
def emit_op_guard_value(self, op, regalloc, fcond):
a0 = op.getarg(0)
@@ -204,16 +215,16 @@
else:
self.mc.CMP_rr(l0.value, l1.value)
regalloc.possibly_free_vars_for_op(op)
- return self._emit_guard(op, regalloc, c.NE)
+ return self._emit_guard(op, regalloc, c.EQ)
emit_op_guard_nonnull = emit_op_guard_true
emit_op_guard_isnull = emit_op_guard_false
def emit_op_guard_no_overflow(self, op, regalloc, fcond):
- return self._emit_guard(op, regalloc, c.VS)
+ return self._emit_guard(op, regalloc, c.VC)
def emit_op_guard_overflow(self, op, regalloc, fcond):
- return self._emit_guard(op, regalloc, c.VC)
+ return self._emit_guard(op, regalloc, c.VS)
class OpAssembler(object):
@@ -301,6 +312,8 @@
else:
self.mc.MOV_rr(resloc.value, argloc.value)
regalloc.possibly_free_vars_for_op(op)
+ if op.result:
+ regalloc.possibly_free_var(op.result)
return fcond
class FieldOpAssembler(object):
@@ -373,6 +386,8 @@
self.mc.LDR_ri(res.value, base_loc.value, ofs)
regalloc.possibly_free_var(op.getarg(0))
+ if op.result:
+ regalloc.possibly_free_var(op.result)
def emit_op_setarrayitem_gc(self, op, regalloc, fcond):
a0 = op.getarg(0)
@@ -443,6 +458,8 @@
l0 = regalloc.make_sure_var_in_reg(op.getarg(0), imm_fine=False)
regalloc.possibly_free_vars_for_op(op)
res = regalloc.force_allocate_reg(op.result)
+ if op.result:
+ regalloc.possibly_free_var(op.result)
basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR,
self.cpu.translate_support_code)
l1 = regalloc.make_sure_var_in_reg(ConstInt(ofs_length))
@@ -460,6 +477,8 @@
res = regalloc.force_allocate_reg(op.result)
regalloc.possibly_free_vars_for_op(op)
regalloc.possibly_free_var(t)
+ if op.result:
+ regalloc.possibly_free_var(op.result)
basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR,
self.cpu.translate_support_code)
@@ -480,6 +499,8 @@
temp = regalloc.force_allocate_reg(t)
regalloc.possibly_free_vars_for_op(op)
regalloc.possibly_free_var(t)
+ if op.result:
+ regalloc.possibly_free_var(op.result)
basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR,
self.cpu.translate_support_code)
@@ -499,6 +520,8 @@
l0 = regalloc.make_sure_var_in_reg(op.getarg(0), imm_fine=False)
regalloc.possibly_free_vars_for_op(op)
res = regalloc.force_allocate_reg(op.result)
+ if op.result:
+ regalloc.possibly_free_var(op.result)
basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE,
self.cpu.translate_support_code)
l1 = regalloc.make_sure_var_in_reg(ConstInt(ofs_length))
@@ -516,6 +539,8 @@
res = regalloc.force_allocate_reg(op.result)
regalloc.possibly_free_vars_for_op(op)
regalloc.possibly_free_var(t)
+ if op.result:
+ regalloc.possibly_free_var(op.result)
basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE,
self.cpu.translate_support_code)
@@ -539,6 +564,8 @@
temp = regalloc.force_allocate_reg(t)
regalloc.possibly_free_vars_for_op(op)
regalloc.possibly_free_var(t)
+ if op.result:
+ regalloc.possibly_free_var(op.result)
basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE,
self.cpu.translate_support_code)
@@ -661,8 +688,10 @@
self.mc.CMP_ri(l0.value, 0)
regalloc.possibly_free_var(t)
regalloc.possibly_free_vars_for_op(op)
+ if op.result:
+ regalloc.possibly_free_var(op.result)
- self._emit_guard(guard_op, regalloc, c.LT)
+ self._emit_guard(guard_op, regalloc, c.GE)
return fcond
def emit_guard_call_may_force(self, op, guard_op, regalloc, fcond):
@@ -679,7 +708,7 @@
self.mc.CMP_ri(l0.value, 0)
regalloc.possibly_free_var(t)
- self._emit_guard(guard_op, regalloc, c.LT)
+ self._emit_guard(guard_op, regalloc, c.GE)
return fcond
def _write_fail_index(self, fail_index, regalloc):
More information about the Pypy-commit
mailing list