Author: Richard Plangger <planri...@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) + _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit