[pypy-commit] pypy arm-backend-2: implement chages to the frame manager
bivab
noreply at buildbot.pypy.org
Thu Dec 29 09:57:34 CET 2011
Author: David Schneider <david.schneider at picle.org>
Branch: arm-backend-2
Changeset: r50945:57c6036823fe
Date: 2011-12-27 16:06 +0100
http://bitbucket.org/pypy/pypy/changeset/57c6036823fe/
Log: implement chages to the frame manager
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
@@ -87,6 +87,7 @@
assert self.memcpy_addr != 0, 'setup_once() not called?'
self.mc = ARMv7Builder()
self.pending_guards = []
+ self.currently_compiling_loop = None
assert self.datablockwrapper is None
allblocks = self.get_asmmemmgr_blocks(looptoken)
self.datablockwrapper = MachineDataBlockWrapper(self.cpu.asmmemmgr,
@@ -98,6 +99,7 @@
self._regalloc = None
self.mc = None
self.pending_guards = None
+ self.currently_compiling_loop = None
assert self.datablockwrapper is None
def setup_once(self):
@@ -641,6 +643,7 @@
looptoken.compiled_loop_token = clt
operations = self.setup(looptoken, operations)
+ self.currently_compiling_loop = looptoken
self._dump(operations)
self.align()
@@ -656,9 +659,9 @@
looptoken._arm_loop_code = loop_head
looptoken._arm_bootstrap_code = 0
- self._walk_operations(operations, regalloc)
-
- looptoken._arm_frame_depth = regalloc.frame_manager.frame_depth
+ looptoken._arm_frame_depth = -1
+ frame_depth = self._assemble(operations, regalloc)
+ looptoken._arm_frame_depth = frame_depth
self._patch_sp_offset(sp_patch_location, looptoken._arm_frame_depth)
self.align()
@@ -679,6 +682,15 @@
print 'Done assembling loop with token %r' % looptoken
self.teardown()
+ def _assemble(self, operations, regalloc):
+ regalloc.compute_hint_frame_locations(operations)
+ self._walk_operations(operations, regalloc)
+ frame_depth = regalloc.frame_manager.get_frame_depth()
+ jump_target_descr = regalloc.jump_target_descr
+ if jump_target_descr is not None:
+ frame_depth = max(frame_depth, jump_target_descr._arm_frame_depth)
+ return frame_depth
+
def assemble_bridge(self, faildescr, inputargs, operations,
original_loop_token, log):
operations = self.setup(original_loop_token, operations)
@@ -692,14 +704,13 @@
assert len(inputargs) == len(arglocs)
regalloc = Regalloc(assembler=self, frame_manager=ARMFrameManager())
- regalloc.prepare_bridge(frame_depth, inputargs, arglocs, operations)
+ regalloc.prepare_bridge(inputargs, arglocs, operations)
sp_patch_location = self._prepare_sp_patch_position()
- self._walk_operations(operations, regalloc)
+ frame_depth = self._assemble(operations, regalloc)
- self._patch_sp_offset(sp_patch_location,
- regalloc.frame_manager.frame_depth)
+ self._patch_sp_offset(sp_patch_location, frame_depth)
self.write_pending_failure_recoveries()
bridge_start = self.materialize_loop(original_loop_token)
@@ -713,6 +724,10 @@
self.cpu.total_compiled_bridges)
self.teardown()
+
+ def target_arglocs(self, loop_token):
+ return loop_token._arm_arglocs
+
def materialize_loop(self, looptoken):
self.datablockwrapper.done() # finish using cpu.asmmemmgr
self.datablockwrapper = None
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
@@ -309,14 +309,11 @@
assert fcond == c.AL
self._insert_checks()
- if descr._arm_bootstrap_code == 0:
+ if descr is self.currently_compiling_loop:
self.mc.B_offs(descr._arm_loop_code, fcond)
else:
target = descr._arm_bootstrap_code + descr._arm_loop_code
self.mc.B(target, fcond)
- new_fd = max(regalloc.frame_manager.frame_depth,
- descr._arm_frame_depth)
- regalloc.frame_manager.frame_depth = new_fd
return fcond
def emit_op_finish(self, op, arglocs, regalloc, fcond):
diff --git a/pypy/jit/backend/arm/regalloc.py b/pypy/jit/backend/arm/regalloc.py
--- a/pypy/jit/backend/arm/regalloc.py
+++ b/pypy/jit/backend/arm/regalloc.py
@@ -51,7 +51,9 @@
def __init__(self):
FrameManager.__init__(self)
- self.frame_depth = 1
+ self.used = [True] # keep first slot free
+ # XXX refactor frame to avoid this issue of keeping the first slot
+ # reserved
@staticmethod
def frame_pos(loc, type):
@@ -70,6 +72,13 @@
return 2
return 1
+ @staticmethod
+ def get_loc_index(loc):
+ assert loc.is_stack()
+ if loc.type == FLOAT:
+ return loc.position - 1
+ else:
+ return loc.position
def void(self, op, fcond):
return []
@@ -182,6 +191,7 @@
self.cpu = assembler.cpu
self.assembler = assembler
self.frame_manager = frame_manager
+ self.jump_target_descr = None
def loc(self, var):
if var.type == FLOAT:
@@ -291,9 +301,9 @@
useful = self._prepare(inputargs, operations)
return self._process_inputargs(inputargs, useful)
- def prepare_bridge(self, frame_depth, inputargs, arglocs, ops):
+ def prepare_bridge(self, inputargs, arglocs, ops):
self._prepare(inputargs, ops)
- self._update_bindings(arglocs, frame_depth, inputargs)
+ self._update_bindings(arglocs, inputargs)
def _process_inputargs(self, inputargs, useful):
floatlocs = [None] * len(inputargs)
@@ -313,10 +323,9 @@
self.possibly_free_vars(list(inputargs))
return nonfloatlocs, floatlocs
- def _update_bindings(self, locs, frame_depth, inputargs):
+ def _update_bindings(self, locs, inputargs):
used = {}
i = 0
- self.frame_manager.frame_depth = frame_depth
for loc in locs:
arg = inputargs[i]
i += 1
@@ -326,7 +335,7 @@
self.vfprm.reg_bindings[arg] = loc
else:
assert loc.is_stack()
- self.frame_manager.frame_bindings[arg] = loc
+ self.frame_manager.set_binding(arg, loc)
used[loc] = None
# XXX combine with x86 code and move to llsupport
@@ -519,7 +528,7 @@
def _prepare_guard(self, op, args=None):
if args is None:
args = []
- args.append(imm(self.frame_manager.frame_depth))
+ args.append(imm(self.frame_manager.get_frame_depth()))
for arg in op.getfailargs():
if arg:
args.append(self.loc(arg))
@@ -613,10 +622,34 @@
return arglocs
+ def compute_hint_frame_locations(self, operations):
+ # optimization only: fill in the 'hint_frame_locations' dictionary
+ # of rm and xrm based on the JUMP at the end of the loop, by looking
+ # at where we would like the boxes to be after the jump.
+ op = operations[-1]
+ if op.getopnum() != rop.JUMP:
+ return
+ descr = op.getdescr()
+ assert isinstance(descr, LoopToken)
+ nonfloatlocs, floatlocs = self.assembler.target_arglocs(descr)
+ for i in range(op.numargs()):
+ box = op.getarg(i)
+ if isinstance(box, Box):
+ loc = nonfloatlocs[i]
+ if loc is not None and loc.is_stack():
+ assert box.type != FLOAT
+ self.frame_manager.hint_frame_locations[box] = loc
+ else:
+ loc = floatlocs[i]
+ if loc is not None and loc.is_stack():
+ assert box.type == FLOAT
+ self.frame_manager.hint_frame_locations[box] = loc
+
def prepare_op_jump(self, op, fcond):
descr = op.getdescr()
assert isinstance(descr, LoopToken)
- nonfloatlocs, floatlocs = descr._arm_arglocs
+ self.jump_target_descr = descr
+ nonfloatlocs, floatlocs = self.assembler.target_arglocs(descr)
# get temporary locs
tmploc = r.ip
@@ -940,7 +973,7 @@
def get_mark_gc_roots(self, gcrootmap, use_copy_area=False):
shape = gcrootmap.get_basic_shape(False)
- for v, val in self.frame_manager.frame_bindings.items():
+ for v, val in self.frame_manager.bindings.items():
if (isinstance(v, BoxPtr) and self.rm.stays_alive(v)):
assert val.is_stack()
gcrootmap.add_frame_offset(shape, val.position * -WORD)
More information about the pypy-commit
mailing list