[pypy-commit] pypy arm-backend-2: refactor guards make the handling more similar to how it is done in the x86
bivab
noreply at buildbot.pypy.org
Fri Jul 1 14:18:37 CEST 2011
Author: David Schneider <david.schneider at picle.org>
Branch: arm-backend-2
Changeset: r45219:0268a6ca49d1
Date: 2011-07-01 14:25 +0200
http://bitbucket.org/pypy/pypy/changeset/0268a6ca49d1/
Log: refactor guards make the handling more similar to how it is done in
the x86 backend generating a check and a conditional jump to an exit
stub that is later generated at the end of the compiled loop.
diff --git a/pypy/jit/backend/arm/assembler.py b/pypy/jit/backend/arm/assembler.py
--- a/pypy/jit/backend/arm/assembler.py
+++ b/pypy/jit/backend/arm/assembler.py
@@ -300,11 +300,7 @@
return mc.materialize(self.cpu.asmmemmgr, [],
self.cpu.gc_ll_descr.gcrootmap)
- def gen_descr_encoding(self, op, args, arglocs):
- descr = op.getdescr()
- if op.getopnum() != rop.FINISH:
- assert isinstance(descr, AbstractFailDescr)
- descr._arm_frame_depth = arglocs[0].getint()
+ def gen_descr_encoding(self, descr, args, arglocs):
# The size of the allocated memory is based on the following sizes
# first argloc is the frame depth and not considered for the memory
# allocation
@@ -359,8 +355,8 @@
encode32(mem, j+1, n)
return memaddr
- def _gen_path_to_exit_path(self, op, args, arglocs, fcond=c.AL, save_exc=False):
- memaddr = self.gen_descr_encoding(op, args, arglocs)
+ def _gen_path_to_exit_path(self, descr, args, arglocs, fcond=c.AL, save_exc=False):
+ memaddr = self.gen_descr_encoding(descr, args, arglocs)
self.gen_exit_code(self.mc, memaddr, fcond, save_exc)
return memaddr
@@ -586,6 +582,7 @@
direct_bootstrap_code = self.mc.currpos()
self.gen_direct_bootstrap_code(loop_head, looptoken, inputargs)
+ self.write_pending_failure_recoveries()
loop_start = self.materialize_loop(looptoken)
looptoken._arm_bootstrap_code = loop_start
looptoken._arm_direct_bootstrap_code = loop_start + direct_bootstrap_code
@@ -617,6 +614,7 @@
#original_loop_token._arm_frame_depth = regalloc.frame_manager.frame_depth
self._patch_sp_offset(sp_patch_location, regalloc.frame_manager.frame_depth)
+ self.write_pending_failure_recoveries()
bridge_start = self.materialize_loop(original_loop_token)
self.process_pending_guards(bridge_start)
@@ -634,17 +632,38 @@
return self.mc.materialize(self.cpu.asmmemmgr, allblocks,
self.cpu.gc_ll_descr.gcrootmap)
+ def write_pending_failure_recoveries(self):
+ for tok in self.pending_guards:
+ descr = tok.descr
+ #generate the exit stub and the encoded representation
+ pos = self.mc.currpos()
+ tok.pos_recovery_stub = pos
+
+ memaddr = self._gen_path_to_exit_path(descr, tok.failargs,
+ tok.faillocs, save_exc=tok.save_exc)
+ # store info on the descr
+ descr._arm_frame_depth = tok.faillocs[0].getint()
+ descr._failure_recovery_code = memaddr
+ descr._arm_guard_pos = pos
+
def process_pending_guards(self, block_start):
clt = self.current_clt
for tok in self.pending_guards:
descr = tok.descr
+ assert isinstance(descr, AbstractFailDescr)
+
#XXX _arm_block_start should go in the looptoken
descr._arm_block_start = block_start
- descr._failure_recovery_code = tok.encoded_args
- descr._arm_guard_pos = tok.offset
- if tok.is_invalidate:
+
+ if not tok.is_invalidate:
+ #patch the guard jumpt to the stub
+ # overwrite the generate NOP with a B_offs to the pos of the stub
+ mc = ARMv7Builder()
+ mc.B_offs(descr._arm_guard_pos - tok.offset, c.get_opposite_of(tok.fcond))
+ mc.copy_to_raw_memory(block_start + tok.offset)
+ else:
clt.invalidate_positions.append(
- (block_start + tok.offset, tok.encoded_args))
+ (block_start + tok.offset, descr._arm_guard_pos - tok.offset))
def get_asmmemmgr_blocks(self, looptoken):
clt = looptoken.compiled_loop_token
diff --git a/pypy/jit/backend/arm/codebuilder.py b/pypy/jit/backend/arm/codebuilder.py
--- a/pypy/jit/backend/arm/codebuilder.py
+++ b/pypy/jit/backend/arm/codebuilder.py
@@ -156,6 +156,8 @@
self.write32(cond << 28 | 0xEF1FA10)
def B(self, target, c=cond.AL):
+ #assert self._fits_in_24bits(target)
+ #return (c << 20 | 0xA << 24 | target & 0xFFFFFF)
if c == cond.AL:
self.LDR_ri(reg.pc.value, reg.pc.value, -arch.PC_OFFSET/2)
self.write32(target)
@@ -165,12 +167,9 @@
def B_offs(self, target_ofs, c=cond.AL):
pos = self.currpos()
- if target_ofs > pos:
- raise NotImplementedError
- else:
- target_ofs = target_ofs - (pos + arch.PC_OFFSET)
- assert target_ofs & 0x3 == 0
- self.write32(c << 28 | 0xA << 24 | (target_ofs >> 2) & 0xFFFFFF)
+ target_ofs = target_ofs - (pos + arch.PC_OFFSET)
+ assert target_ofs & 0x3 == 0
+ self.write32(c << 28 | 0xA << 24 | (target_ofs >> 2) & 0xFFFFFF)
def BL(self, target, c=cond.AL):
if c == cond.AL:
@@ -242,6 +241,9 @@
self.index = start
self.end = start + size
+ def currpos(self):
+ return self.index
+
def writechar(self, char):
assert self.index <= self.end
self.cb.overwrite(self.index, char)
diff --git a/pypy/jit/backend/arm/opassembler.py b/pypy/jit/backend/arm/opassembler.py
--- a/pypy/jit/backend/arm/opassembler.py
+++ b/pypy/jit/backend/arm/opassembler.py
@@ -34,11 +34,15 @@
NO_FORCE_INDEX = -1
class GuardToken(object):
- def __init__(self, descr, offset=0, encoded_args=0, is_invalidate=False):
+ def __init__(self, descr, failargs, faillocs, offset, fcond=c.AL,
+ save_exc=False, is_invalidate=False):
self.descr = descr
self.offset = offset
- self.encoded_args = encoded_args
self.is_invalidate = is_invalidate
+ self.failargs = failargs
+ self.faillocs = faillocs
+ self.save_exc = save_exc
+ self.fcond=fcond
class IntOpAsslember(object):
@@ -165,7 +169,7 @@
_mixin_ = True
guard_size = 5*WORD
- def _emit_guard(self, op, arglocs, fcond, save_exc=False):
+ def _emit_guard(self, op, arglocs, fcond, save_exc=False, is_guard_not_ivalidated=False):
descr = op.getdescr()
assert isinstance(descr, AbstractFailDescr)
@@ -173,13 +177,15 @@
if not we_are_translated() and hasattr(op, 'getfailargs'):
print 'Failargs: ', op.getfailargs()
- self.mc.ADD_ri(r.pc.value, r.pc.value, self.guard_size-PC_OFFSET, cond=fcond)
pos = self.mc.currpos()
-
- memaddr = self._gen_path_to_exit_path(op, op.getfailargs(),
- arglocs, save_exc=save_exc)
- self.pending_guards.append(GuardToken(op.getdescr(),
- offset=pos, encoded_args=memaddr))
+ self.mc.NOP()
+ self.pending_guards.append(GuardToken(descr,
+ failargs=op.getfailargs(),
+ faillocs=arglocs,
+ offset=pos,
+ fcond=fcond,
+ is_invalidate=is_guard_not_ivalidated,
+ save_exc=save_exc))
return c.AL
def _emit_guard_overflow(self, guard, failargs, fcond):
@@ -241,17 +247,14 @@
self.mc.CMP_ri(arglocs[0].value, 0)
if offset is not None:
- self.mc.ADD_ri(r.pc.value, r.pc.value, 2*WORD, cond=c.EQ)
+ self._emit_guard(op, arglocs[3:], c.NE)
else:
raise NotImplementedError
self._cmp_guard_class(op, arglocs, regalloc, fcond)
return fcond
def emit_op_guard_not_invalidated(self, op, locs, regalloc, fcond):
- pos = self.mc.currpos() # after potential jmp
- memaddr = self.gen_descr_encoding(op, op.getfailargs(), locs)
- self.pending_guards.append(GuardToken(op.getdescr(), pos, memaddr, True))
- return fcond
+ return self._emit_guard(op, locs, fcond, is_guard_not_ivalidated=True)
def _cmp_guard_class(self, op, locs, regalloc, fcond):
offset = locs[2]
@@ -289,7 +292,7 @@
return fcond
def emit_op_finish(self, op, arglocs, regalloc, fcond):
- self._gen_path_to_exit_path(op, op.getarglist(), arglocs, c.AL)
+ self._gen_path_to_exit_path(op.getdescr(), op.getarglist(), arglocs, c.AL)
return fcond
def emit_op_call(self, op, args, regalloc, fcond, force_index=-1):
diff --git a/pypy/jit/backend/arm/runner.py b/pypy/jit/backend/arm/runner.py
--- a/pypy/jit/backend/arm/runner.py
+++ b/pypy/jit/backend/arm/runner.py
@@ -139,9 +139,9 @@
old one that already has a bridge attached to it."""
from pypy.jit.backend.arm.codebuilder import ARMv7Builder
- for tgt, memaddr in looptoken.compiled_loop_token.invalidate_positions:
+ for jmp, tgt in looptoken.compiled_loop_token.invalidate_positions:
mc = ARMv7Builder()
- self.assembler.gen_exit_code(mc, memaddr)
- mc.copy_to_raw_memory(tgt)
+ mc.B_offs(tgt)
+ mc.copy_to_raw_memory(jmp)
# positions invalidated
looptoken.compiled_loop_token.invalidate_positions = []
More information about the pypy-commit
mailing list