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

Reply via email to