[pypy-commit] pypy s390x-backend: adding trap2 instruction, skeletal structure to assemble a bridge, allocating additional space in pool if a 64bit jump is needed (e.g. bridge jump to loop token of already compiled loop)
plan_rich
noreply at buildbot.pypy.org
Mon Nov 2 06:25:47 EST 2015
Author: Richard Plangger <planrichi at gmail.com>
Branch: s390x-backend
Changeset: r80499:468121ce68fa
Date: 2015-11-02 12:25 +0100
http://bitbucket.org/pypy/pypy/changeset/468121ce68fa/
Log: adding trap2 instruction, skeletal structure to assemble a bridge,
allocating additional space in pool if a 64bit jump is needed (e.g.
bridge jump to loop token of already compiled loop)
diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py
--- a/rpython/jit/backend/test/runner_test.py
+++ b/rpython/jit/backend/test/runner_test.py
@@ -210,6 +210,8 @@
del looptoken._x86_ops_offset # else it's kept alive
if hasattr(looptoken, '_ppc_ops_offset'):
del looptoken._ppc_ops_offset # else it's kept alive
+ if hasattr(looptoken, '_zarch_ops_offset'):
+ del looptoken._ppc_ops_offset # else it's kept alive
del loop
gc.collect()
assert not wr_i1() and not wr_guard()
diff --git a/rpython/jit/backend/zarch/assembler.py b/rpython/jit/backend/zarch/assembler.py
--- a/rpython/jit/backend/zarch/assembler.py
+++ b/rpython/jit/backend/zarch/assembler.py
@@ -25,6 +25,7 @@
from rpython.rlib import rgc
from rpython.rlib.longlong2float import float2longlong
from rpython.rtyper.lltypesystem import lltype, rffi, llmemory
+from rpython.rlib.jit import AsmInfo
class AssemblerZARCH(BaseAssembler,
IntOpAssembler, FloatOpAssembler,
@@ -201,6 +202,25 @@
mc.cmp_op(0, r.SCRATCH.value, r.SCRATCH2.value, signed=False)
mc.bgtctrl()
+ def _check_frame_depth(self, mc, gcmap):
+ """ check if the frame is of enough depth to follow this bridge.
+ Otherwise reallocate the frame in a helper.
+ """
+ descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu)
+ ofs = self.cpu.unpack_fielddescr(descrs.arraydescr.lendescr)
+ mc.LG(r.r2, l.addr(ofs, r.SPP))
+ patch_pos = mc.currpos()
+ mc.TRAP2() # placeholder for cmpdi(0, r2, ...)
+ mc.TRAP2() # placeholder for bge
+ mc.TRAP2() # placeholder for li(r0, ...)
+ #mc.load_imm(r.SCRATCH2, self._frame_realloc_slowpath)
+ #mc.mtctr(r.SCRATCH2.value)
+ #self.load_gcmap(mc, r.r2, gcmap)
+ #mc.bctrl()
+
+ self.frame_depth_to_patch.append((patch_pos, mc.currpos()))
+
+
@rgc.no_release_gil
def assemble_loop(self, jd_id, unique_id, logger, loopname, inputargs,
operations, looptoken, log):
@@ -228,7 +248,7 @@
operations = regalloc.prepare_loop(inputargs, operations,
looptoken, clt.allgcrefs)
looppos = self.mc.get_relative_pos()
- self.pool.pre_assemble(self.mc, operations)
+ self.pool.pre_assemble(self, operations)
frame_depth_no_fixed_size = self._assemble(regalloc, inputargs,
operations)
self.update_frame_depth(frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE)
@@ -262,6 +282,64 @@
logger.log_loop(inputargs, operations, 0, "rewritten",
name=loopname, ops_offset=ops_offset)
+ self.fixup_target_tokens(rawstart)
+ self.teardown()
+ # oprofile support
+ #if self.cpu.profile_agent is not None:
+ # name = "Loop # %s: %s" % (looptoken.number, loopname)
+ # self.cpu.profile_agent.native_code_written(name,
+ # rawstart, full_size)
+ return AsmInfo(ops_offset, rawstart + looppos,
+ size_excluding_failure_stuff - looppos)
+
+ @rgc.no_release_gil
+ def assemble_bridge(self, faildescr, inputargs, operations,
+ original_loop_token, log, logger):
+ if not we_are_translated():
+ # Arguments should be unique
+ assert len(set(inputargs)) == len(inputargs)
+
+ self.setup(original_loop_token)
+ descr_number = compute_unique_id(faildescr)
+ if log:
+ operations = self._inject_debugging_code(faildescr, operations,
+ 'b', descr_number)
+
+ arglocs = self.rebuild_faillocs_from_descr(faildescr, inputargs)
+ regalloc = Regalloc(assembler=self)
+ startpos = self.mc.get_relative_pos()
+ operations = regalloc.prepare_bridge(inputargs, arglocs,
+ operations,
+ self.current_clt.allgcrefs,
+ self.current_clt.frame_info)
+ self._check_frame_depth(self.mc, regalloc.get_gcmap())
+ frame_depth_no_fixed_size = self._assemble(regalloc, inputargs, operations)
+ codeendpos = self.mc.get_relative_pos()
+ self.write_pending_failure_recoveries()
+ fullsize = self.mc.get_relative_pos()
+ #
+ self.patch_stack_checks(frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE)
+ rawstart = self.materialize_loop(original_loop_token)
+ debug_bridge(descr_number, rawstart, codeendpos)
+ self.patch_pending_failure_recoveries(rawstart)
+ # patch the jump from original guard
+ self.patch_jump_for_descr(faildescr, rawstart)
+ ops_offset = self.mc.ops_offset
+ frame_depth = max(self.current_clt.frame_info.jfi_frame_depth,
+ frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE)
+ if logger:
+ logger.log_bridge(inputargs, operations, "rewritten",
+ ops_offset=ops_offset)
+ self.fixup_target_tokens(rawstart)
+ self.update_frame_depth(frame_depth)
+ self.teardown()
+ return AsmInfo(ops_offset, startpos + rawstart, codeendpos - startpos)
+
+ def fixup_target_tokens(self, rawstart):
+ for targettoken in self.target_tokens_currently_compiling:
+ targettoken._ll_loop_code += rawstart
+ self.target_tokens_currently_compiling = None
+
def _assemble(self, regalloc, inputargs, operations):
self._regalloc = regalloc
self.guard_success_cc = c.cond_none
diff --git a/rpython/jit/backend/zarch/instruction_builder.py b/rpython/jit/backend/zarch/instruction_builder.py
--- a/rpython/jit/backend/zarch/instruction_builder.py
+++ b/rpython/jit/backend/zarch/instruction_builder.py
@@ -45,6 +45,8 @@
self.counter += 4
def impl(func):
func._arguments_ = args_str.split(',')
+ if args_str == '':
+ func._arguments_ = []
args = [dummy_argument(a) for a in func._arguments_]
c = Counter()
# invoke it once and get the amount of bytes
@@ -103,6 +105,13 @@
mc.writechar(chr(byte))
mc.writechar(chr(displace & 0xff))
+def build_e(mnemonic, (opcode1,opcode2)):
+ @builder.arguments('')
+ def encode_e(self):
+ self.writechar(opcode1)
+ self.writechar(opcode2)
+ return encode_e
+
def build_i(mnemonic, (opcode,)):
@builder.arguments('u8')
def encode_i(self, imm):
diff --git a/rpython/jit/backend/zarch/instructions.py b/rpython/jit/backend/zarch/instructions.py
--- a/rpython/jit/backend/zarch/instructions.py
+++ b/rpython/jit/backend/zarch/instructions.py
@@ -168,6 +168,7 @@
'CDB': ('rxe', ['\xED','\x19'], 'r,bidl,-'),
}
+# MISC
all_mnemonic_codes = {
#
'BXH': ('rs', ['\x86']),
@@ -184,6 +185,7 @@
'PKA': ('ssf', ['\xE9']),
'SVC': ('i', ['\x0A']),
+ 'TRAP2': ('e', ['\x01','\xFF']),
}
all_mnemonic_codes.update(arith_mnemonic_codes)
all_mnemonic_codes.update(logic_mnemonic_codes)
diff --git a/rpython/jit/backend/zarch/pool.py b/rpython/jit/backend/zarch/pool.py
--- a/rpython/jit/backend/zarch/pool.py
+++ b/rpython/jit/backend/zarch/pool.py
@@ -13,12 +13,17 @@
self.pool_start = 0
self.offset_map = {}
- def ensure_can_hold_constants(self, op):
+ def ensure_can_hold_constants(self, asm, op):
if op.is_guard():
# 1x gcmap pointer
# 1x target address
self.offset_map[op.getdescr()] = self.size
self.reserve_literal(2 * 8)
+ if op.getopnum() == rop.JUMP:
+ descr = op.getdescr()
+ if descr not in asm.target_tokens_currently_compiling:
+ # this is a 'long' jump instead of a relative jump
+ self.reserve_literal(8)
for arg in op.getarglist():
if arg.is_constant():
self.offset_map[arg] = self.size
@@ -33,7 +38,8 @@
self.size = 0
self.offset = 0
- def walk_operations(self, operations):
+ def pre_assemble(self, asm, operations):
+ self.reset()
# O(len(operations)). I do not think there is a way
# around this.
#
@@ -49,20 +55,16 @@
# located at register r13. This one can easily offset with 20
# bit signed values (should be enough)
for op in operations:
- self.ensure_can_hold_constants(op)
-
- def pre_assemble(self, mc, operations):
- self.reset()
- self.walk_operations(operations)
+ self.ensure_can_hold_constants(asm, op)
if self.size == 0:
# no pool needed!
return
if self.size % 2 == 1:
self.size += 1
assert self.size < 2**16-1
- mc.BRAS(r.POOL, l.imm(self.size+mc.BRAS._byte_count))
+ asm.mc.BRAS(r.POOL, l.imm(self.size+mc.BRAS._byte_count))
self.pool_start = mc.get_relative_pos()
- mc.write('\x00' * self.size)
+ asm.mc.write('\x00' * self.size)
print "pool with %d quad words" % (self.size // 8)
def overwrite_64(self, mc, index, value):
diff --git a/rpython/jit/backend/zarch/runner.py b/rpython/jit/backend/zarch/runner.py
--- a/rpython/jit/backend/zarch/runner.py
+++ b/rpython/jit/backend/zarch/runner.py
@@ -38,3 +38,11 @@
@rgc.no_release_gil
def finish_once(self):
self.assembler.finish_once()
+
+ def compile_bridge(self, faildescr, inputargs, operations,
+ original_loop_token, log=True, logger=None):
+ clt = original_loop_token.compiled_loop_token
+ clt.compiling_a_bridge()
+ return self.assembler.assemble_bridge(faildescr, inputargs, operations,
+ original_loop_token, log, logger)
+
More information about the pypy-commit
mailing list