[pypy-commit] pypy memop-simplify2: added gc_load_indexed scaled to the assembler

plan_rich noreply at buildbot.pypy.org
Thu Nov 26 09:07:51 EST 2015


Author: Richard Plangger <planrichi at gmail.com>
Branch: memop-simplify2
Changeset: r80973:b3214e1778f7
Date: 2015-11-26 14:36 +0100
http://bitbucket.org/pypy/pypy/changeset/b3214e1778f7/

Log:	added gc_load_indexed scaled to the assembler

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
@@ -116,47 +116,36 @@
     def handle_getarrayitem(self, op):
         itemsize, ofs, sign = unpack_arraydescr(op.getdescr())
         ptr_box, index_box = op.getarglist()
-
-        assert itemsize <= ofs
-
-        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, ConstInt(itemsize)])
-            self.emit_op(index_box)
-        # adjust the constant offset
-        if self.cpu.load_constant_offset:
-            offset = 0
-        else:
-            offset = 0
-            pass
-            # ofs is NOT the offset!
-            #index_box = ResOperation(rop.INT_ADD, [index_box, ConstInt(ofs)])
-            #self.emit_op(index_box)
-
-        if sign:
-            itemsize = -itemsize
-        if factor == 1 and offset == 0:
-            newload = ResOperation(OpHelpers.get_gc_load(op.type),
-                        [ptr_box, index_box, ConstInt(itemsize)])
-            self.replace_op_with(op, newload)
-        else:
-            newload = ResOperation(OpHelpers.get_gc_load_indexed(op.type),
-                        [ptr_box, index_box, ConstInt(factor),
-                         ConstInt(offset), ConstInt(itemsize)])
-            self.replace_op_with(op, newload)
+        self.emit_gc_load_or_indexed(op, ptr_box, index_box, itemsize, itemsize, ofs, sign)
 
     def handle_rawload(self, op):
         itemsize, ofs, sign = unpack_arraydescr(op.getdescr())
         ptr_box, index_box = op.getarglist()
+        self.emit_gc_load_or_indexed(op, ptr_box, index_box, itemsize, 1, ofs, sign)
 
+    def emit_gc_load_or_indexed(self, op, ptr_box, index_box, itemsize, factor, offset, sign):
+        # factor
+        if factor != 1 and factor not in self.cpu.load_supported_factors:
+            index_box = ResOperation(rop.INT_MUL, [index_box, ConstInt(factor)])
+            self.emit_op(index_box)
+            factor = 0
+        # adjust the constant offset
+        if offset != 0 and not self.cpu.load_constant_offset:
+            index_box = ResOperation(rop.INT_ADD, [index_box, ConstInt(offset)])
+            self.emit_op(index_box)
+            offset = 0
+        #
         if sign:
+            # encode signed into the itemsize value
             itemsize = -itemsize
-        newload = ResOperation(OpHelpers.get_gc_load(op.type),
-                    [ptr_box, index_box, ConstInt(itemsize)])
+        #
+        if factor == 1 and offset == 0:
+            args = [ptr_box, index_box, ConstInt(itemsize)]
+            newload = ResOperation(OpHelpers.get_gc_load(op.type), args)
+        else:
+            args = [ptr_box, index_box, ConstInt(factor),
+                    ConstInt(offset), ConstInt(itemsize)]
+            newload = ResOperation(OpHelpers.get_gc_load_indexed(op.type), args)
         self.replace_op_with(op, newload)
 
     def rewrite(self, operations):
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
@@ -1491,6 +1491,17 @@
     genop_gc_load_r = _genop_gc_load
     genop_gc_load_f = _genop_gc_load
 
+    def _genop_gc_load_indexed(self, op, arglocs, resloc):
+        base_loc, ofs_loc, scale_loc, offset_loc, size_loc, sign_loc = arglocs
+        assert isinstance(size_loc, ImmedLoc)
+        scale = get_scale(size_loc.value)
+        src_addr = addr_add(base_loc, ofs_loc, offset_loc.value, scale)
+        self.load_from_mem(resloc, src_addr, size_loc, sign_loc)
+
+    genop_gc_load_indexed_i = _genop_gc_load_indexed
+    genop_gc_load_indexed_r = _genop_gc_load_indexed
+    genop_gc_load_indexed_f = _genop_gc_load_indexed
+
     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
@@ -1183,12 +1183,35 @@
             sign_loc = imm1
         else:
             sign_loc = imm0
+        print("GC_LOAD execute", base_loc, "+", ofs_loc, "scale", scale, "offset", offset)
         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_gc_load_indexed(self, op):
+        args = 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)
+        scale = op.getarg(2).value
+        offset = op.getarg(3).value
+        size = op.getarg(4).value
+        size_loc = imm(abs(size))
+        print("GC_LOAD_INDEXED execute", base_loc, "+", ofs_loc, "scale", scale, "offset", offset)
+        if size < 0:
+            sign_loc = imm1
+        else:
+            sign_loc = imm0
+        locs = [base_loc, ofs_loc, imm(scale), imm(offset), size_loc, sign_loc]
+        self.perform(op, locs, result_loc)
+
+    consider_gc_load_indexed_i = _consider_gc_load_indexed
+    consider_gc_load_indexed_r = _consider_gc_load_indexed
+    consider_gc_load_indexed_f = _consider_gc_load_indexed
+
+
     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
@@ -25,9 +25,9 @@
     frame_reg = regloc.ebp
 
     # can an ISA instruction handle a constant offset?
-    load_constant_offset = False
+    load_constant_offset = True
     # can an ISA instruction handle a factor to the offset?
-    load_supported_factors = (1,)
+    load_supported_factors = (1,2,4,8)
 
     from rpython.jit.backend.x86.arch import JITFRAME_FIXED_SIZE
     all_reg_indexes = gpr_reg_mgr_cls.all_reg_indexes
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
@@ -1103,8 +1103,18 @@
     #
     '_ALWAYS_PURE_LAST',  # ----- end of always_pure operations -----
 
+    # parameters GC_LOAD
+    # 1: pointer to complex object
+    # 2: integer describing the offset
+    # 3: constant integer. byte size of datatype to load (negative if it is signed)
     'GC_LOAD/3/rfi',
-    'GC_LOAD_INDEXED/4/rfi',
+    # parameters GC_LOAD_INDEXED
+    # 1: pointer to complex object
+    # 2: integer describing the offset
+    # 3: constant integer scale factor
+    # 4: constant integer offset
+    # 5: constant integer. byte size of datatype to load (negative if it is signed)
+    'GC_LOAD_INDEXED/5/rfi',
 
     '_RAW_LOAD_FIRST',
     'GETARRAYITEM_GC/2d/rfi',


More information about the pypy-commit mailing list