Author: Richard Plangger <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit