Author: Richard Plangger <planri...@gmail.com> Branch: memop-simplify2 Changeset: r80942:397e21b4ff04 Date: 2015-11-25 15:16 +0100 http://bitbucket.org/pypy/pypy/changeset/397e21b4ff04/
Log: added gc_load,gc_load_indexed as resop started the rewrite transformation and added dummies to the x86 backend diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -32,6 +32,11 @@ done_with_this_frame_descr_void = None exit_frame_with_exception_descr_ref = None + # can an ISA instruction handle a constant offset? + load_constant_offset = False + # can an ISA instruction handle a factor to the offset? + load_supported_factors = [1] + vector_extension = False vector_register_size = 0 # in bytes vector_horizontal_operations = False diff --git a/rpython/jit/backend/llsupport/rewrite.py b/rpython/jit/backend/llsupport/rewrite.py --- a/rpython/jit/backend/llsupport/rewrite.py +++ b/rpython/jit/backend/llsupport/rewrite.py @@ -112,6 +112,33 @@ assert not op.get_forwarded() op.set_forwarded(newop) + def handle_getarrayitem(self, op): + itemsize, ofs, sign = unpack_arraydescr(op.getdescr()) + ptr_box, index_box = op.getargs() + + offset = 0 + factor = 1 + # i * f + c + if itemsize in self.cpu.load_supported_factors: + factor = itemsize + else: + index_box = ResOperation(rop.INT_MUL, [index_box, Const(factor)]) + self.emit_op(index_box) + # adjust the constant offset + if self.cpu.load_constant_offset: + offset = ofs + else: + index_box = ResOperation(rop.INT_ADD, [index_box, Const(ofs)]) + self.emit_op(index_box) + if factor == 1 and offset == 0: + newload = ResOperation(OpHelpers.get_gc_load(op.type), + [ptr_box, index_box, Const(itemsize), Const(sign)]) + self.replace_op_with(newload, op) + else: + newload = ResOperation(OpHelpers.get_gc_load_scaled(op.type), + [ptr_box, index_box, Const(factor), Const(offset), Const(sign)]) + self.replace_op_with(newload, op) + def rewrite(self, operations): # we can only remember one malloc since the next malloc can possibly # collect; but we can try to collapse several known-size mallocs into @@ -128,6 +155,10 @@ continue if op is self._changed_op: op = self._changed_op_to + # ---------- GC_LOAD -------------- + if op.is_getarrayitem(): # TODO + self.handle_getarrayitem(op) + pass # ---------- GETFIELD_GC ---------- if op.getopnum() in (rop.GETFIELD_GC_I, rop.GETFIELD_GC_F, rop.GETFIELD_GC_R): diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -1481,6 +1481,17 @@ genop_getfield_gc_pure_r = _genop_getfield genop_getfield_gc_pure_f = _genop_getfield + def _genop_gc_load(self, op, arglocs, resloc): + base_loc, ofs_loc, size_loc, sign_loc = arglocs + assert isinstance(ofs, ImmedLoc) + assert isinstance(size_loc, ImmedLoc) + scale = get_scale(size_loc.value) + self.load_from_mem(resloc, ofs_loc, size_loc, sign_loc) + + genop_gc_load_i = _genop_gc_load + genop_gc_load_r = _genop_gc_load + genop_gc_load_f = _genop_gc_load + def _genop_getarrayitem(self, op, arglocs, resloc): base_loc, ofs_loc, size_loc, ofs, sign_loc = arglocs assert isinstance(ofs, ImmedLoc) diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -1172,6 +1172,22 @@ consider_raw_load_i = _consider_getarrayitem consider_raw_load_f = _consider_getarrayitem + def _consider_gc_load(self, op): + ptr, index, size, sign = op.getarglist() + base_loc = self.rm.make_sure_var_in_reg(op.getarg(0), args) + ofs_loc = self.rm.make_sure_var_in_reg(op.getarg(1), args) + result_loc = self.force_allocate_reg(op) + if sign.value: + sign_loc = imm1 + else: + sign_loc = imm0 + size_loc = imm(size.value) + self.perform(op, [base_loc, ofs_loc, size_loc, sign_loc], result_loc) + + consider_gc_load_i = _consider_gc_load + consider_gc_load_r = _consider_gc_load + consider_gc_load_f = _consider_gc_load + def _consider_getinteriorfield(self, op): t = unpack_interiorfielddescr(op.getdescr()) ofs, itemsize, fieldsize, sign = imm(t[0]), imm(t[1]), imm(t[2]), t[3] diff --git a/rpython/jit/backend/x86/runner.py b/rpython/jit/backend/x86/runner.py --- a/rpython/jit/backend/x86/runner.py +++ b/rpython/jit/backend/x86/runner.py @@ -24,6 +24,11 @@ with_threads = False frame_reg = regloc.ebp + # can an ISA instruction handle a constant offset? + load_constant_offset = False + # can an ISA instruction handle a factor to the offset? + load_supported_factors = [1] + from rpython.jit.backend.x86.arch import JITFRAME_FIXED_SIZE all_reg_indexes = gpr_reg_mgr_cls.all_reg_indexes gen_regs = gpr_reg_mgr_cls.all_regs diff --git a/rpython/jit/metainterp/executor.py b/rpython/jit/metainterp/executor.py --- a/rpython/jit/metainterp/executor.py +++ b/rpython/jit/metainterp/executor.py @@ -397,6 +397,12 @@ rop.VEC_GETARRAYITEM_GC_I, rop.VEC_GETARRAYITEM_GC_F, rop.VEC_SETARRAYITEM_GC, + rop.GC_LOAD_I, + rop.GC_LOAD_R, + rop.GC_LOAD_F, + rop.GC_LOAD_INDEX_I, + rop.GC_LOAD_INDEX_R, + rop.GC_LOAD_INDEX_F, ): # list of opcodes never executed by pyjitpl continue if rop._VEC_PURE_FIRST <= value <= rop._VEC_PURE_LAST: diff --git a/rpython/jit/metainterp/resoperation.py b/rpython/jit/metainterp/resoperation.py --- a/rpython/jit/metainterp/resoperation.py +++ b/rpython/jit/metainterp/resoperation.py @@ -1099,6 +1099,9 @@ # '_ALWAYS_PURE_LAST', # ----- end of always_pure operations ----- + 'GC_LOAD/3/rfi', + 'GC_LOAD_INDEX/4/rfi', + '_RAW_LOAD_FIRST', 'GETARRAYITEM_GC/2d/rfi', 'VEC_GETARRAYITEM_GC/2d/fi', @@ -1603,6 +1606,26 @@ opnum == rop.CALL_RELEASE_GIL_N) @staticmethod + def get_gc_load(tp): + if tp == 'i': + return rop.GC_LOAD_I + elif tp == 'f': + return rop.GC_LOAD_F + else: + assert tp == 'r' + return rop.GC_LOAD_R + + @staticmethod + def get_gc_load_scaled(tp): + if tp == 'i': + return rop.GC_LOAD_SCALED_I + elif tp == 'f': + return rop.GC_LOAD_SCALED_F + else: + assert tp == 'r' + return rop.GC_LOAD_SCALED_R + + @staticmethod def inputarg_from_tp(tp): if tp == 'i': return InputArgInt() _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit